spring|eureka使用总结

目录
Eureka常用配置
Eureka 单节点搭建
eureka多节点
服务注册的配置选项
Eureka单独使用
Rest服务调用
/eureka/status 服务状态
注册到eureka的服务信息查看
注册到eureka的具体的服务查看
服务续约
更改服务状态
删除状态更新
删除服务
元数据
EurekaClient
多网卡选择
Eureka 健康检查
安全配置
Server 优化
Client 优化

Eureka常用配置 服务端配置

eureka: instance: hostname: xxxxx# 主机名称 prefer-ip-address: true/false# 注册时显示ip server: enableSelfPreservation: true# 启动自我保护 renewalPercentThreshold: 0.85# 续约配置百分比

还需要在spring boot启动类中设置 @EnableEurekaServer 注解开启 Eureka 服务
客户端配置
eureka: client: register-with-eureka: true/false# 是否向注册中心注册自己 fetch-registry: # 指定此客户端是否能获取eureka注册信息 service-url:# 暴露服务中心地址 defaultZone: http://xxxxxx# 默认配置 instance: instance-id: xxxxx # 指定当前客户端在注册中心的名称


Eureka 单节点搭建 server端
pom.xml
org.springframework.cloud spring-cloud-starter-netflix-eureka-server 有的教程中还引入spring-boot-starter-web,其实不用。因为上面的依赖已经包含了它。在pom中点此依赖进去,一共点4次spring-cloud-netflix-eureka-server,发现web的依赖。

application.yml
eureka: client: #是否将自己注册到Eureka Server,默认为true,由于当前就是server,故而设置成false,表明该服务不会向eureka注册自己的信息 register-with-eureka: false #是否从eureka server获取注册信息,由于单节点,不需要同步其他节点数据,用false fetch-registry: false #设置服务注册中心的URL,用于client和server端交流 service-url: defaultZone: http://localhost:7900/eureka/

application.properties
#是否将自己注册到Eureka Server,默认为true,由于当前就是server,故而设置成false,表明该服务不会向eureka注册自己的信息 eureka.client.register-with-eureka=false #是否从eureka server获取注册信息,由于单节点,不需要同步其他节点数据,用false eureka.client.fetch-registry=false #设置服务注册中心的URL,用于client和server端交流 eureka.client.service-url.defaultZone=http://localhost:7900/eureka/

代码
启动类上添加此注解标识该服务为配置中心
@EnableEurekaServer
PS:Eureka会暴露一些端点。端点用于Eureka Client注册自身,获取注册表,发送心跳。
简单看一下eureka server控制台,实例信息区,运行环境信息区,Eureka Server自身信息区。

client端
pom.xml
org.springframework.cloud spring-cloud-starter-netflix-eureka-client

application.yml
#注册中心 eureka: client: #设置服务注册中心的URL service-url: defaultZone: http://root:root@localhost:7900/eureka/

ps:不想注册,设置成false即可,实例演示结果:注册中心没有实例信息。找控制台204信息也没有找到。
spring: cloud: service-registry: auto-registration: enabled: false

注册成功:
DiscoveryClient_API-LISTEN-ORDER/api-listen-order:30.136.133.9:port - registration status: 204

eureka多节点 搭建步骤
1.准备
准备2个节点部署eureka,也可以单机部署
修改本机host文件,绑定一个主机名,单机部署时使用ip地址会有问题
2.配置文件
节点 1:
#是否将自己注册到其他Eureka Server,默认为true 需要 eureka.client.register-with-eureka=true #是否从eureka server获取注册信息, 需要 eureka.client.fetch-registry=true #设置服务注册中心的URL,用于client和server端交流 #此节点应向其他节点发起请求 eureka.client.serviceUrl.defaultZone=http://ek2.com:7902/eureka/ #主机名,必填 eureka.instance.hostname=ek1.com management.endpoint.shutdown.enabled=true #web端口,服务是由这个端口处理rest请求的 server.port=7901

