Eureka 是 Netflix 开源服务发现组件,本身是一个基于 REST 的服务。它包含 Server 和 Client 两部分。Spring Cloud 将它集成在子项目 Spring Cloud Netflix 中。从而实现微服务注册和发现。
前言
- 所有内容基于 Spring Boot(2.0.0.RELEASE) 和 Gradle(4.5.1),建议使用 Intellij 编辑器 和 application.yml 配置文件
- 创建项目时 Web 为必选项
- 使用 Java 便可,不要使用 Groovy 。因为,如果 Java 中出现 Groovy ,Gradle 打包会报错。而且以 Groovy 写的 Controller,打包后不会被识别(所有地址都是404)
1、建立服务端 Eureka Server
添加Eureka服务端依赖(创建项目时选择 Eureka Server项便可)
compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-server')
启动类增加注解
@EnableEurekaServer
application.yml
配置文件中增加以下内容
server:port: 8761
eureka:client:# 禁止客户端添加自身register-with-eureka: falsefetch-registry: falseservice-url:defaultZone: http://localhost:8761/eureka/
启动项目,访问 http://localhsot:8761
可以看到 Eureka 的首页
2、建立客户端并注册到 Eureka Server
增加Eureka客户端依赖(创建项目时选择 Eureka Discovery便可)。使用服务端依赖也可以,服务端可同时支持服务端和客户端
compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')
启动类增加注解
@EnableEurekaClient
以上的注解只能使用 Eureka ,为了支持多种发现组件 Zookeeper、Consul等,可改为
@EnabelDiscoveryClient
application.yml
配置文件中增加以下内容
spring:applicaion:# 项目名name: microservice-provider-user
server:port: 8000
eureka:client:# 注册到 Serverservice-url:defaultZone: http://localhost:8761/eureka/instance:prefer-ip-address: true
先启动服务端,然后再启动客户端。之后可在 Eureka 首页看到客服端的注册信息
3、部署 Eureka Server 集群,增加可用性
Eureka Server 集群是服务端相互注册来提高整个服务的可用性部署
首先要配置系统的 hosts 文件。Windows hosts文件路径是 C:\Windows\System32\drivers\etc\hosts;Linux、Mac Os 等的路径是 /etc/hosts 。文件中增加以下行,文件编辑权限问题请自行百度。
127.0.0.1 peer1 peer2
建立一个服务端,application.yml
如下
spring:application:# 这个是项目的名字name: eureka-group
---
spring:# 指定profilesprofiles: peer1
server:port: 8761
eureka:instance:# 当指定profile=peer1时,主机名是peer1hostname: peer1client:service-url:# 注册到peer2这个EurekadefaultZone: http://peer2:8762/eureka/
---
spring:# 指定profilesprofiles: peer2
server:port: 8762
eureka:instance:# 当指定profile=peer2时,主机名是peer2hostname: peer2client:service-url:# 注册到peer1这个EurekadefaultZone: http://peer1:8761/eureka/
将应用打成 Jar 包, 若使用的是 Gradle , 使用终端进入项目目录执行以下命令
gradle build
显示 SUCCESS 后会在项目目录 build/lib 下生成jar包(名字由 version 和 项目名决定,我生成的是 eureka-group-0.0.1-SHAPSHOT)。使用终端分别执行:
java -jar eureka-group-0.0.1-SHAPSHOT.jar --spring.profiles.active=peer1
java -jar eureka-group-0.0.1-SHAPSHOT.jar --spring.profiles.active=peer2
第一个执行的必定会报错,因为要互相注册,第一个执行的找不到对方。但不影响后续
执行过后分别访问 http://peer1:8761和 http://peer2:8762进入 Eureka 首页会发现两个服务已经相互注册
客户端注册到服务端方式类似:
eureka:client:service-url:# 因为集群数据会同步,注册到一个节点便可。为适应极端情景,可注册多个节点。defaultZone: http://peer1:8761/eureka/,http://peer2:8762/eureka/
4、为 Eureka Server 增加用户认证
也就是在进入 Eureka 首页时需要输入密码,且注册时需要账号密码属性
加入 security 依赖
compile( 'org.springframework.boot:spring-boot-starter-security')
appliction.yml
中配置
security:basic:enabled: trueuser:name: userpassword: password123
如果不写这一段,默认的账号就是 user(最新版Spring Cloud似乎已经禁用此配置) ,密码会在启动时打印出来。现在进入 Eureka 首页会收到登录验证。
而现在客户端要注册到服务端需要修改以下配置为:
eureka:client:serviceUrl:# 用户:密码@服务器defaultZone: http://user:password123@localhost:8761/eureka/
5、Eureka 的元数据
Eureka 元数据分为标准元数据和自定义元数据
修改客户端的 application.yml
,使用 eureka.instance.metadata-map
增加自定义属性
eureka:client:service-url:defaultZone: http://localhost:8761/eureka/instance:prefer-ip-address: truemetadata-map:# 以下是自定义元数据, key/value 随便写my-metata: The Self-made meta-data
写 Controller
package ***.Controllerimport 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.RestController//@RestController = @ResponseBody + @Controller
@RestController("/")
public class Controller {
//!!应导入的是:org.springframework.cloud.client.discovery.DiscoveryClient@Autowiredprivate DiscoveryClient discoveryClient@GetMapping("/user-instance")public List<InstanceInfo> showInfo(){
return this.discoveryClient.getInstances("microservice-provider-user")}
}
启动服务端,然后启动客户端。访问 http://localhost:8000/user-instance
可以看到所有的元数据,包括自定义的
6、使用 Eureka 的 REST 端点注册和注销服务
非 JVM 的微服务可以使用 REST 端点操作 Eureka ,从而实现注册和发现
注册
首先,你需要 Curl 命令。Windows 系统到这里下载对应系统的 Curl ,把 curl.exe 放到 C:/Windows/System32 就能直接在 cmd 中使用了。Linux 或 Mac 可以使用。
然后,启动服务端
编写一个 XML ,命名为 rest-api-test.xml
<instance><instanceId>itmuch:rest-api-test:9000</instanceId><hostName>intmuch</hostName><app>REST-API-TEST</app><ipAddr>127.0.01</ipAddr><vipAddress>rest-api-test</vipAddress><secureVipAddress>rest-api-test</secureVipAddress><status>UP</status><port enable="true">9000</port><securePort enable="false">443</securePort><homePageUrl>http://127.0.0.1:9000</homePageUrl><statusPageUrl>http://127.0.0.1:9000/info</statusPageUrl><healthCheckUrl>http://127.0.0.1:9000/health</healthCheckUrl><dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo"><name>MyOwn</name></dataCenterInfo>
</instance>
Linux 或 Mac 中执行
cat rest-api-test.xml | curl -v -X POST -H "Content-type: application/xml" -d @- http://localhost:8761/eureka/apps/rest-api-test
Windows 下执行(Windows 对应的 cat 命令是 type )
type rest-api-test.xml | curl -v -X POST -H "Content-type: application/xml" -d @- http://localhost:8761/eureka/apps/rest-api-test
会输出类似以下信息:
* upload completely sent off: 664 out of 664 bytes
< HTTP/1.1 204
< Content-Type: application/xml
< Date: Wed, 14 Mar 2018 03:21:48 GMT
到 Eureka 首页发现服务已经注册。 访问 http://loaclhost:8761/eureka/apps/rest-api-test
能看到此服务的所有实例,以及实例想详细信息
注销
执行以下命令
curl -v -X DELETE http://localhost:8761/eureka/apps/rest-api-test/itmuch:rest-api-test:9000
输出类似以下的信息,服务就已经注销
< HTTP/1.1 200
< Content-Type: application/xml
< Content-Length: 0
< Date: Wed, 14 Mar 2018 04:16:49 GMT
因为服务 rest-api-test 并不存在,所以 Eureka Server 过一段时间后便会自动注销此服务
7、多网卡环境下 IP 选择
对于多网卡的服务器,Spring Cloud 提供了按需选择 IP 的能力
配置如下 请看注释:
springcloud:inetutils:# 1、忽略指定名称的网卡,以下忽略了 docker0 和 所有以 veth 开头的网卡ignored-interfaces:- docker0- veth.*# 2、使用正则表达式,指定使用的网络地址preferred-networks:- 192.168- 10.0# 3、只使用站点本地地址use-only-site-local-interfaces: true
eureka:instance:prefer-ip-address: true# 4、在某些极端场景下,可以手动指定注册到 Eureka Server 的微服务 IPid-address: 127.0.0,1
以上的方法按需选择
8、Eureka 的自我保护和自我检查
自我保护
- Eureka 进入自我保护最直观的体现是 Eureka Server 首页输出的警告
- 如果 Eureka Server 在一定时间内没有收到某个微服务的心跳(默认是90s)。但是如果网络分区故障发生时,微服务与 Eureka Server 之间无法正常通信,以上行为会变得非常危险——因为微服务本事是健康的,此时本不应该注销这个服务
- Eureka 通过“自我保护模式”来解决这个问题——当 Eureka Server 节点在短时间内丢失过多客服端时,那么这个节点就会进入自我保护模式。一旦进入自我保护模式, Eureka Server 就会保护服务注册表中的信息,不在删除服务注册表中的数据(不在注销任何微服务)。网络故障恢复后,该 Eureka Server 接待会自动退出自我保护模式。
可以使用以下配置来禁用自我保护模式:
eureka:server:enable-self-preservation: false
健康检查
在 Eureka Server 的首页,如果一个客户端和服务端的心跳保持正常,客户端 Status 的一栏会显示 “UP”。但仅仅代表心跳正常,不代表客户端一定可以连上数据源
Spring Boot Actuator 的 /health 端点可以展示应用程序的健康状况。引入 actuator 依赖:
compile('org.springframework.boot:spring-boot-starter-actuator')
然后开启以下配置,客户端就会将自己的健康状况发送给 Eureka Server
eureka:client:healthcheck:enabled:true
后记
以上的代码大多数经过我的测试
引用内容源自 《Spring Cloud与Docker微服务架构实战》/周立 著