文章目录
1 Eureka
1.1 基础知识
服务治理:
在传统的RPC远程调用框架中,管理每个服务与服务之间的依赖关系比较复杂,所以需要服务治理
来管理服务之间的依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现和注册
服务注册与发现:
Eureka采用CS的架构设计,Eureka Server作为服务注册功能的服务器
系统中的其他微服务使用Eureka客户端连接到Eureka Server并维持心跳连接
在服务注册与发现中,有一个注册中心,当微服务启动时会将自己的信息如ip端口等
以别名方式注册到注册中心上,而微服务消费者从注册中心上以别名的方式获取实际的ip端口等信息
然后再进行RPC调用,以注册中心来规避服务间复杂的依赖关系
Eureka架构设计:
Eureka Server
提供服务注册功能,作为注册中心
各个微服务节点通过配置启动后,会在EurekaServer中进行注册
这样EurekaServer中的服务注册表会存储所有可用服务节点信息
EurekaClient
是一个Java客户端,用于简化和EurekaServer的交互
客户端内置一个使用轮询负载算法的负载均衡器,在应用启动后,将向EurekaServer发送心跳
如EurekaServer在多个心跳周期内没有收到某个节点的心跳,EurekaServer将从服务注册表中移除它
1.2 搭建单机Eureka环境
1.2.1 Eureka服务端安装
1、在父项目下新建module,修改pom文件增加Eureka服务端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2、创建yaml文件,配置端口以及Eureka服务器参数
server:
port: 7001
eureka:
instance:
hostname: localhost
client:
# false表示不向注册中心注册自己
register-with-eureka: false
# false表示不需要检索服务 自己就是注册中心
fetch-registry: false
service-url:
# 设置与Eureka Server交互的地址查询服务和注册服务都需要依赖的地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
3、创建主启动类,并注明该微服务作为注册中心
4、启动微服务并在浏览器访问localhost:7001
1.2.2 Provider注册
将支付模块Cloud-Provider-Payment8001作为Eureka Client注册到Eureka Server
等待将来被发现并提供服务
1、首先在pom导入EurekaClient相关依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、yaml文件中增加作为Eureka Client的必要配置
server:
port: 8001
spring:
application:
name: cloud-payment-service
eureka:
client:
# 作为Client注册到Eureka Server
register-with-eureka: true
# 可以从Eureka Server抓取已有注册信息 可以配合ribbon使用负载均衡功能
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
3、启动类增加EurekaClient注解
此时可以在EurekaServer中看到注册好的Cloud-Provider-Payment8001
并看到状态以及地址信息:
1.2.3 Consumer注册
依次增加EurekaClient依赖,yaml配置
server:
port: 80
spring:
application:
name: cloud-order-service
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
在启动类上增加EurekaClient注释后,启动后可以再EurekaServer中观察到Consumer已注册
1.3 搭建Eureka集群
1.3.1 EurekaServer集群搭建
为了保证服务的高可用和避免单点故障,选择使用两台服务器组成EurekaServer集群
这两台服务器互相注册,相互守望
首先创建好两个子模块Cloud-Eureka-Server7001和Cloud-Eureka-Server7002
接着需要配置Host域名映射,详见Mac配置域名映射
修改yaml配置文件
Cloud-Eureka-Server7001:
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka7002.com:7002/eureka/
Cloud-Eureka-Server7002:
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
启动两个EurekaService服务,Eureka集群搭建成功:
1.3.2 Provider&Consumer注册到Eureka集群
作为服务提供者的Cloud-Provider-Payment8001和
服务消费者Cloud-Consumer-Order80无需做其他改动
只需修改yaml文件的defaultZone属性即可
Cloud-Provider-Payment8001:
server:
port: 8001
spring:
application:
name: cloud-payment-service
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
Cloud-Consumer-Order80同理
启动Cloud-Provider-Payment8001和Cloud-Consumer-Order80
在Eureka集群中已成功注册:
1.3.3 EurekaClient集群构建
Provider作为服务提供者也应该搭建集群
创建新模块Cloud-Provider-Payment8002,pom无需改动,yaml修改port即可
将Cloud-Provider-Payment8001和Cloud-Provider-Payment8002
加入EurekaClient集群,可以在Controller层中使用@Value注入port
以区分提供服务的机器是Provider集群中的哪台
启动后看到Cloud-Payment-Service有两台机器,以组成集群注册到EurekaServer集群
注意需要将Cloud-Consumer-Order80中Controller层的访问url更新
原先使用写死的http://localhost:8001开头,现在搭建集群后需要修改:
此时仍然是不能正常工作的,Consumer能找到Provider集群
但不知道使用集群中的哪一台,为此需要开启负载均衡功能@LoadBalanced采用轮询
让RestTemplate轮流选择Provider集群中的机器使用
1.4 Eureka补充
1.4.1 actuator微服务信息完善
在Eureka界面中,可以看到如下的信息:
可以自定义修改一些信息,如修改服务名称、访问信息增加IP提示
1、修改服务名称
在Cloud-Provider-Payment8001的yaml中的eureka属性中增加instance属性即可
更改后的yaml文件:
server:
port: 8001
spring:
application:
name: cloud-payment-service
eureka:
instance:
instance-id: payment8001
client:
# 作为Client注册到Eureka Server
register-with-eureka: true
# 可以从Eureka Server抓取已有注册信息 可以配合ribbon使用负载均衡功能
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
重新启动后:
服务正常:
2、访问信息增加IP提示
在yaml配置文件中的instance属性下新增配置即可:
eureka:
instance:
instance-id: payment8001
prefer-ip-address: true
client:
# 作为Client注册到Eureka Server
register-with-eureka: true
# 可以从Eureka Server抓取已有注册信息 可以配合ribbon使用负载均衡功能
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
1.4.2 服务发现Discovery
可以通过DiscoveryClient来获取集群中的服务信息
在Controller层注入DiscoveryClient:
并在启动类中增加@EnableDiscoveryClient注解:
通过discoveryClient提供的方法获取集群信息及某集群中的机器信息:
1.4.3 Eureka自我保护
在进入Eureka管理页面时,会看到如下一行红字:
这代表Eureka进入了保护模式
保护模式主要用于一组客户端和EurekaServer之间存在网络分区场景下的保护
进入保护模式后,EurekaServer将保护注册表中的信息,即不再删除注册表中的数据
也就是说不会注销任何微服务
也就是说某时刻某个微服务不可用了,但Eureka不会立刻清理
依旧会保存该微服务信息,属于CAP中的AP分支
这样做是为了保证高可用,如果因为短暂网络抖动,某个EurekaClient在几轮心跳周期内
没有给EurekaServer发送心跳包,此时如果立刻将它移除,这个行为是危险的
因为微服务本身是健康的,此时不应该注销这个服务
Eureka的保护模式宁可保留所有的微服务(健康的和不健康的),也不盲目注销微服务
使用自我保护模式,可以让Eureka集群更加健壮、稳定
当然也可以在yaml中关闭保护模式:
EurekaServer配置:
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
server:
# 禁用自我保护模式
enable-self-preservation: false
# 2s没有Client的心跳 立刻将client移出集群
eviction-interval-timer-in-ms: 2000
EurekaClient配置:
server:
port: 8001
spring:
application:
name: cloud-payment-service
instance:
instance-id: payment8001
prefer-ip-address: true
# Eureka客户端向服务器发送心跳的时间间隔(s)
lease-renewal-interval-in-seconds: 1
# Eureka服务端收到最后一次心跳后等待时间上限(s) 关闭保护模式后,超时将移除该服务
lease-expiration-duration-in-seconds: 120
client:
# 作为Client注册到Eureka Server
register-with-eureka: true
# 可以从Eureka Server抓取已有注册信息 可以配合ribbon使用负载均衡功能
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
2 Zookeeper
Zookeeper是一个分布式协调工具,架构类似于Eureka,同样可以实现注册中心的功能
在Linux系统中启动Zookeeper服务器,关闭防火墙
2.1 Provider注册
新建子模块Cloud-Provider-Payment8004
1、首先需要在pom中增加Zookeeper的客户端依赖
注意zk的版本需要与Linux中的zk版本一致,否则会冲突
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
2、配置yaml文件,指明Zookeeper服务器地址
server:
port: 8004
spring:
application:
name: cloud-provider-payment
cloud:
zookeeper:
connect-string: 192.168.111.144:2181
3、完成主启动类,需要加@EnableDiscoveryClient注解
以向Consul或Zookeeper注册服务
zk注册中心不具备保护模式,当一段时间后没有收到客户端心跳就将其移除
2.2 Consumer注册
新建子模块Cloud-Consumerzk-Order80
pom增加zk客户端依赖,yaml增加zk地址配置
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
server:
port: 80
spring:
application:
name: cloud-consumer-order
cloud:
zookeeper:
connect-string: 192.168.111.144:2181
主启动类上增加@EnableDiscoveryClient注解
Controller层访问Provider的url根据ZK注册中心内显示的填写
3 Consul
Consul是一套开源的分布式服务发现和配置管理体系,由HashiCorp公司用Go语言开发。
提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用构建全方位的服务网格。
3.1 Provider注册
新建子模块Cloud-Provider-Paymentconsul8006
1、在pom中增加consul客户端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
2、yaml中完成配置
server:
port: 8006
spring:
application:
name: consul-provider-payment
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
3、完成主启动类,增加@EnableDiscoveryClient注解
3.2 Consumer注册
新建子模块Cloud-Consumerconsul-Order80
pom增加zk客户端依赖,yaml增加zk地址配置
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
server:
port: 80
spring:
application:
name: consul-consumer-order
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
主启动类上增加@EnableDiscoveryClient注解
Controller层访问Provider的url根据Consul注册中心内显示的填写