一、概念

1、Spring Cloud 简介

Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。

Spring 并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 Spring Boot 风格进行再封装、屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

2、Spring Cloud 五大组件

  • 服务发现——————Netflix Eureka
  • 客服端负载均衡———Netflix Ribbon
  • 断路器———————Netflix Hystrix
  • 服务网关——————Spring Cloud Gateway
  • 分布式配置—————Spring Cloud Config

3、微服务

微服务架构是一种架构模式或者说一种架构风格,它提倡将单一应用程序划分成一组小的服务,每个服务运行在其独立的进程中,服务之间互相协调、互相配合,为用户提供最终的价值。同时,服务之间采用轻量级的通信机制(通常是基于 HTTP 的 RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境等。

微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底去掉耦合,每一个微服务提供单个业务功能,一个服务只做一件事。

从技术角度讲就是一种小而独立的处理过程,类似与进程的概念,能够自行单独启动或销毁,可以拥有自己独立的数据库。

① 微服务优点

  1. 每个服务足够内聚,足够小,代码容易理解。这样能聚焦一个业务功能或业务需求。
  2. 开发简单、开发效率提高,一个服务可能就是专业的只干一件事,微服务能够被小团队单独开发,这个小团队可以是 2 到 5 人的开发人员组成。
  3. 微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的。
  4. 微服务能使用不同的语言开发。
  5. 易于和第三方集成,微服务运行容易且灵活的方式集成自动部署。
  6. 微服务易于被一个开发人员理解、修改和维护,这样小团队能够更关注自己的工作成果,无需通过合作才能体现价值。
  7. 微服务允许你利用融合最新技术。微服务只是业务逻辑的代码,不会和 HTML/CSS 或其他界面组件混合,即前后端分离。
  8. 每个微服务都有自己的存储能力,可以有自己的数据库,也可以有统一数据库。

② 微服务的缺点

开发人员要处理分布式系统的复杂性。

4、微服务、Spring Boot、Spring Cloud 之间的关系

  • 微服务是一种架构的理念,提出了微服务的设计原则,从理论为具体的技术落地提供了指导思想。
  • Spring Boot 是一套快速配置脚手架,可以基于 Spring Boot 快速开发单个微服务。
  • Spring Cloud 是一个基于 Spring Boot 实现的服务治理工具包;
  • Spring Boot 专注于快速、方便集成的单个微服务个体;
  • Spring Cloud 关注全局的服务治理框架。

5、服务调用方式

  • RPC
  • HTTP

RPC 和 HTTP 区别

RPC(Remote Procedure Call Protocol):远程过程调用协议

它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议

① 序列化协议

HTTP 是基于 HTTP 协议

RPC 可以基于 TCP/UDP,也可以基于 HTTP 协议进行传输。

② 使用方式

HTTP 是服务端把方法写好,客户端并不知道具体方法。客户端只想获取资源,所以发起 HTTP 请求,而服务端接收到请求后根据 URI 经过一系列的路由才定位到方法上面去,因此,HTTP 接口只关注服务提供方,接口只要保证有客户端调用时,返回对应的数据就行了。

RPC 是服务端提供好方法给客户端调用,客户端需要知道服务端的具体类,具体方法,然后像调用本地方法一样直接调用它。所以 RPC 要求客户端接口保持和服务端的一致。

③ 面向对象

从设计上来看,RPC,所谓的远程过程调用 ,是面向方法的 ,HTTP :是面向资源的

④ 性能

由于 HTTP 本身提供了丰富的状态功能与扩展功能,但也正由于 HTTP 提供的功能过多,导致在网络传输时,需要携带的信息更多,从性能角度上讲,较为低效。

RPC 服务网络传输上仅传输与业务内容相关的数据,传输数据更小,性能更高。

6、Spring 的 RestTemplate

RestTemplate 介绍

  • RestTemplate 是 Rest 的 HTTP 客户端模板工具类
  • 对基于 Http 的客户端进行封装
  • 实现对象与 JSON 的序列化与反序列化(JSON<——->JavaBean)
  • 不限定客户端类型,目前常用的 3 种客户端都支持:HttpClient、OKHttp、JDK 原生 URLConnection(默认方式)

二、入门案例

1、搭建注册中心

Eureka 架构中的三个核心角色

Eureka:就是服务注册中心(可以是一个集群),对外暴露自己的地址,提供服务注册发现功能

服务提供者:启动后向 Eureka 注册自己的信息(地址,提供什么服务),要求统一对外提供 Rest 风格服务

服务消费者:向 Eureka 订阅服务,Eureka 会将对应服务的所有提供者地址列表发送给消费者,并且定期更新

Eurka 基本工作流程

  1. Eureka Server 启动成功,等待服务端注册。在启动过程中如果配置了集群,集群之间定时通过 Replicate 同步注册表,每个 Eureka Server 都存在独立完整的服务注册表信息
  2. Eureka Client 启动时根据配置的 Eureka Server 地址去注册中心注册服务
  3. Eureka Client 会每 30s 向 Eureka Server 发送一次心跳请求,证明客户端服务正常
  4. 当 Eureka Server 90s 内没有收到 Eureka Client 的心跳,注册中心则认为该节点失效,会注销该实例
  5. 单位时间内 Eureka Server 统计到有大量的 Eureka Client 没有上送心跳,则认为可能为网络异常,进入自我保护机制,不再剔除没有上送心跳的客户端
  6. 当 Eureka Client 心跳请求恢复正常之后,Eureka Server 自动退出自我保护模式
  7. Eureka Client 定时全量或者增量从注册中心获取服务注册表,并且将获取到的信息缓存到本地
  8. 服务调用时,Eureka Client 会先从本地缓存找寻调取的服务。如果获取不到,先从注册中心刷新注册表,再同步到本地缓存
  9. Eureka Client 获取到目标服务器信息,发起服务调用
  10. Eureka Client 程序关闭时向 Eureka Server 发送取消请求,Eureka Server 将实例从注册表中删除

心跳(续约):提供者定期通过 http 方式向 Eureka 刷新自己的状态

① 新建工程

创建 Maven 父工程 springcloud-parent

导入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>

<!--SpringCloud包依赖管理-->
<dependencyManagement>
<dependencies>
<!--spring cloud Hoxton.SR1-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

在父工程 springcloud-parent下创建注册中心项目 eureka-server

pom.xml依赖导入

1
2
3
4
5
6
7
8
<!--依赖包-->
<dependencies>
<!--eureka-server依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>

配置application.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server:
# 配置服务中心端口号
port: 7001
spring:
application:
# 应用名称:会在Eureka中作为服务的id标识(serviceId)
name: eureka-server
eureka:
client:
# 是否将自己注册到Eureka中
register-with-eureka: false
# 是否从eureka中获取服务信息
fetch-registry: false
service-url:
# EurekaServer的地址
defaultZone: http://localhost:7001/eureka

② 创建启动类

在 src 下创建com.atguigu.EurekaServerApplication

在类上需要添加一个注解@EnableEurekaServer,用于开启 Eureka 服务

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.atguigu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}

