Eureka
Eureka使用步骤
-
eureka服务端
-
添加eureka-server依赖坐标
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
-
eureka-server配置项
server: port: 9001 spring: application: name: eureka-service eureka: client: register-with-eureka: false #是否将自己注册到注册中心,单机服务可以不开启 fetch-registry: false #是否从注册中心拉取数据,单机服务可以不开启 #暴露给Eureka Client的请求地址 service-url: defaultZone: http://127.0.0.1:9001/eureka/
-
修改启动类注解
@EnableEurekaServer @SpringBootApplication public class EurekaServiceApplication { public static void main(String[] args) { SpringApplication.run(EurekaServiceApplication.class, args); } }
-
-
服务提供方
-
添加eureka-client依赖坐标
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>2.2.2.RELEASE</version> </dependency>
-
添加配置项
eureka: client: service-url: defaultZone: http://localhost:9001/eureka/
-
修改启动类注解
//激活EurekaClient //@EnableEurekaClient //或者使用@EnableDiscoveryClient,当配置了defaultZone时,即使不开启注解也会自从注册的eureka注册中心 @EnableDiscoveryClient @SpringBootApplication @MapperScan("com.cloud.userservice.mapper") public class UserServiceApplication { public static void main(String[] args) { SpringApplication.run(UserServiceApplication.class, args); } }
-
-
服务消费方
1、2、3、与服务提供方类似
4、在调用服务的地方修改获取服务提供方地址方式
//自动注入DiscoveryClient @Autowired DiscoveryClient discoveryClient; @GetMapping("/getUserById/{id}") public User getUserById(@PathVariable Long id){ String url = "http://localhost:8001/user/getUserById/"+id; //根据服务注册名称获取服务实例列表 List<ServiceInstance> instances = discoveryClient.getInstances("user-service"); ServiceInstance serviceInstance = instances.get(0); //获取服务的ip+port url = "http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/user/getUserById/"+id; return restTemplate.getForObject(url,User.class); }
Eureka高可用
配置多台eureka-server,开启发现注册和拉取服务,互相注册
server:
port: 9001
spring:
application:
name: eureka-service
eureka:
client:
#暴露给Eureka Client的请求地址
service-url:
defaultZone: http://127.0.0.1:9002/eureka/,http://127.0.0.1:9003/eureka/
server:
port: 9002
spring:
application:
name: eureka-service
eureka:
client:
#暴露给Eureka Client的请求地址
service-url:
defaultZone: http://127.0.0.1:9001/eureka/,http://127.0.0.1:9003/eureka/
server:
port: 9003
spring:
application:
name: eureka-service
eureka:
client:
#暴露给Eureka Client的请求地址
service-url:
defaultZone: http://127.0.0.1:9001/eureka/,http://127.0.0.1:9002/eureka/
Eureka细节问题
在控制台显示服务IP
配置使用ip地址和并向注册中心注册ip地址
eureka:
client:
service-url:
defaultZone: http://localhost:9001/eureka/
instance:
prefer-ip-address: true #使用ip地址注册
instance-id: ${spring.cloud.client.ip-address}:${port} #向注册中心注册服务id
Eureka的服务剔除问题
服务的提供者,设置心跳间隔和续约到期时间
eureka:
client:
service-url:
defaultZone: http://localhost:9001/eureka/
instance:
prefer-ip-address: true #使用ip地址注册
instance-id: ${spring.cloud.client.ip-address}:${port} #向注册中心注册服务id
lease-renewal-interval-in-seconds: 5 #发送心跳间隔,默认30秒
lease-expiration-duration-in-seconds: 10 #续约到期时间,默认90秒
Eureka的自我保护机制
开发阶段可在eureka-server中配置关闭自我保护和服务剔除时间
server:
enable-self-preservation: false #是否开启自我保护机制 默认true
eviction-interval-timer-in-ms: 4000 #服务宕机后多久剔除服务
consul
1 安装启动
进入consul的安装目录
##以开发者模式快速启动
consul agent -dev -client=0.0.0.0
agent:启动一个consul的守护进程
dev:开发者模式
client:是consul代理,和consul server交互
可以有多个
一个微服务对应一个client
微服务和client部署到同一台机器上
server:真正工作的consul服务
官方推荐3-5个
Gossip:流言协议
所有的consul节点都会参与到gossip协议中(多节点中数据赋值)
服务端Raft协议: http://thesecretlivesofdata.com/raft/ (可视化算法流程图)
保证server集群的数据一致
Leader:是server集群中唯一处理客户端请求的
Follower:选民,被动接受数据
候选人:可以被选举为Leader
进入到管理后台界面
http://{{ip}}:8500
2 入门案例
-
提供一个服务者微服务
-
提供一个消费者服务
-
将微服务注册到注册中心consul
-
依赖
<!-- springcloud提供的基于consul的服务发现--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> <version>2.2.0.RELEASE</version> </dependency> <!-- actuator健康检查 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
-
配置
#配置consul的服务注册 cloud: consul: host: 127.0.0.1 #consul服务器的主机地址 port: 8500 #consul服务器的端口地址 discovery: register: true #是否需要注册 instance-id: ${spring.application.name}-${server.port} #注册的实例ID(唯一标志) service-name: ${spring.application.name} #服务的名称 port: ${server.port} #服务的请求端口 prefer-ip-address: true #指定开启ip地址注册 ip-address: ${spring.cloud.client.ip-address}#当前服务的请求ip
-
-
服务的消费者从consul中拉取所有的服务列表
-
依赖和配置同上
-
对RestTemplate bean添加@LoadBalanced注解
/** * springcloud 对consul进行了进一步的处理 * 向其中集成了ribbon的支持 * @return */ @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); }
-
Controller调用端中继续使用服务名发起请求
@GetMapping("/getUserById/{id}") public User getUserById(@PathVariable Long id) { String url = "http://user-service/user/getUserById/"+id; return restTemplate.getForObject(url, User.class); }
-
3 consule高可用集群
-
下载安装consul
- 下载后解压
- 移动至/usr/local/bin
- 使用consul命令测试
-
启动每个consul server节点
## 登录s1服务器,以server形式运行 consul agent -server -bootstrap-expect 3 -data-dir /etc/consul.d -node=server-1 -bind=192.168.74.101 -ui -client 0.0.0.0 & ## 登录s2服务器,以server形式运行 consul agent -server -bootstrap-expect 2 -data-dir /etc/consul.d -node=server-2 -bind=192.168.74.102 -ui -client 0.0.0.0 & ## 登录s3服务器,以server形式运行 consul agent -server -bootstrap-expect 2 -data-dir /etc/consul.d -node=server-3 -bind=192.168.74.103 -ui -client 0.0.0.0 &
-server:以server身份启动
-bootstrap-expect:集群要求的最少server数量,当低于这个数量,集群即失效。
-data-dir:data存放的目录,更多信息请参阅consul数据同步机制
-node:节点id,在同一集群中不能重复
-bind:监听的ip地址
-ui:打开web监控页面
-client:客户端的ip地址(0.0.0.0表示不限制)
&:后台运行
-
三个consul server模式服务全部启动完成
##在本地电脑上使用client形式启动consul consul agent -client=0.0.0.0 -bind=192.168.74.1 -data-dir /etc/consul.d -node=client-1
-
每个节点加入集群
在s2、s3、s4服务器上通过consul join命令加入s1的consul中
## 加入consul集群 consul join 192.168.74.101
-
在任意一台服务器中输入consul members查看集群中的所有节点信息
##查看consul集群节点信息 consul members
4 consul常见问题
- 节点的服务注销
当服务或节点失效,consul不会对注册的信息进行剔除处理,仅仅标记状态(并且不可使用)。如果担心失效节点和失效服务过多影响监控。可以通过调用HTTP API的形式进行处理:
节点和服务的注销可以使用HTTP API:
- 注销任意节点和服务:/catalog/deregister
- 注销当前节点和服务:/agent/service/deregister/:service_id
如果某个节点不继续使用了,也可以在本机使用consul leave命令,或者在其他节点使用consul force-leave 节点id.
-
健康检查和故障转移
在集群环境下,健康检查是由服务注册到Agent来处理的,那么如果这个Agent挂掉了,那么此节点的健康检查就处于无人管理的状态.
从实际应用看,节点上的服务可能既要被发现,又要发现别的服务,如果节点挂掉了,仅提供被发现了的功能实际上服务还是不可用的.当然发现别的服务也可以不使用本机节点,可以通过访问一个Nginx实现的若干consul节点的负载均衡来实现.