节点 2:
#是否将自己注册到其他Eureka Server,默认为true 需要 eureka.client.register-with-eureka=true #是否从eureka server获取注册信息, 需要 eureka.client.fetch-registry=true #设置服务注册中心的URL,用于client和server端交流 #此节点应向其他节点发起请求 eureka.client.serviceUrl.defaultZone=http://ek1.com:7902/eureka/ #主机名,必填 eureka.instance.hostname=ek2.com management.endpoint.shutdown.enabled=true #web端口,服务是由这个端口处理rest请求的 server.port=7902

两个节点的话,如下图内容 就算成功了
spring|eureka使用总结
文章图片

服务注册的配置选项 新建一个web项目,引入starterspring-cloud-starter-netflix-eureka-client
客户端
#续约发送间隔默认30秒,心跳间隔 eureka.instance.lease-renewal-interval-in-seconds=5 #表示eureka client间隔多久去拉取服务注册信息,默认为30秒,对于api-gateway,如果要迅速获取服务注册状态,可以缩小该值,比如5秒 eureka.client.registry-fetch-interval-seconds=5 # 续约到期时间(默认90秒) eureka.instance.lease-expiration-duration-in-seconds=60

服务端
#关闭自我保护模式 eureka.server.enable-self-preservation=false #失效服务间隔 eureka.server.eviction-interval-timer-in-ms=3000

Eureka单独使用 Rest服务调用 官方文档
https://github.com/Netflix/eureka/wiki/Eureka-REST-operations
Operation HTTP action Description
Register new application instance POST /eureka/v2/apps/appID Input: JSON/XMLpayload HTTPCode: 204 on success
De-register application instance DELETE /eureka/v2/apps/appID/instanceID HTTP Code: 200 on success
Send application instance heartbeat PUT /eureka/v2/apps/appID/instanceID HTTP Code: * 200 on success * 404 if instanceIDdoesn’t exist
Query for all instances GET /eureka/v2/apps HTTP Code: 200 on success Output: JSON/XML
Query for all appID instances GET /eureka/v2/apps/appID HTTP Code: 200 on success Output: JSON/XML
Query for a specific appID/instanceID GET /eureka/v2/apps/appID/instanceID HTTP Code: 200 on success Output: JSON/XML
Query for a specific instanceID GET /eureka/v2/instances/instanceID HTTP Code: 200 on success Output: JSON/XML
Take instance out of service PUT /eureka/v2/apps/appID/instanceID/status?value=https://www.it610.com/article/OUT_OF_SERVICE HTTP Code: * 200 on success * 500 on failure
Move instance back into service (remove override) DELETE /eureka/v2/apps/appID/instanceID/status?value=https://www.it610.com/article/UP (The value=UP is optional, it is used as a suggestion for the fallback status due to removal of the override) HTTP Code: * 200 on success * 500 on failure
Update metadata PUT /eureka/v2/apps/appID/instanceID/metadata?key=value HTTP Code: * 200 on success * 500 on failure
Query for all instances under a particular vip address GET /eureka/v2/vips/vipAddress * HTTP Code: 200 on success Output: JSON/XML * 404 if the vipAddressdoes not exist.
Query for all instances under a particular secure vip address GET /eureka/v2/svips/svipAddress * HTTP Code: 200 on success Output: JSON/XML * 404 if the svipAddressdoes not exist.
/eureka/status 服务状态
使用浏览器请求url会返回服务器状态信息
test 16 526mb 183mb (34%) 00:00 localhost localhost UNKNOWN 192.168.29.1 UP UNKNOWN8080 443 1 MyOwn 30 90 0 0 0 0 8080 7649 http://localhost:8080/ http://localhost:8080/actuator/info http://localhost:8080/actuator/health unknown unknown false 1586328420409 1586328420519

如果需要json格式 可以加个请求头Accept:application/json
{ "generalStats": { "environment": "test", "num-of-cpus": "16", "total-avail-memory": "517mb", "current-memory-usage": "45mb (8%)", "server-uptime": "00:03" }, "applicationStats": { "registered-replicas": "", "available-replicas": "", "unavailable-replicas": "" }, "instanceInfo": { "instanceId": "localhost", "hostName": "localhost", "app": "UNKNOWN", "ipAddr": "192.168.29.1", "status": "UP", "overriddenStatus": "UNKNOWN", "port": { "$": 8080, "@enabled": "true" }, "securePort": { "$": 443, "@enabled": "false" }, "countryId": 1, "dataCenterInfo": { "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo", "name": "MyOwn" }, "leaseInfo": { "renewalIntervalInSecs": 30, "durationInSecs": 90, "registrationTimestamp": 0, "lastRenewalTimestamp": 0, "evictionTimestamp": 0, "serviceUpTimestamp": 0 }, "metadata": { "management.port": "8080", "jmx.port": "7649" }, "homePageUrl": "http://localhost:8080/", "statusPageUrl": "http://localhost:8080/actuator/info", "healthCheckUrl": "http://localhost:8080/actuator/health", "vipAddress": "unknown", "secureVipAddress": "unknown", "isCoordinatingDiscoveryServer": "false", "lastUpdatedTimestamp": "1586328420409", "lastDirtyTimestamp": "1586328420519" }

注册到eureka的服务信息查看
get: {ip:port}/eureka/apps
注册到eureka的具体的服务查看
get: {ip:port}/eureka/apps/{appname}/{id}
服务续约
put:{ip:port}/eureka/apps/{appname}/{id}?lastDirtyTimestamp={}&status=up
更改服务状态
put:{ip:port}/eureka/apps/{appname}/{id}/status?lastDirtyTimestamp={}&value=https://www.it610.com/article/{UP/DOWN}
对应eureka源码的:InstanceResource.statusUpdate
删除状态更新
delete:{ip:port}/eureka/apps/{appname}/{id}/status?lastDirtyTimestamp={}&value=https://www.it610.com/article/{UP/DOWN}
删除服务
delete: {ip:port}/eureka/apps/{appname}/{id}
元数据 Eureka的元数据有两种:标准元数据和自定义元数据。 标准元数据:主机名、IP地址、端口号、状态页和健康检查等信息,这些信息都会被发布在服务注册表中,用于服务之间的调用。 自定义元数据:可以使用eureka.instance.metadata-map配置,这些元数据可以在远程客户端中访问,但是一般不改变客户端行为,除非客户端知道该元数据的含义。
可以在配置文件中对当前服务设置自定义元数据,可后期用户个性化使用
元数据可以配置在eureka服务器和eureka的客户端上
eureka.instance.metadata-map.dalao=mashibing

或者调用url,post请求,动态修改元数据
http://localhost:7900/eureka/apps/SERVICE-SMS/SHW12357:service-sms:8003/metadata?version=test
SERVICE-SMS:服务名
SHW12357:service-sms:8003:实例ID

服务端:
spring|eureka使用总结
文章图片

客户端:
{ "applications": { "versions__delta": "1", "apps__hashcode": "UP_2_", "application": [ { "name": "EUREKA-CONSUMER", "instance": [ { "instanceId": "localhost:Eureka-Consumer:9001", "hostName": "localhost", "app": "EUREKA-CONSUMER", "ipAddr": "192.168.29.1", "status": "UP", "overriddenStatus": "UNKNOWN", "port": { "$": 9001, "@enabled": "true" }, "securePort": { "$": 443, "@enabled": "false" }, "countryId": 1, "dataCenterInfo": { "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo", "name": "MyOwn" }, "leaseInfo": { "renewalIntervalInSecs": 30, "durationInSecs": 90, "registrationTimestamp": 1586331982283, "lastRenewalTimestamp": 1586331982283, "evictionTimestamp": 0, "serviceUpTimestamp": 1586331982283 }, "metadata": { "dalao": "mashibing666", "management.port": "9001", "jmx.port": "10158" }, "homePageUrl": "http://localhost:9001/", "statusPageUrl": "http://localhost:9001/actuator/info", "healthCheckUrl": "http://localhost:9001/actuator/health", "vipAddress": "Eureka-Consumer", "secureVipAddress": "Eureka-Consumer", "isCoordinatingDiscoveryServer": "false", "lastUpdatedTimestamp": "1586331982283", "lastDirtyTimestamp": "1586331982260", "actionType": "ADDED" }, { "instanceId": "localhost:Eureka-Consumer:9000", "hostName": "localhost", "app": "EUREKA-CONSUMER", "ipAddr": "192.168.29.1", "status": "UP", "overriddenStatus": "UNKNOWN", "port": { "$": 9000, "@enabled": "true" }, "securePort": { "$": 443, "@enabled": "false" }, "countryId": 1, "dataCenterInfo": { "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo", "name": "MyOwn" }, "leaseInfo": { "renewalIntervalInSecs": 30, "durationInSecs": 90, "registrationTimestamp": 1586331637223, "lastRenewalTimestamp": 1586332057220, "evictionTimestamp": 0, "serviceUpTimestamp": 1586331637223 }, "metadata": { "dalao": "mashibing", "management.port": "9000", "jmx.port": "10000" }, "homePageUrl": "http://localhost:9000/", "statusPageUrl": "http://localhost:9000/actuator/info", "healthCheckUrl": "http://localhost:9000/actuator/health", "vipAddress": "Eureka-Consumer", "secureVipAddress": "Eureka-Consumer", "isCoordinatingDiscoveryServer": "false", "lastUpdatedTimestamp": "1586331637223", "lastDirtyTimestamp": "1586331637182", "actionType": "ADDED" } ] } ] } }


EurekaClient EurekaClient 可以在客户端获取eureka服务器上的注册者信息
org.springframework.cloud.client.discovery与com.netflix.discovery.DiscoveryClient
org.springframework.cloud.client.discovery是SpringCloud对注册中心client的抽象封装,提供公用功能
org.springframework.cloud.client.discovery定义用来服务发现的客户端接口,是客户端进行服务发现的核心接口,是spring cloud用来进行服务发现的顶级接口,在common中可以看到其地位。在Netflix Eureka和Consul中都有具体的实现类。
代表通用于服务发现的读操作,例如在 eureka或consul中。
com.netflix.discovery.DiscoveryClient为Eureka注册中心客户端的接口,功能更丰富
可以直接 autowired一个DiscoveryClient,然后获取服务实例
有 String description(); //获取实现类的描述。 List getServices(); //获取所有服务实例id。 List getInstances(String serviceId); //通过服务id查询服务实例信息列表。

多网卡选择 ip注册
eureka: instance: prefer-ip-address: true 表示将自己的ip注册到EurekaServer上。不配置或false,表示将操作系统的hostname注册到server

服务器有多个网卡,eh0,eh1,eh2,只有eh0可以让外部其他服务访问进来,而Eureka client将eh1和eh2注册到Eureka server上,这样其他服务就无法访问该微服务了。
指定Ip
eureka: instance: prefer-ip-address: true ip-address: 实际能访问到的Ip

如果设置了此时的ip-address,在元数据查看到就是此ip,其他服务也通过此ip来调用。
{ "host": "127.0.0.1", "port": 8084, "metadata": { "yueyi": "2019", "user.password": "root", "management.port": "8084", "jmx.port": "61378", "user.name": "root" }, "secure": false, "uri": "http://127.0.0.1:8084", "instanceId": "api-listen-order:30.136.133.11:port", "serviceId": "API-LISTEN-ORDER", "instanceInfo": { "instanceId": "api-listen-order:30.136.133.11:port", "app": "API-LISTEN-ORDER", "appGroupName": null, "ipAddr": "127.0.0.1", "sid": "na", "homePageUrl": "http://127.0.0.1:8084/", "statusPageUrl": "http://127.0.0.1:8084/actuator/info", "healthCheckUrl": "http://127.0.0.1:8084/actuator/health", "secureHealthCheckUrl": null, "vipAddress": "api-listen-order", "secureVipAddress": "api-listen-order", "countryId": 1, "dataCenterInfo": { "@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo", "name": "MyOwn" }, "hostName": "127.0.0.1", "status": "UP", "overriddenStatus": "UNKNOWN", "leaseInfo": { "renewalIntervalInSecs": 1, "durationInSecs": 1, "registrationTimestamp": 1579489514655, "lastRenewalTimestamp": 1579489524146, "evictionTimestamp": 0, "serviceUpTimestamp": 1579489514147 }, "isCoordinatingDiscoveryServer": false, "metadata": { "yueyi": "2019", "user.password": "root", "management.port": "8084", "jmx.port": "61378", "user.name": "root" }, "lastUpdatedTimestamp": 1579489514655, "lastDirtyTimestamp": 1579489514111, "actionType": "ADDED", "asgName": null }, "scheme": null }

或者使用spring.cloud.inetutils配置网卡选择
Eureka 健康检查 由于server和client通过心跳保持 服务状态,而只有状态为UP的服务才能被访问。看eureka界面中的status。
比如心跳一直正常,服务一直UP,但是此服务DB连不上了,无法正常提供服务。
此时,我们需要将 微服务的健康状态也同步到server。只需要启动eureka的健康检查就行。这样微服务就会将自己的健康状态同步到eureka。配置如下即可。
开启手动控制
在client端配置:将自己真正的健康状态传播到server。
eureka: client: healthcheck: enabled: true

Client端配置Actuator
org.springframework.boot spring-boot-starter-actuator

改变健康状态的Service
@Service public class HealthStatusService implements HealthIndicator{ private Boolean status = true; public void setStatus(Boolean status) { this.status= status; } @Override public Health health() { // TODO Auto-generated method stub if(status) return new Health.Builder().up().build(); return new Health.Builder().down().build(); } public String getStatus() { // TODO Auto-generated method stub return this.status.toString(); }

测试用的Controller
@GetMapping("/health") public String health(@RequestParam("status") Boolean status) {healthStatusSrv.setStatus(status); return healthStatusSrv.getStatus(); }

安全配置 开启Eureka安全连接
spring.security.user.name=yiming spring.security.user.password=123

spring|eureka使用总结
文章图片


如果服务注册报错
Root name 'timestamp' does not match expected ('instance') for type [simple

是默认开启了防止跨域攻击
手动关闭csrf
在服务端增加配置类
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter{ @Override protected void configure(HttpSecurity http) throws Exception { // TODO Auto-generated method stub http.csrf().disable(); super.configure(http); }}

Server 优化 自我保护的选择,看网络和服务的状态
如果微服务数量少,可以开启自我保护
如果微服务数量多,可以关闭自我保护,因为10个实例,默认是0.85,只要损失2个,就进入自我保护阶段,不稳定。
如果关闭自我保护,可以缩小心跳速度,缓存的同步时间,剔除服务时间的间隔,并且关闭readOnly读注册表,从而减少服务上下线的延时
server: # 自我保护,看服务多少。 enable-self-preservation: false # 自我保护阈值 renewal-percent-threshold: 0.85 # 剔除服务时间间隔 eviction-interval-timer-in-ms: 1000 # 关闭从readOnly读注册表 use-read-only-response-cache: false # readWrite 和 readOnly 同步时间间隔。 response-cache-update-interval-ms: 1000

如果服务被更新了(发版本了),要先停止服务,再发送下线请求
Client 优化 client配置总结
减小拉注册表的间隔和心跳时间
client: registry-fetch-interval-seconds: 5 刷新注册表(拉取注册表)间隔instance: lease-renewal-interval-in-seconds: 10,心跳续约间隔。 lease-expiration-duration-in-seconds: 10,缺心跳过期时间。

可以设置饥饿加载。防止第一次请求超时。
service-url:打乱 配置。不要所有服务都写一样顺序的配置。
【spring|eureka使用总结】我们在生产中配置eureka.client.service-url.defaultZone的时候,各个client端的配置尽量要随机一下,即打乱一下defaultZone中url的顺序,这是因为在拉取注册表的时候,默认从第一个url开始拉取,拉取不到才从下一个拉取,并且最多只能拉取3个;同时,在注册的时候,只会注册到第一个url,不会注册到下面的url。所以我们打乱了顺序以后,就减少了对某一个server的依赖,也降低了对某一个server的请求次数。

    推荐阅读