Eureka
第一章 eureka简介
Eureka 一个用于服务注册和发现的组件
Eureka:
Eureka server 为服务注册中心
Eureka client 为Eureka客户端
Eureka架构中三种角色:
Register Service 服务注册中心,Eureka server 提供服务注册和发现的功能
Provider Service 服务提供者,Eureka client 提供服务
Consumer Service 服务消费者,Eureka client 消费服务
第二章 Eureka server
2.1. 主maven模块
主maven模块为项目父节点模块,pom.xml配置
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.1.RELEASE</version> </parent> <groupId>com.kai.springcloud</groupId> <artifactId>cloud-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <description>a micro service cloud demo</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8 </project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR6</spring-cloud.version> <mapper.starter.version>2.1.5</mapper.starter.version> <mysql.version>8.0.20</mysql.version> </properties> <dependencyManagement> <dependencies> <!-- spring cloud --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- 通用mapper启动器 --> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>${mapper.starter.version}</version> </dependency> <!-- mysql驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 修改后立即生效,热部署 --> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <classifier>exec</classifier> </configuration> </plugin> </plugins> </build> <modules> <module>common</module> <module>consumer-80</module> <module>provider-9001</module> <module>eureka-server-7001</module> <module>eureka-server-7002</module> <module>eureka-server-7003</module> </modules> </project>
2.2. Eureka server端配置
2.2.1. 起步依赖
<!-- eureka 服务端依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2.2.2. Application.yml配置
server: port: 7001 eureka: instance: hostname: localhost appname: eureka-server-7001 #eureka服务端的实例名称 client: registerWithEureka: false #向注册中心注册(eureka server本身不需要向自己注册),默认true fetchRegistry: false #此客户端是否获取eureka服务器注册表上的注册信息(自己不需要获取自己),默认true serviceUrl: defaultZone: #http://${eureka.instance.hostname}:${server.port}/eureka/ http://eureka-server-7001:7001/eureka/
2.2.3. 启动类
启动类中需要加上@EnableEurekaServer来开启 eureka server功能
@EnableEurekaServer @SpringBootApplication public class EurekaServerApplication { public static void main(String[] args) throws Exception { SpringApplication.run(EurekaServerApplication.class, args); }
2.3. Eureka client端
2.3.1. 起步依赖
<!-- eureka 客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.3.2. Application.yml配置
server: port: 9001 spring: application: name: provider-9001 eureka: client: registerWithEureka: true fetchRegistry: true serviceUrl: defaultZone: http://eureka-server-7001:7001/eureka/ instance: instance-id: provider-9001 prefer-ip-address: true
2.3.3. 启动类
@EnableEurekaClient @SpringBootApplication @MapperScan("com.kai.cloud.mapper") public class Provider_StartSpringCloudApp
2.4. 界面
第三章 Eureka特性
3.1. 概念术语
3.1.1. Reguster 服务注册
Eureka client向Eureka server注册时,提供自身元数据(ip地址,端口,运行状况,主页地址等)
Eureka client 在配置文件中没有配置ServiceId,则服务名为${spring.application.name}
源码:
配置文件
com.netflix.discovery.DefaultEurekaClientConfig
com.netflix.discovery.PropertyBasedClientConfigConstants
Client端
com.netflix.discovery.DiscoveryClient(实现了EurekaClient接口)
boolean register() throws Throwable { logger.info(PREFIX + "{}: registering service...", appPathIdentifier); EurekaHttpResponse<Void> httpResponse; try { httpResponse = eurekaTransport.registrationClient.register(instanceInfo); } catch (Exception e) { logger.warn(PREFIX + "{} - registration failed {}", appPathIdentifier, e.getMessage(), e); throw e; } if (logger.isInfoEnabled()) { logger.info(PREFIX + "{} - registration status: {}", appPathIdentifier, httpResponse.getStatusCode()); } return httpResponse.getStatusCode() == Status.NO_CONTENT.getStatusCode(); }
com.netflix.discovery.InstanceInfoReplicator
run()
com.netflix.discovery.DiscoveryClient
initScheduledTasks()
Server端:
com.netflix.eureka.EurekaBootStrap
initEurekaServerContext()
registry = new PeerAwareInstanceRegistryImpl( eurekaServerConfig, eurekaClient.getEurekaClientConfig(), serverCodecs, eurekaClient );
com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl
public void register(final InstanceInfo info, final boolean isReplication) { int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS; if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) { leaseDuration = info.getLeaseInfo().getDurationInSecs(); } super.register(info, leaseDuration, isReplication); replicateToPeers(Action.Register, info.getAppName(), info.getId(), info, null, isReplication); }
com.netflix.eureka.resources.ApplicationResource
addInstance
3.1.2. Renew 服务续约
Eureka client默认情况下每隔30秒发送一次心跳来进行服务续约,来通知Eureka server该client服务仍然可用。
正常情况下,Eureka server在90秒内没有收到client端的心跳,Eureka server会将该client实例从注册列表中删除。
源码:
com.netflix.discovery.DiscoveryClient
boolean renew() { EurekaHttpResponse<InstanceInfo> httpResponse; try { httpResponse = eurekaTransport.registrationClient.sendHeartBeat(instanceInfo.getAppName(), instanceInfo.getId(), instanceInfo, null); logger.debug(PREFIX + "{} - Heartbeat status: {}", appPathIdentifier, httpResponse.getStatusCode()); if (httpResponse.getStatusCode() == Status.NOT_FOUND.getStatusCode()) { REREGISTER_COUNTER.increment(); logger.info(PREFIX + "{} - Re-registering apps/{}", appPathIdentifier, instanceInfo.getAppName()); long timestamp = instanceInfo.setIsDirtyWithTime(); boolean success = register(); if (success) { instanceInfo.unsetIsDirty(timestamp); } return success; } return httpResponse.getStatusCode() == Status.OK.getStatusCode(); } catch (Throwable e) { logger.error(PREFIX + "{} - was unable to send heartbeat!", appPathIdentifier, e); return false; } }
3.1.3. Fatch Registries 获取服务注册列表信息
Eureka client从Eureka server 获取服务注册列表信息,并将其缓存在本地,该信息列表信息每30秒更新一次
3.1.4. Cancel 服务下线
Eureka client程序关闭时可以向Eureka server 发送下线请求,发送请求后,client实例信息将从Eureka server的服务注册列表中删除。
该下线请求不会自动完成,需要在程序关闭时调用代码:
DisconveryManager.getInstance().shutdownComponent();
3.1.5. Eviction 服务剔除
默认情况下,当client在90秒内没有想Eureka server发送服务续约,Eureka server会将该服务实例从服务注册列表中删除。
3.1.6. Eureka client注册延迟
Client启动后,不是立即向Eureka server注册,而是有一个延迟时间,默认延迟时间为40秒
com.netflix.discovery.DefaultEurekaClientConfig
com.netflix.discovery.PropertyBasedClientConfigConstants
public int getInitialInstanceInfoReplicationIntervalSeconds() { return configInstance.getIntProperty( namespace + INITIAL_REGISTRATION_REPLICATION_DELAY_KEY, 40).get(); }
3.1.7. Eureka server响应缓存
Eureka Server 维护每 30 更新一次响应缓存,可通过更改配置eureka.server.responseCacheUpdateIntervalMs来修改。所以即使是刚刚注册的实例,也不会立即出现在服务注册列表中。
3.1.8. Eureka client缓存
Eureka client保留注册表信息的缓存,每30秒更新一次。
3.1.9. LoadBalance缓存
Ribbon缓存,从本地的Eureka client获取服务注册列表信息,每30刷新一次,可通过配置修改:ribbom.ServerListRefreshInterval
3.2. Eureka的自我保护模式
如果Eureka server接收到的服务续约低于阈值的百分比(默认为15分钟内低于85%),则服务器开启自我保护模式,不再剔除注册列表信息。
这样主要是因为如果Eureka server自身网络出现问题而导致Eureka client无法续约,注册列表信息不再删除,Eureka client还可以别其他服务消费。
关闭自我保护模式:
Eureka: Server: Enable-self-preservation: false
第四章 Eureka server 集群
4.1. 集群中yml文件配置
Server1:
server: port: 7001 eureka: instance: hostname: localhost appname: eureka-server-7001 #eureka服务端的实例名称 client: registerWithEureka: false #向注册中心注册(eureka server本身不需要向自己注册),默认true fetchRegistry: false #此客户端是否获取eureka服务器注册表上的注册信息(自己不需要获取自己),默认true serviceUrl: defaultZone: #http://${eureka.instance.hostname}:${server.port}/eureka/ #http://eureka-server-7001:7001/eureka/ http://eureka-server-7002:7002/eureka/,http://eureka-server-7003:7003/eureka/
Server2:
server: port: 7002 eureka: instance: hostname: localhost appname: eureka-server-7002 #eureka服务端的实例名称 client: registerWithEureka: false #向注册中心注册(eureka server本身不需要向自己注册),默认true fetchRegistry: false #此客户端是否获取eureka服务器注册表上的注册信息(自己不需要获取自己),默认true serviceUrl: defaultZone: #http://${eureka.instance.hostname}:${server.port}/eureka/ http://eureka-server-7001:7001/eureka/,http://eureka-server-7003:7003/eureka/
Server3:
server: port: 7003 eureka: instance: hostname: localhost appname: eureka-server-7003 #eureka服务端的实例名称 client: registerWithEureka: false #向注册中心注册(eureka server本身不需要向自己注册),默认true fetchRegistry: false #此客户端是否获取eureka服务器注册表上的注册信息(自己不需要获取自己),默认true serviceUrl: defaultZone: #http://${eureka.instance.hostname}:${server.port}/eureka/ http://eureka-server-7001:7001/eureka/,http://eureka-server-7002:7002/eureka/
4.2. 界面
4.3. 本地host文件修改
Window:
C:\Windows\System32\drivers\etc\hosts
#for eureka
127.0.0.1 eureka-server-7001
127.0.0.1 eureka-server-7002
127.0.0.1 eureka-server-7003
127.0.0.1 provider-9001
汇总: