spring cloud(三)Eureka高可用性+Feign声明式Rest客户端

老子叫甜甜 提交于 2019-11-25 19:12:26

spring cloud(三)Eureka高可用性+Feign声明式Rest客户端

码农成神关注

0.2472018.12.03 22:41:17字数 1,570阅读 347

目录

一、 配置Eureka高可用性介绍

Eureka服务器没有后端存储,但是注册表中的服务实例必须发送心跳包以保持注册更新,因此可以在内存中完成。Eureka客户端还具有服务注册表缓存,当客户端获取注册表中的服务实例时,会从自己的缓存中获取,客户端的缓存会定时更新,所以当Eureka服务挂了之后,并不会导致客户端找不到需要请求的服务实例。但是当Eureka服务器挂掉之后,原来注册表中的服务发生故障或者更新,这时就会出现危险的情况。我们怎么保证Eureka服务器的高可用性呢?

Eureka服务器同时也是一个客户端,默认配置下,需要提供一个serviceUrl来同步注册信息,如果不提供这个配置,就会在日志文件中出现大量的错我提示。我们之前通过再Eureka服务器(eureka_server项目)配置eureka.client.registerWithEureka=false,和eureka.client.fetchRegistry=false,关闭了Eureka服务器之间的同步消息,所以上文中介绍的Eureka是以独立模式运行的。为了提高可用性我们需要配置多个Eureka服务器,并让它们之间互相同步注册信息,当其中一个挂掉之后,Eureka客户端会自动切换到另外的Eureka服务器。

二、配置Eureka并行模式(Peer Awareness)

1. 修改之间的Eureka服务eureka_server的application.yml

通过spring boot的profiles机制,定义多个profiles,多个profiles用---分割。当运行服务时可以通过在命令行传参的方式指定使用哪个具体的profiles作为配置。这样我们就可以使用同一个jar文件运行多个不同的服务。下面看application.yml的示例。

 spring:   application:     name: eureka-server --- server:   port: 8761 eureka:   client:     service-url:       defaultZone: http://peer2:8762/eureka/   instance:     hostname: peer1 spring:   profiles: peer1 --- server:   port: 8762 eureka:   client:     fetch-registry: false     register-with-eureka: false     service-url:       defaultZone: http://peer1:8761/eureka/   instance:     hostname: peer2 spring:   profiles: peer2 

当我们指定profiles为peer1时,我们使用8761运行服务,并将serviceUrl设为peer2,当profiles为peer2时我们使用8762端口运行服务,并接serviceUrl设为peer1。这里需要注意的是,peer1,peer2均为hostname,因为服务都跑在自己的电脑上,所以我在hosts文件里做了如下的映射

 127.0.0.1 peer1 peer2 

2. 修改客户端的application.yml

分别在consume_server和product_server项目的application.yml中,修改serviceUrl增加新的Eureka服务器的地址,示例如下:

 eureka:   client:     service-url:       defaultZone: http://peer1:8761/eureka/,http://peer2:8762/eureka/ 

3. 运行多个Eureka服务

方式一: 通过maven打包生成jar之后运行命令java -jar eureka_server-1.0-SNAPSHOT.jar --spring.profiles.active=peer1 && java -jar eureka_server-1.0-SNAPSHOT.jar --spring.profiles.active=peer2
方式二: 我本人在使用idea作为开发工具,在开发环境下可以通过如下步骤配置多个服务启动器

  1. 点击EditConfigutations

     

    EditConfigutations

  2. 配置多个SpringBoot启动类

     

    启动类1

     

    启动类2

4. 运行consume_server和product_server并验证是否配置成功

peer1服务

 

peer2服务

访问成功

 

到此多实例Eureka服务器完成。一切正常。

5. 关掉peer1的服务测试是否一切运行正常

关掉peer1服务

 

peer1服务状态

 

peer2服务状态

 

服务正常访问

 

我们可以看到其中一个Eureka挂掉之后,另一个Eureka服务器可以继续为Eureka客户端提供服务。

6.关掉所有Eureka服务器测试Eureka客户端是否可以通过客户端缓存继续访问原来的服务

关掉所有Eureka服务

 

依旧服务正常

 

Eureka客户端报错

 

我们可以看到,即使关掉全部的Eureka服务器,Eureka客户端依旧可以依靠自身缓存的注册表继续提供正确的服务。当然如果客户端依赖的服务也停止了,客户端缓存的注册表此时是不会更新的,这时服务就会出错。

三、配置Feign声明式Rest访问

还记得上篇文章中我们为了访问服务拼接字符串的操作吗?这时如果涉及的参数非常多手动拼接字符串就会变的异常繁琐。接下来介绍Feign,它可以让我们从拼接字符串的操作中解放出来具体怎么操作,接着看吧。

1. 在cosume_server项目的pom文件中新增feign的依赖

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

2. 在启动类新增@ EnableFeignClients注解

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

3. 配置feignclient,并将原先的拼接字符串的请求方式替换为Feign的形式

先看代码:

 package com.yshmsoft.controller;  import com.yshmsoft.entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController;  @RestController public class UserController {      @Autowired     ProductServerClient productServerClient;      @FeignClient("product-server")     static interface ProductServerClient {         @GetMapping("/{id}")         public User findUserById(@PathVariable("id") Long id);     }      @GetMapping("/user/{id}")     User getUserById(@PathVariable Long id) {         User user = productServerClient.findUserById(id);         return  user;     }  } 

为了简单起见我以静态内部类的形式定义了Feign客户端ProductServerClient。接下来我一步一步说这些代码都干了什么。

  • @FeignClient注解用来声明此接口为Feign客户端。
  • @FeignClient传入的值为vipaddress也就是我们定义服务的时候提供的spring.application.name=product-server这个地方定义的应用名。
  • @GetMapping spring cloud为我们提供了spring mvc式的feign注解,这个@GetMapping意思就是发送一个get请求,然后请求路径为/{id},这个id就是注解标注的方法里面由@PathVariable("id")标注的参数。
  • 以上都明白之后我们用@Autowired将@FeignClient标注的接口注入到我们的UserController中然后调用productServerClient.findUserById(id)方法,发送请求取得User对象。
    综上当调用了findUserById方法实际上就是发送了一个get请求hostname和port,通过@FeignClient("product-server")传入的值去调用Eureka的client获取。请求的路径为@GetMapping(/{id})注解中的参数,而路径变量id由实际调用findUserById方法时由该方法的参数id去替换。注意@PathVariable("id")中的id在这里不能省略,省略会报错。

这篇文章我们介绍了如何配置Eureka高可用,如何配置Feign声明式Rest客户端简化请求。接下来,我们需要更详细的了解一下Eureka的配置和Feign的配置,敬请期待。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!