【SpringCloud组件学习笔记系列】(1)Eureka组件
【SpringCloud组件学习笔记系列】(2)Hystrix组件
【SpringCloud组件学习笔记系列】(3)OpenFeign组件
【SpringCloud组件学习笔记系列】(4)Gateway组件
【SpringCloud组件学习笔记系列】(5)Config组件
完整代码已在Github开源:
https://github.com/Aliang99/SpringCloud_Bill
环境:
☕️JDK:11
Maven:3.8.2
SpringBoot:2.3.2.RELEASE
☁️SpringCloud:Hoxton.SR1
Eureka:2.2.1.RELEASE
Hystrix:2.2.1.RELEASE
⚖️Ribbon:2.2.1.RELEASE
♻️Feign:2.2.1.RELEASE
Gateway:2.2.1.RELEASE
Config:2.2.1.RELEASE
Bus:2.2.1.RELEASE
MySQL:8.0.19
TK-MyBatis:2.1.5
✂️Lombok:1.18.12
Maven-Plugin:2.6.2
IDEA:2021.3
Chrome:97.0.4692.71
Windows:win10 家庭版 19042
SpringCloud 体系架构图
Eureka主要用于服务的注册以及发现,多个微服务使用同一个服务名称,注册为集群。
多个eureka也可以使用同一个服务名称,形成注册集群,达成高可用目的。
名称:SpringCloudeDemo
指定pom文件中package类型为POM
导入spring-boot-dependencies依赖,指定type为POM,Scope为import (重点)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>org.alianggroupId>
<artifactId>SpringCloudDemoartifactId>
<packaging>pompackaging>
<version>1.0-SNAPSHOTversion>
<properties>
<maven.compiler.source>11maven.compiler.source>
<maven.compiler.target>11maven.compiler.target>
<spring.boot.version>2.3.2.RELEASEspring.boot.version>
<spring-cloud.version>Hoxton.SR1spring-cloud.version>
<mapper.starter.version>2.1.5mapper.starter.version>
<mysql.version>8.0.19mysql.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>${spring.boot.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring-cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>tk.mybatisgroupId>
<artifactId>mapper-spring-boot-starterartifactId>
<version>${mapper.starter.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.version}version>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<version>2.6.2version>
plugin>
plugins>
build>
project>
名称:SpringCloud-Commons
该微服务主要用于给其它微服务提供实体类、响应封装类服务,减少冗余重复代码,其它重复使用的类也可以放在这个微服务中
/**
* 后端响应前端的封装对象
* @param
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonVo<T> {
private int code;
private String msg;
private T obj;
}
/**
*数据库实体类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long 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;
}
创建完毕后,使用Maven打包并安装,供其它微服务使用
名称:SpringCloud-User-8001
pom文件中parent标签指定为父工程,并引入所需的依赖包,以及公共微服务的引入
<parent>
<groupId>com.alianggroupId>
<artifactId>SpringCloudDemoartifactId>
<version>0.0.1-SNAPSHOTversion>
parent>
添加eureka客户端依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
@SpringBootApplication
@EnableEurekaClient //当前微服务加入注册中心,作为客户端
public class SpringCloud_User_8001_Application {
public static void main(String[] args) {
SpringApplication.run(SpringCloud_User_8001_Application.class,args);
}
}
配置文件指定端口、DataSource、Eureka配置信息等 (重点)
server:
port: 8001
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springcloud?serverTimezone=GMT%2B8
username: root
password: 111111
application:
name: User-Service # 用于标识单个或多个同一类型的服务
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka
# register-with-eureka和fetch-registry 默认是true,所以不用设置
instance:
ip-address: 127.0.0.1
prefer-ip-address: true
public interface UserDao extends Mapper<User> {
// 使用TkMybatis的内置方法
}
编写service调用dao接口,查询或修改数据
接口
public interface IUserService {
User queryById(Long id);
Integer insertUser(User user);
}
实现类
@Service
public class UserServiceImpl implements IUserService {
@Resource
private UserDao userDao;
@Override
public User queryById(Long id) {
return userDao.selectByPrimaryKey(id);
}
@Override
public Integer insertUser(User user) {
return userDao.insert(user);
}
}
创建controller,编写 对消费型开放的远程调用 业务接口
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private IUserService userService;
/**
* 根据id查询用户信息
* @param id
* @return
*/
@GetMapping("queryById/{id}")
public CommonVo<User> queryById(@PathVariable("id") Long id) {
User user = userService.queryById(id);
if (user==null){
return new CommonVo<>(400,"数据库中暂无此数据",null);
}else{
return new CommonVo<User>(200,"OK",user);
}
}
/**
* 接收用户信息,新增用户
* @param user
* @return
*/
@PostMapping("insertUser")
public CommonVo<Integer> insertUser(User user){
Integer integer = userService.insertUser(user);
if (integer!=1){
return new CommonVo<>(400,"插入失败",0);
}else{
return new CommonVo<>(200,"ok",1);
}
}
}
名称:SpringCloud-Consumer-User-80
pom文件中parent标签指定为父工程,并引入所需的依赖包,以及公共微服务的引入,重点在于eureka的client依赖包,当前微服务是注册服务的客户端。
父工程引入参考3.1
添加eureka客户端依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
@SpringBootApplication//(exclude= {DataSourceAutoConfiguration.class}) //exclude 避免因导入的其它模块中有类需要链接数据库而报错
public class SpringCloud_Consumer_80_Application {
public static void main(String[] args) {
SpringApplication.run(SpringCloud_Consumer_80_Application.class,args);
}
}
配置文件指定端口、Eureka配置信息等 (重点)
server:
port: 80
eureka:
client:
service-url:
defaultZone: http://localhost:10086/eureka # 注册到该路径的Eureka中
# register-with-eureka和fetch-registry 默认是true,所以不用设置
spring:
application:
name: User-Consumer # 服务名称
使用配置类,创建RestTemplate对象,用于远程调用其它微服务提供的接口 (重点)
/**
* RestTemplate是 SpringBoot 提供的访问远程服务的模板
*/
@Configuration
public class RestTempConfiguration {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
创建controller,定义全局变量字符串,指定当前消费型微服务需要消费哪个地址的服务
代码部分见4.7
编写controller内的mapping方法,给出提供给用户的接口
代码部分见4.7
方法内部使用RestTempalte调用服务型微服务,并获取返回值,再调用公共微服务的封装对象封装信息,返回到客户端
@RestController
@RequestMapping("consumer")
@DefaultProperties(defaultFallback = "defaultFallback") //指定默认服务降级方法
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("queryById/{id}")
public CommonVo<User> queryById(@PathVariable("id") Long id){
String url = "http://localhost:8001"; //服务提供者地址
CommonVo<User> resp = restTemplate.getForObject(url + "/queryById/" + id, CommonVo.class);
return resp;
}
}
名称:SpringCloud-Eureka-Server-10086
用于为服务型及消费型微服务提供注册服务,实现注册的微服务可以远程调用
pom文件中parent标签指定为父工程,并引入所需的依赖包,重点在于eureka的server依赖包,当前微服务是注册服务 服务端
父工程引入参考3.1
添加eureka服务端依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
@SpringBootApplication
@EnableEurekaServer //Eureka服务端注解
public class SpringCloud_EurekaServer_10086_Application {
public static void main(String[] args) {
SpringApplication.run(SpringCloud_EurekaServer_10086_Application.class, args);
}
}
配置文件指定端口、Eureka配置信息等 (重点)
eureka:
instance:
hostname: localhost # eureka 服务端的实例名称
client:
register-with-eureka: false # 申明不向注册中心注册自己
fetch-registry: false # 申明不检索服务,自己就是注册中心
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 设置 与eureka交互 的 查询服务 和 注册服务 都需要依赖这个地址
修改HOST文件,使当前机器可以映射多个地址
打开C:\Windows\System32\drivers\etc\HOSTS文件
添加
127.0.0.1 eureka10086.com
127.0.0.1 eureka10087.com
127.0.0.1 eureka10088.com
这一步的目的在于,集群下的Eureka,可以使用域名代替ip地址,有一个标识作用。
在地址栏中可以使用域名+端口号,访问对应的Eureka服务页面
复制两份10086到10087,10088,模拟多台机器上的Eureka集群
修改10087,10088配置文件
10088的配置文件同下面一样,把10087改成10088即可。
server:
port: 10087
eureka:
instance:
hostname: eureka10087.com # 集群写法 避免多个eureka 同名 ,映射的eureka10087.com 需要再host文件中添加映射 127.0.0.1 eureka10087.com
# hostname: localhost #单机写法: eureka 服务端的实例名称
client:
register-with-eureka: false # 申明不向注册中心注册自己
fetch-registry: false # 申明不检索服务,自己就是注册中心
service-url:
defaultZone: http://eureka10086.com:10086/eureka/,http://eureka10088.com:10088/eureka/ # 设置 与eureka交互 的 查询服务 和 注册服务 都需要依赖这个地址
# 集群写法:需要将当前eureka绑定到另一个eureka地址
10087启动类
/**
* Eureka启动类 前端面板访问页地址: localhost:10087/
*/
@SpringBootApplication
@EnableEurekaServer //当前微服务加入注册中心,作为注册中心,服务端
public class SpringCloud_EurekaServer_10087_Application {
public static void main(String[] args) {
SpringApplication.run(SpringCloud_EurekaServer_10087_Application.class, args);
}
}
10088同理,不再赘述。
启动10086,10087,10088,8001,80
查看Eureka的DS Replicas下,存在多个Eureka相互管理信息,即为成功
复制8001微服务到8002,8003
server:
port: 8002 # 端口号
spring:
application:
name: User-Service # 微服务名称,在Eureka面板页面可以查看
datasource: # 数据源
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springcloud?serverTimezone=GMT%2B8 # mysql8.0以上版本,有一个时区不一致问题,需要添加 serverTimezone=GMT%2B8 ===> %2B8 为 +8 UrlEncode之后的值
username: root
password: 111111
eureka:
client:
register-with-eureka: true # 表示是否将自己注册进Eureka 默认为true
fetch-registry: true # 表示是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
service-url:
defaultZone: http://eureka10086.com:10086/eureka/,http://eureka10088.com:10088/eureka/,http://eureka10087.com:10087/eureka # 集群版 指定多个
# 单机版 指定一个:http://localhost:10086/eureka
8003配置文件在8002基础上将8002改成8003即可。
在controller中定义端口的值
@Value注解会自动从配置文件中获取配置好的端口号
@Value("${server.port}")
private String serverPort;
修改消费型微服务的配置文件
server:
port: 80
eureka:
client:
register-with-eureka: true # 表示是否将自己注册进Eureka 默认为true
fetch-registry: true # 表示是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
service-url:
defaultZone: http://eureka10086.com:10086/eureka/,http://eureka10088.com:10088/eureka/,http://eureka10087.com:10087/eureka # 集群版 指定多个
# 单机版 指定一个:http://localhost:10086/eureka
spring:
application:
name: SpringCloud-Consumer-User-80
在Controller中指定微服务名称
@RestController
public class PaymentController {
// 8001微服务的地址
//private static final String USER_URL = "http://localhost:8001"; 单机版,写死了
//集群版 给的地址应该时eureka中注册的微服务名称,多个微服务共用同一个名称,地址填写为该名称,并且需要在RestTempConfiguration类中添加RestTemplate的负载均衡注解@LoadBalanced,达成实现了多个端口的负载均衡目的
// 一个微服务名称下可以有多个提供服务的机器 这里使用单机的多个端口,模拟多台机器,远程调用时,只需要关心微服务名称,不再关心地址和端口号,Eureka已自动映射了
private static final String USER_URL = "http://User-Service";
@Autowired
private RestTemplate restTemplate; // 当前微服务可以使用 RestTemplate对象 与 8001 通信
}
在RestTemplate配置文件中,添加@LoadBalanced注解,做负载均衡(重点)
/**
* RestTemplate是 SpringBoot 提供的访问远程服务的模板
*/
@Configuration
public class RestTempConfiguration {
@Bean
@LoadBalanced //开启负载均衡,默认是轮询,即远程调用的微服务名称下有多台机器,调用时轮番调用,减小服务端压力
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
注意:
在使用http://localhost/consumer/payment/1 访问时,会轮番出现8001,8002,8003提供服务
当试着停掉一个微服务后,轮询会报错,理由是当前轮到的微服务不能访问,多次刷新依旧如此。
只有等待eureka自动把停掉的微服务从注册中心注销后,再访问就不报错了,剩下的两个微服务依然可以轮询调用。等待的时间大概90秒左右。
什么是Eureka的自我保护机制?
默认情况下,EurekaClient定时向EurekaServer发送心跳包,如果EurekaServer在一定时间内**(从上一次收到心跳包开始计时等待90秒)没有收到某个微服务实例的心跳,EurekaServer将会注销该实例,每次发送心跳包的间隔时间为30秒**
但如果是当前网络分区故障,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了,因为服务本身是健康的,出于高可用的目的,此时本不应该注销这个微服务。
于是Eureka通过自我保护机制,来解决当前问题,当客户机因为网络问题丢失了大量的心跳包时,不注销该微服务。注意:EurekaServer在没有收到EurekaClient心跳包时会触发自我保护机制,暂时不注销,如果90秒内没有收到心跳包,再注销。
自我保护机制的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。
自我保护机制可在配置文件通过参数关闭。
#关闭各个EurekaServer之间的自我保护机制,EurekaClient在2000ms后未联系上就踢出注册表
eureka:
server:
enable-self-preservation: false # 关闭自我保护机制,保证不可用服务及时被踢出
eviction-interval-timer-in-ms: 2000 #从默认心跳包等待时间 90秒 改成 2秒
关闭后,再打开Eureka页面,红色的字表示已经关闭自我保护
在controller中注入DiscoveryClient
注意导包:import org.springframework.cloud.client.discovery.DiscoveryClient;
// 用于提供服务发现,可以使用该对象,获取Eureka的服务名称、地址、端口等信息,实现动态的调用远程接口。,注意,导包是springcloud下的
@Resource
private DiscoveryClient discoveryClient;
编写演示DiscoveryClient对象用法的mapping
@GetMapping("/user/discovery") //discovery信息获取测试
public CommonVo<List> discoveryClient(){
List<ServiceInstance> instances = discoveryClient.getInstances("User-Service"); //根据微服务在Eureka注册的名称获取信息
for (ServiceInstance instance : instances) {
System.out.println(instance);
}
return new CommonVo<List>(200,"OK", instances);
}
启动类上添加注解
@EnableDiscoveryClient //开启服务发现
Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为。
为Ribbon配置服务提供者地址列表后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。
Ribbon默认为我们提供了很多的负载均衡算法,例如轮询、随机等。
当然,我们也可为Ribbon实现自定义的负载均衡算法。
在实际环境中,多个服务提供型微服务形成的集群,在接受到访问时,各个子服务应该要轮番对请求进行处理,以达成负载均衡目的。
Eureka中集成的Ribbon就可以实现该功能。
首先要在在restTemplate方法上使用注解@LoadBalanced
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
对于远程调用的代码,也需要做相应的修改,根据服务名称去调用,Ribbon会自动根据该服务名称下的集群选择一个微服务处理请求。
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id) {
ServiceInstance serviceInstance = discoveryClient.getInstances("User-Service").get(0);// 根据服务名称获取服务信息
String hostName = serviceInstance.getHost(); // 获取主机名称
int hostPort = serviceInstance.getPort(); //获取端口
String url = "http://"+hostName+":"+hostPort; //拼接远程调用地址
return restTemplate.getForObject(url + "/queryById/" + id, User.class);
}
为什么只输入了服务型微服务名称就可以访问了呢?之前还要获取ip和端口。
显然是因为有组件根据服务型微服务名称,获取到了服务实例的ip和端口。
因为消费型微服务使用的是RestTemplate,spring使用LoadBalancerInterceptor拦截器 ,这个类会对RestTemplate的请求进行拦截,然后根据服务id从Eureka获取已注册的服务列表,随后利用负载均衡算法得到真实的服务地址信息,替换服务id。
我们进行源码跟踪:
继续跟入execute方法:发现获取了9091端口的服务,也就是8081(端口不一致是复现时端口给的9091)
再跟下一次,发现获取的是9092:也就是8082(端口不一致是复现时端口给的9092)
Ribbon默认的负载均衡策略是简单的轮询
在刚才的源码中我们看到拦截中是使用RibbonLoadBalanceClient来进行负载均衡的,其中有一个 choose方法,是这样介绍的:
现在这个就是负载均衡获取实例的方法。
我们对注入这个类的对象,然后对其测试:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = UserConsumerDemoApplication.class)
public class LoadBalanceTest {
@Autowired
RibbonLoadBalancerClient client;
@Test
public void test(){
// 轮询100次
for (int i = 0; i < 100; i++) {
ServiceInstance instance = this.client.choose("user-service");
System.out.println(instance.getHost() + ":" + instance.getPort());
}
}
}
结果:
符合预期推测,确定是轮询方式。
SpringBoot也帮我们提供了修改负载均衡规则的配置入口:
user-service:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 随机调用
格式是: {服务名称}.ribbon.NFLoadBalancerRuleClassName ,值就是IRule的实现类。
再次测试,结果变成了随机调用:
服务提供者在启动时,会检测配置属性中的: eureka.client.register-with-erueka=true 参数是否为true,事实上默认就是true。如果值确实为true,则会向EurekaServer发起一个Rest请求,并携带自己的元数据信息,
EurekaServer会把这些信息保存到一个双层Map结构中 。
第一层Map的Key就是服务id,一般是配置中的 spring.application.name 属性,user-service
第二层Map的key是服务的实例id。一般host+ serviceId + port,例如: localhost:user-service:8081,值则是服务的实例对象,也就是说一个服务,这样可以同时启动多个不同实例,形成集群。
默认注册时使用的是主机名或者localhost,如果想用ip进行注册,可以在 user-service 中添加配置如下:
eureka: instance: ip-address: 127.0.0.1 # ip地址 prefer-ip-address: true # 更倾向于使用ip,而不是host名
修改完后先后重启 服务端 和 消费端 ;在调用服务的时候就已经变成ip地址。
需要注意的是:不是在eureka中的控制台服务实例状态显示。
在注册服务完成以后,服务提供者会维持一个心跳(定时向EurekaServer发起Rest请求),告诉
EurekaServer:“我还活着”。这个我们称为服务的续约(renew);
有两个重要参数可以修改服务续约的行为;可以在 user-service 中添加如下配置项:
eureka: instance: lease-expiration-duration-in-seconds: 90 lease-renewal-interval-in-seconds: 30
lease-renewal-interval-in-seconds:服务续约(renew)的间隔,默认为30秒
lease-expiration-duration-in-seconds:服务失效时间,默认值90秒
也就是说,默认情况下每个30秒服务会向注册中心发送一次心跳,证明自己还活着。如果超过90秒没有发送心
跳,EurekaServer就会认为该服务宕机,会从服务列表中移除,这两个值在生产环境不要修改,默认即可。
当服务消费者启动时,会检测 eureka.client.fetch-registry=true 参数的值,如果为true,则会从Eureka Server服
务的列表拉取只读备份,然后缓存在本地。并且 每隔30秒 会重新拉取并更新数据。可以在 consumer-demo 项目
中通过下面的参数来修改:
eureka: client: registry-fetch-interval-seconds: 30
生产环境中,我们不需要修改这个值。
但是为了开发环境下,能够快速得到服务的最新状态,我们可以将其设置小一点。
如下的配置都是在EurekaServer服务端进行
当服务进行正常关闭操作时,它会触发一个服务下线的Rest请求给EurekaServer,告诉服务注册中心,要下线了,服务注册中心接受到请求之后,将该服务设置为下线状态
有时候,服务可能由于内存溢出或网络故障等原因,不能正常的工作,使得服务注册中心无法收到服务下线请求,那么,服务注册中心会在启动时创建一个定时任务,默认每隔60秒,将当前注册清单中,超过90秒未收到续约包的服务剔除,这个操作被成为失效剔除。
关停一个服务,就会在Eureka面板上看到一条警告。这表示触发了Eureka的自我保护机制。进入自我保护之后,不剔除任何实例。
当一个服务未按时进行心跳续约时,Eureka会统计最近15分钟心跳失败的服务实例的比例,是否超过了85%,如果统计出EurekaServer节点在短时间内丢失过多客户端(超过85%),Eureka会认为是网络故障,而不剔除服务。
在生产环境下,因为网络延迟等原因,心跳失败实例的比例很可能超标,但是此时就把服务剔除列表,显然是不恰当的,因为服务可能并没有宕机。Eureka会把当前实例的注册信息保护起来,不予剔除。
但在开发环境下,为了方便起见,一般都会关闭自我保护机制。将续约时间从默认的30秒修改为5秒,将失效剔除的等待时间默认30秒修改为5秒。利于开发阶段。
当前笔记所使用到的eureka参数
eureka:
server:
# 关闭自我保护机制,保证不可用服务及时被踢出
enable-self-preservation: false
#默认的失效剔除时间由 60*1000ms 改成 2000ms
eviction-interval-timer-in-ms: 2000
client:
# 表示是否将自己注册进Eureka 默认为true
register-with-eureka: true
# 表示是否从EurekaServer抓取已有的注册信息,
# 默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone:
# 集群版 指定多个
- http://eureka10086.com:10086/eureka/
- http://eureka10088.com:10088/eureka/
- http://eureka10087.com:10087/eureka/
# 单机版 指定一个
# http://localhost:10086/eureka
instance:
# 指定主机名集群写法 避免多个eureka 同名 ,映射的eureka10087.com 需要在host文件中添加映射
hostname: eureka10087.com
# 这里的用处主要体现在discoveryClient.getInstances("user-service").get(0).getHost(); 获取时,
# 获取的是ip地址名而不是主机名,
# 具体参考consumer的controller的queryById方法体
# 设置使用ip地址而不是主机名
# 主要配置在 discoveryClient.getInstances("user-service") 指定的微服务上
prefer-ip-address: true
# 单机模式下,使用本地地址无所谓,但是集群模式下最好使用域名映射端口
ip-address: 127.0.0.1
# 服务续约的间隔(在eurekaserver未收到心跳包超过90秒,就将该服务提供者剔除),默认90秒
lease-expiration-duration-in-seconds: 90
#服务失效时间( 指在注册服务完成以后,服务提供者会维持一个心跳,向eurekaServer发送rest请求,告诉eureka状态正常 ,超过30秒 则标识服务失效),默认30秒
lease-renewal-interval-in-seconds: 30
当前笔记使用到的各类默认时间的小结:
注册中心端配置:
每隔60秒,将当前注册清单中,超过90秒未收到续约包的服务剔除**(超时90秒的实例都存放在待剔除列表中,等待剔除)**
eureka: server: #默认的失效剔除时间由 60*1000ms 改成 2000ms eviction-interval-timer-in-ms: 2000 instance: # 服务续约的间隔(在eurekaserver未收到心跳包超过90秒,就将该服务提供者剔除),默认90秒 lease-expiration-duration-in-seconds: 90
客户端配置:
心跳包间隔时间( 续约间隔时间 ):
eureka: instance: #服务失效时间( 指在注册服务完成以后,服务提供者会维持一个心跳,向eurekaServer发送rest请求,告诉eureka状态正常 ,超过30秒则标识服务失效),默认30秒 lease-renewal-interval-in-seconds: 30
当前笔记使用的注解
@EnableDiscoveryClient //开启服务发现,用于将服务接入Eureka 和 @@EnableEurekaClient作用大致一致,异同点见下方说明
//Eureka继承了Ribbon,该注解引入了eureka包可以直接使用。
@LoadBalanced //该注解用于开启负载均衡,默认是轮询,即远程调用的微服务名称下有多台机器,调用时轮番调用,能减小服务端压力,用在创建restTemplate的方法上
@EnableEurekaServer //当前微服务加入注册中心,作为注册中心,服务端,用于eureka微服务
@EnableEurekaClient // 将当前微服务注册到注册中心,作为客户端
@EnableDiscoveryClient 和 @EnableEurekaClient的比较
**共同点:**都是能够让注册中心能够发现,扫描到该服务。
不同点:@EnableEurekaClient只适用于Eureka作为注册中心,@EnableDiscoveryClient 可以是其他注册中心(Zookeeper、Consul、Nacos等注册中心)。