运行启动类的主方法,测试访问:http://127.0.0.1:7001/

2、服务提供者-注册服务

引入 eureka 客户端依赖包
在 application.yml 中配置 Eureka 服务地址
在启动类上添加@EnableDiscoveryClient 或者@EnableEurekaClient

在父工程 springcloud-parent下新建 user-provider 工程

引入 pom.xml 依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!--依赖包-->
<dependencies>
<!--JPA包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--web起步包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--MySQL驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

application.yml 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server:
port: 18081
# 配置mysql
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://192.168.88.88:3306/springcloud?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
# 添加Eureka服务地址
application:
# 服务的名字,不同的应用,名字不同,如果是集群,名字需要相同
name: user-provider
# 指定eureka服务地址
eureka:
client:
service-url:
# EurekaServer的地址
defaultZone: http://localhost:7001/eureka

①User

创建com.atguigu.domain.User

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.atguigu.domain;

import javax.persistence.*;
import java.util.Date;

@Entity
@Table(name = "tb_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
// 主键id
private Integer id;
// 用户名
private String username;
// 密码
private String password;
// 姓名
private String name;
// 年龄
private Integer age;
// 性别
private Integer sex;
// 出生日期
private Date birthday;
// 创建时间
private Date created;
// 更新时间
private Date updated;
// 备注
private String note;

// 各种方法.....
}

