微服务:整合 Spring Cloud Eureka - 高可用集群
目录
微服务:整合 Spring Cloud Eureka - 注册中心 Eureka Server
微服务:整合 Spring Cloud Eureka - 服务注册 Eureka Client
微服务:整合 Spring Cloud Eureka - 服务发现 DiscoveryClient
微服务:整合 Spring Cloud Eureka - 服务消费以及Ribbon简单使用
微服务:整合 Spring Cloud Eureka - 高可用集群
微服务:整合 Spring Cloud Eureka - .NET Core Mvc Api (C#)
微服务:整合 Spring Cloud Eureka - 服务治理机制
微服务:整合 Spring Cloud Eureka - 服务事件监听
微服务:整合 Spring Cloud Eureka - 高级属性Region、Zone
微服务:整合 Spring Cloud Eureka - Rest接口文档
微服务:整合 Spring Cloud Eureka - Security 安全保护
一、前言
前面我们已经说明了如何搭建Rureka注册中心,如何将服务提供者的服务地址注册到注册中心、已经服务消费者如何消费远程服务。其实前面都是基于单个实例进行讲解。今天将给大家讲解如何构建高可用的Eureka注册中心。
二、如何设计高可用注册中心
1、单实例架构图
从上图可以看出来,Eureka注册中心、Provider服务、Consumer服务,三个挂掉任何一个,都会让整个系统不可用。虽然这三个服务可以发布在三台服务器上,提高了系统性能,但是宕机的风险也越来越大。如果Eureka注册中心的可用性=90%、Provider服务的可用性=90%、Consumer服务的可用性=90%,那么整个系统的可用性就是0.9*0.9*0.9=0.729,即72.9%。这个可用性并不是我们想要的。于是高可用的服务集群就因运而生。
2、高可用架构图
- 在上图,我们将Eureka做了一个注册中心集群,共有三个实例。每个实例的可用性=90%,那么这三个注册中心的集群的可用心就是 1-(1-0.9)*(1-0.9)*(1-0.9)=99.9%。这个可用性就足以令人满意。
- Provider服务集群,假如我们的Provider服务是一个OAuth2的服务,那么其他的业务服务如:销售、订单、仓储服务就都是Consumer服务。如果OAuth2的服务只有一个,也会降低整体服务的可用性。因此OAuth2的服务也应该做服务集群以提高鉴权服务的可用性。三个Provider(OAuth2)服务也可以组成一个高可用集群。可用性也是 1-(1-0.9)*(1-0.9)*(1-0.9)=99.9%
- 对于Eureka而言,Consumer和Provider是一样的,都需要将服务地址注册到Eureka中。比如仓储服务调用OAuth2服务,那么仓储就是Consumer,OAuth2就是Provider。如果订单服务调用仓储服务,那么订单服务就是Consumer,仓储服务就是Provider。也就是说Consumer和Provider的角色是可以互换的。
- Consumer通过Ribbon负载均衡策略调用Provider集群中一个可用的服务。
三、Eureka服务注册中心集群代码实现
其实Eureka集群很容易实现,只需要简单的几个步骤就好了,因为Eureka内部已经帮我们做了大量的工作了。
1、修改Hosts文件,地址在:C:\Windows\System32\drivers\etc
添加如下配置:
127.0.0.1 peer1
127.0.0.1 peer2
127.0.0.1 peer3
2、项目结构
具体符合编写,请参考:微服务:整合 Spring Cloud Eureka - 注册中心 Eureka Server
3、修改application.yml
第一个实例的application.yml配置
server: port: 8001 servlet: context-path: /register spring: application: name: demo-register eureka: instance: hostname: peer1 client: #是否将该实例信息注册到其他eureka server上;如果设置为false,那么该server无法被其他server发现,但是仍然可以发现其他server register-with-eureka: true #是否允许该客户端从eureka server上获取注册信息 fetch-registry: true instance-info-replication-interval-seconds: 30 serviceUrl: defaultZone: http://peer2:8002/register/eureka/,http://peer3:8003/register/eureka/
第二个实例的application.yml配置:
server: port: 8002 servlet: context-path: /register spring: application: name: demo-register eureka: instance: hostname: peer2 client: #是否将该实例信息注册到其他eureka server上;如果设置为false,那么该server无法被其他server发现,但是仍然可以发现其他server register-with-eureka: true #是否允许该客户端从eureka server上获取注册信息 fetch-registry: true instance-info-replication-interval-seconds: 30 serviceUrl: defaultZone: http://peer1:8001/register/eureka/,http://peer3:8003/register/eureka/
第三个实例的application.yml配置:
server: port: 8003 servlet: context-path: /register spring: application: name: demo-register eureka: instance: hostname: peer3 client: #是否将该实例信息注册到其他eureka server上;如果设置为false,那么该server无法被其他server发现,但是仍然可以发现其他server register-with-eureka: true #是否允许该客户端从eureka server上获取注册信息 fetch-registry: true instance-info-replication-interval-seconds: 30 serviceUrl: defaultZone: http://peer1:8001/register/eureka/,http://peer2:8002/register/eureka/
4、运行效果:
第一个注册中心实例地址:http://localhost:8001/register/
第二个注册中心实例地址:http://localhost:8002/register/
第三个注册中心实例地址:http://localhost:8003/register/
四、将服务注册到Eureka注册中心集群中
将Provider服务注册到Rureka集群中,只需要修改一个配置即可:application.yml
server: port: 8101 spring: application: name: demo-service-provider eureka: instance: lease-renewal-interval-in-seconds: 20 hostname: peer1 client: register-with-eureka: true fetch-registry: true instance-info-replication-interval-seconds: 30 registry-fetch-interval-seconds: 10 serviceUrl: defaultZone: http://peer1:8001/register/eureka/,http://peer2:8002/register/eureka/,http://peer3:8003/register/eureka/
为了方便测试,我们修改 ProviderHelloController类:
package com.demo.service.provider.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/hello") public class ProviderHelloController { @Value("${server.port}") String server_port; @RequestMapping("/sayhello/{name}") public String sayHello(@PathVariable("name")String name){ return "(port:"+ server_port +")hello , " + name; } }
启动三个实例,单个端口号为:8101,8102,8103
查看注册中心:http://localhost:8001/register/,http://localhost:8002/register/,http://localhost:8003/register/。此时服务出现在三个注册中心里面。
此时,Provider将三个服务地址注册到了三个注册中心。接下来测试服务消费者。
五、服务消费者
1、第一步同样是修改application.yml配置:
server: port: 8201 spring: application: name: demo-service-consumer eureka: instance: lease-renewal-interval-in-seconds: 10 lease-expiration-duration-in-seconds: 20 client: register-with-eureka: true fetch-registry: true instance-info-replication-interval-seconds: 30 registry-fetch-interval-seconds: 10 serviceUrl: defaultZone: http://peer1:8001/register/eureka/,http://peer2:8002/register/eureka/,http://peer3:8003/register/eureka/
调用接口服务消费者接口地址:http://localhost:8201/hello/java,多刷新几次。
我们可以看到Consumer控制台已经打印出服务提供者的地址了。很明显得可以看出负载均衡、服务集群都已经实现。并且Ribbon默认采用的负载均衡机制是轮询。
五、总结
现在看起来,是不是微服务架构很简单,并没有那么神秘。至此,我们已经能够搭建一个高可用的微服务架构,虽然这个微服务架构比较简单,但是已经适用于很多场景了。接下来小编还会和大家继续探讨Eureka的高级应用。