基于Spring Cloud的微服务构建学习-3 服务治理-Spring Cloud Eureka之高可用注册中心

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Spring Cloud的微服务构建学习-3 服务治理-Spring Cloud Eureka之高可用注册中心相关的知识,希望对你有一定的参考价值。

什么叫高可用

    高可用一般指服务的冗余,一个服务挂了,可以自动切换到另一个服务上,不会影响到客户体验。

高可用注册中心

    在微服务架构这样的分布式环境中,我们需要充分考虑发生故障的情况,所以在生产环境中必须对各个组件进行高可用部署,对于微服务如此,对于服务中心也一样。

    Eureka Server的设计一开始就考虑了高可用问题,在Eureka的服务治理设计中,所有节点既是服务提供方,也是服务消费方,服务注册中心也不例外。在前一篇随笔中用到过这样的配置:

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

现在回顾一下上一篇中提到的这两个属性的作用:

  • eureka.client.register-with-eureka=false设置为不将自己注册到服务注册中心(默认是true)
  • eureka.client.fetch-registry=false设置为不检索服务(默认是true,在单节点服务注册中心的情况下,服务注册中心并不需要检索自己的服务)

    Eureka server的高可用实际上就是将自己作为服务向其他服务注册中心注册自己,这样就可以形成一组互相注册的服务注册中心,以实现服务清单的互相同步,达到高可用的效果。

技术分享

使用Spring Cloud Eureka实现高可用服务注册中心

    在前一篇的服务注册中心基础上进行扩展,构建一个双节点的服务注册中心集群。

  1. 创建application-peer1.properties,作为peer1服务中心的配置,并将serviceUrl(要注册到服务注册中心的地址)指向peer2

spring.application.name=eureka-server
server.port=1111

#也可以省去下面对hostname的配置,在defaultZone处直接使用IP地址,但是需要配置eureka.instance.prefer-ip-address=true
eureka.instance.hostname=peer1
#eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
eureka.client.serviceUrl.defaultZone=http://peer2:1112/eureka/

    2.创建application-peer2.properties,作为peer2服务中心的配置,并将serviceUrl(要注册到服务注册中心的地址)指向peer1

spring.application.name=eureka-server
server.port=1112

#也可以省去下面对hostname的配置,在defaultZone处直接使用IP地址

eureka.instance.hostname=peer2
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/

    3.在/etc/hosts文件中添加对peer1和peer2的转换,让上面配置的host形式的serviceUrl能在本地正确访问到;Windows系统路径为c:\\windows\\system32\\drivers\\etc\\hosts。

127.0.0.1 peer1
127.0.0.1 peer2

    4.在项目的根目录下使用mvn clean package -Dmaven.skip.test=true对项目进行打包,然后使用java -jar eureka-server-1.0.0.jar --spring.profiles.active=peer1/peer2命令分别启动peer1和peer2。

此时访问peer1的注册中心:http:localhost:1111/

技术分享

访问http://localhost:1112/

技术分享

在截图中我们可以看到,peer1中已经有了peer2的分片,并已经分别注册到peer2和peer1中,并且这些节点都在可用分片(available-replicase)中。

如果我们关闭了其中的peer1,则peer1节点变为了不可用分片:

技术分享

    5.修改服务提供方,将其注册到Eureka Server集群中。

spring.application.name=hello-service
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka,http://peer2:1112/eureka

然后启动该服务,访问http://localhost:1111/http://localhost:1112/

技术分享

尝试关闭peer1:

技术分享

继续访问localhost:8080/hello

技术分享

在图中可以看到,peer1已经被关闭,但是hello-service服务仍然可以被访问到,这就实现了服务注册中心的高可用行。

技术分享

创建服务消费者

    接下来创建一个服务消费者,主要完成两个目标:发现服务,消费服务。其中服务发现的任务由Eureka客户端完成,服务消费由Ribbon完成。

    Ribbon是一个基于HTTP和TCP的客户端负载均衡,它可以在通过客户端中配置的ribbonServerList服务端列表去轮询访问以达到均衡负载的作用。当Ribbon与Eureka联合使用时,则可以免去ribbonServerList的配置,自动由Eureka来完成。我们只需要知道Ribbon实现了一套对服务实例的选择策略。

    1.使用java -jar命令启动两个不同端口的hello-service服务。

技术分享

    2.创建Spring Boot项目,取名为:ribbon-consumer,并在pom中引入如下依赖:

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
</dependency>

 

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

 

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>

 

<dependencyManagement>
     <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-dependencies</artifactId>
             <version>Camden.SR7</version>
             <type>pom</type>
             <scope>import</scope>
         </dependency>
     </dependencies>
</dependencyManagement>

    3.在应用主类中添加@EnableDiscoveryClient注解,将其注册为Eureka客户端,使其拥有服务发现的能力。同时,在该主类中创建RestTemplate的Spring Bean实例,并通过@LoadBalanced注解开启客户端负载均衡:

@EnableDiscoveryClient
@SpringBootApplication

public class RibbonConsumerApplication {

    @Bean
     @LoadBalanced
     RestTemplate restTemplate(){
         return new RestTemplate();
     }
     public static void main(String[] args) {
         SpringApplication.run(RibbonConsumerApplication.class, args);
     }
}

    4.创建ConsumerController类,并实现/ribbon-consumer接口。通过调用RestTemplate来实现对Hello-service服务提供的/hello接口进行调用 。

@RestController
public class ConsumerController {
     @Autowired
     private RestTemplate restTemplate;
    
     @RequestMapping(value="/ribbon-consumer",method=RequestMethod.GET)
     public String helloConsumer() {
         return restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody();
     }
}

//在url中使用的是服务名,而不是一个具体地址,在服务治理框架中,这是一个非常重要的特性。比如:因为服务注册中心维护着很多来自不同主机拥有相同服务名的服务实例,当我们需要调用

//服务时就无需知道服务的具体地址了,从服务名到地址的映射都已经交给服务注册中心完成(在这期间也可以完成很多其他任务)。

    5.修改application.properties

spring.application.name=ribbon-consumer
server.port=9000
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

    6.启动ribbon-consumer应用后,访问http://localhost:1111

技术分享

验证ribbon负载均衡

    在浏览器输入http://localhost:9000/ribbon-consumer多次访问ribbon-consumer,分别查看hello-service的控制台信息:

可以发现他们会交替的打印出:/hello , host:DESKTOP-48KOCS1, service_id:hello-service。证明ribbon已生效,并且采用轮询的方式实现负载均衡。

 

 

参考文献:

        spring cloud 项目实战

以上是关于基于Spring Cloud的微服务构建学习-3 服务治理-Spring Cloud Eureka之高可用注册中心的主要内容,如果未能解决你的问题,请参考以下文章

基于Spring Cloud的微服务构建学习-3 服务治理-Spring Cloud Eureka之高可用注册中心

基于Spring Cloud的微服务构建学习-2 Spring Boot

基于Spring cloud gateway定制的微服务网关

基于 Spring Cloud + Vue.js完整的微服务架构实战

Spring Cloud构建微服务架构 消息驱动的微服务(消费分区)Dalston版

基于Spring Cloud 的微服务架构脚手架,满满的干货来啦~