对应的数据库表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- 使用springcloud数据库
USE springcloud;
-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
CREATE TABLE `tb_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(100) DEFAULT NULL COMMENT '用户名',
`password` varchar(100) DEFAULT NULL COMMENT '密码',
`name` varchar(100) DEFAULT NULL COMMENT '姓名',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`sex` int(11) DEFAULT NULL COMMENT '性别,1男,2女',
`birthday` date DEFAULT NULL COMMENT '出生日期',
`created` date DEFAULT NULL COMMENT '创建时间',
`updated` date DEFAULT NULL COMMENT '更新时间',
`note` varchar(1000) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='用户信息表';
-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES ('1', 'zhangsan', '123456', '张三', '13', '1', '2006-08-01', '2021-05-16', '2021-05-16', '张三');
INSERT INTO `tb_user` VALUES ('2', 'lisi', '123456', '李四', '13', '1', '2006-08-01', '2021-05-16', '2021-05-16', '李四');

②UserDao

创建com.atguigu.dao.UserDao

1
2
3
4
5
6
7
package com.atguigu.dao;

import com.atguigu.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserDao extends JpaRepository<User, Integer> {
}

③Service

创建com.atguigu.service.UserService接口

1
2
3
4
5
6
7
8
9
10
11
12
package com.atguigu.service;

import com.atguigu.domain.User;

public interface UserService {
/***
* 根据ID查询用户信息
* @param id
* @return
*/
User findByUserId(Integer id);
}

④UserServiceImpl

创建com.atguigu.service.impl.UserServiceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.atguigu.service.impl;

import com.atguigu.dao.UserDao;
import com.atguigu.domain.User;
import com.atguigu.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

@Autowired
private UserDao userDao;

/***
* 根据ID查询用户信息
* @param id
* @return
*/
@Override
public User findByUserId(Integer id) {
return userDao.findById(id).get();
}
}

⑤UserController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.atguigu.controller;

import com.atguigu.domain.User;
import com.atguigu.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/user")
public class UserController {

@Autowired
private UserService userService;

/***
* 根据ID查询用户信息
* @param id
* @return
*/
@RequestMapping(value = "/find/{id}")
public User findById(@PathVariable(value = "id") Integer id) {
return userService.findByUserId(id);
}
}

⑥ 启动类创建

创建com.atguigu.UserProviderApplication启动类

@EnableEurekaClient 或者 @EnableDiscoveryClient,都是用于开启客户端发现功能

区别在于@EnableEurekaClient的注册中心只能是 Eureka。

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.atguigu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class UserProviderApplication {
public static void main(String[] args) {
SpringApplication.run(UserProviderApplication.class, args);
}
}

运行启动类

访问 Eureka 地址:http://127.0.0.1:7001/

3、服务消费者-注册服务

引入 eureka 客户端依赖包
在 application.yml 中配置 Eureka 服务地址
在启动类上添加@EnableDiscoveryClient 或者@EnableEurekaClient

在父工程 springcloud-parent下新建 user-consumer 工程

引入 pom.xml 依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--依赖包-->
<dependencies>
<!--web起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>

application.yml 配置

1
2
3
4
5
6
7
8
9
10
11
server:
port: 18082
spring:
application:
name: user-consumer #服务名字
#指定eureka服务地址
eureka:
client:
service-url:
# EurekaServer的地址
defaultZone: http://localhost:7001/eureka

①User

创建com.atguigu.domain.User

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.atguigu.domain;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {
// 主键id
private Integer id;
// 用户名
private String username;
// 密码
private String password;
// 姓名
private String name;
// 年龄
private Integer age;
// 性别 1男性,2女性
private Integer sex;
// 出生日期
private Date birthday;
// 创建时间
private Date created;
// 更新时间
private Date updated;
// 备注
private String note;

// 生成各种方法
}

②UserController

创建com.atguigu.controller.UserController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.atguigu.controller;

import com.atguigu.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
@RequestMapping(value = "/consumer")
public class UserController {

@Autowired
private RestTemplate restTemplate;

@Autowired
// 注入该对象,可以用来发现当前注册中心中的服务对象
private DiscoveryClient discoveryClient;

/****
* 在user-consumer服务中通过RestTemplate调用user-provider服务
* @param id
* @return
*/
@GetMapping(value = "/{id}")
public User queryById(@PathVariable(value = "id") Integer id) {
// 获取指定实例
List<ServiceInstance> instances = discoveryClient.getInstances("user-provider");
// 获取第一个实例对象
ServiceInstance serviceInstance = instances.get(0);
// 拼接服务地址
// "http://"+ 服务的主机 + ":" +服务的端口号
String instanceUrl = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/user/find/" + id;
return restTemplate.getForObject(instanceUrl, User.class);
}
}

③ 启动引导类

创建com.atguigu.UserConsumerApplication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.atguigu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
public class UserConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(UserConsumerApplication.class, args);
}

/***
* 将RestTemplate的实例放到Spring容器中
* @return
*/
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}

使用 IP 访问配置

可以通过配置文件,将请求地址换成 IP,修改 application.yml 配置文件

1
2
3
4
5
6
7
8
9
10
eureka:
client:
service-url:
# EurekaServer的地址
defaultZone: http://localhost:7001/eureka
instance:
#指定IP地址
ip-address: 127.0.0.1
#访问服务的时候,推荐使用IP
prefer-ip-address: true

4、总结

①Eureka 客户端

服务提供者要向 EurekaServer 注册服务,并完成服务续约等工作

服务注册:

  1. 当我们开启了客户端发现注解@EnableDiscoveryClient。同时导入了 eureka-client 依赖坐标
  2. 同时配置 Eureka 服务注册中心地址在配置文件
  3. 服务在启动时,检测是否有@EnableDiscoveryClient注解和配置信息
  4. 如果有,则会向注册中心发起注册请求,携带服务元数据信息(IP、端口等)
  5. Eureka 注册中心会把服务的信息保存在 Map 中。

② 服务续约

Eureka Client 会每隔 30 秒发送一次心跳来续约。 通过续约来告知 Eureka Server 该 Eureka Client 运行正常,没有出现问题。

默认情况下,如果 Eureka Server 在 90 秒内没有收到 Eureka Client 的续约,Server 端会将实例从其注册表中删除,此时间可配置,一般情况不建议更改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
eureka:
client:
service-url:
# EurekaServer的地址
defaultZone: http://localhost:7001/eureka
instance:
#指定IP地址
ip-address: 127.0.0.1
#访问服务的时候,推荐使用IP
prefer-ip-address: true
#租约到期,服务时效时间,默认值90秒
lease-expiration-duration-in-seconds: 150
#租约续约间隔时间,默认30秒
lease-renewal-interval-in-seconds: 30

③ 获取服务列表

Eureka Client 从服务器获取注册表信息,并将其缓存在本地。客户端会使用该信息查找其他服务,从而进行远程调用。该注册列表信息定期(每 30 秒钟)更新一次。每次返回注册列表信息可能与 Eureka Client 的缓存信息不同,Eureka Client 自动处理。

如果由于某种原因导致注册列表信息不能及时匹配,Eureka Client 则会重新获取整个注册表信息。 Eureka Server 缓存注册列表信息,整个注册表以及每个应用程序的信息进行了压缩,压缩内容和没有压缩的内容完全相同。Eureka Client 和 Eureka Server 可以使用 JSON/XML 格式进行通讯。在默认情况下 Eureka Client 使用压缩 JSON 格式来获取注册列表的信息。

1
2
3
4
5
6
7
eureka:
client:
service-url:
# EurekaServer的地址
defaultZone: http://localhost:7001/eureka
# 每隔30秒获取服务中心列表(只读备份)
registry-fetch-interval-seconds: 30

说明

服务消费者启动时,会检测是否获取服务注册信息配置
如果是,则会从 EurekaServer 服务列表获取只读备份,缓存到本地
每隔 30 秒,会重新获取并更新数据
每隔 30 秒的时间可以通过配置 registry-fetch-interval-seconds 修改

④ 失效剔除和自我保护

当 Eureka Client 和 Eureka Server 不再有心跳时,Eureka Server 会将该服务实例从服务注册列表中删除,即服务剔除。

服务下线

当服务正常关闭操作时,会发送服务下线的 REST 请求给 EurekaServer。服务中心接受到请求后,将该服务置为下线状态

失效剔除

服务中心每隔一段时间(默认 60 秒)将清单中没有续约的服务剔除。

1
2
3
4
5
6
7
8
9
10
eureka:
client:
service-url:
# EurekaServer的地址
defaultZone: http://localhost:7001/eureka
# 每隔30秒获取服务中心列表(只读备份)
registry-fetch-interval-seconds: 30
service:
# 对无效的服务进行剔除操作,单位是毫秒
eviction-interval-timer-in-ms: 5000

⑤ 自我保护

默认情况下,如果 Eureka Server 在一定的 90s 内没有接收到某个微服务实例的心跳,会注销该实例。但是在微服务架构下服务之间通常都是跨进程调用,网络通信往往会面临着各种问题,比如微服务状态正常,网络分区故障,导致此实例被注销。

固定时间内大量实例被注销,可能会严重威胁整个微服务架构的可用性。为了解决这个问题,Eureka 开发了自我保护机制

Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 即会进入自我保护机制。

自我保护模式下,不会剔除任何服务实例
自我保护模式保证了大多数服务依然可用
通过 enable-self-preservation 配置可用关停自我保护,默认值是打开

1
2
3
4
5
6
7
8
9
10
11
12
eureka:
client:
service-url:
# EurekaServer的地址
defaultZone: http://localhost:7001/eureka
# 每隔30秒获取服务中心列表(只读备份)
registry-fetch-interval-seconds: 30
service:
# 关闭自我保护模式(缺省为打开)
enable-self-preservation: false
# 对无效的服务进行剔除操作,单位是毫秒
eviction-interval-timer-in-ms: 5000