• SpringCloud集成OpenFeign,轻松RPC


    前言

    Springcloud解决方案,实现微服务;是目前很多中小公司实现微服务的常见的解决方式;在每个微服务单元之间的RPC调用,在SpringCloud的解决方案中通过Web Restful实现也是最常见的场景,在Springcloud的整体解决方案中,官方推荐的是使用SpringCloud OpenFeign来实现此目的;有关这个话题很多技术论坛都有相关的文章进行介绍,在大多数的文章中,还没有与时俱进,SpringCloud的版本还停留在2019年推出的以地铁站为命名的一系列版本里,例如Hoxton.SRX等;2019版本已经过于旧了,其中的netifix的ribbon和hystrix都已经不进行维护了,今天咱们要给大家介绍的就是使用最新的SpringCloud2021系列的版本进行OpenFeign的集成,从而实现RPC。

    SpringCloud&SpringBoot

    以上的图是SpringCloud官网上的SpringCloud的release Map图; 最新的SpringCloud的版本是2021.0.X, 注意第二列,由于SpringCloud是基于SpingBoot框架而进行实现和定义接口的,所以需要严格的对应SpringCloud和SpringBoot的版本; 如上图所示, 我们的SpringBoot可以选择使用2.6.X系列或者2.7.X系列, 笔者建议先使用2.6.X系列

    SpringCloud OpenFeign

    上图是从SpringCloud官网的OpenFeign模块的主页摘录下来的; (https://spring.io/projects/spring-cloud-openfeign)

    如图中说示: OpenFeign是声明性REST客户端:Feign创建一个用JAX-RS或Spring MVC注释装饰的接口的动态实现REST RPC的实现。

    下图是SpringCloud OpenFeign的版本蓝图, 笔者建议使用3.1.X版本,笔者自己使用的是3.1.1版本

    SpringCloud OpenFeign工作流程

    Target(动态代理层),即为我们通过FeignClient实现RPC定义的接口层,此次技术使用了Java的动态代理技术和SpringBoot里的BeanProcessor的Bean生命周期管理的技术;

    Constract为合约层,在SpringCloud的WebMvc实现了WebMvcContract,为默认的合约,没有指定合约时即使用该合约; OpenFeign包里实现了Feign的标准合约,通常我们的项目开发里都是没有特别指定的,都是用的Mvc的合约,在FeignClient的RPC接口定义时,使用的annotation也都是MVC的annotation, 如:PostMapping, GetMapping

    MethondHandler是动态代理的具体实现方法,对应的就是去Target进行RPC的调用

    使用步骤

    引入OpenFeign包

    1. <dependency>
    2. <groupId>org.springframework.cloudgroupId>
    3. <artifactId>spring-cloud-starter-openfeignartifactId>
    4. dependency>
    5. <dependency>
    6. <groupId>org.springframework.cloudgroupId>
    7. <artifactId>spring-cloud-starter-loadbalancerartifactId>
    8. dependency>
    9. <dependency>
    10. <groupId>org.springframework.cloudgroupId>
    11. <artifactId>spring-cloud-loadbalancerartifactId>
    12. dependency>
    13. <dependency>
    14. <groupId>org.springframework.cloudgroupId>
    15. <artifactId>spring-cloud-starter-circuitbreaker-resilience4jartifactId>
    16. dependency>
    17. <dependency>
    18. <groupId>io.github.resilience4jgroupId>
    19. <artifactId>resilience4j-feignartifactId>
    20. <version>1.7.0version>
    21. dependency>

    启动类引入Feign支持

    1. @SpringBootApplication
    2. @EnableFeignClients
    3. public class Application {
    4. public static void main(String[] args) {
    5. SpringApplication.run(Application.class, args);
    6. }
    7. }

    在启动类里需要增加@EnableFeignClients注解,这样项目启动是,会有autoconfiguration机制自动的在Application为根包路径下去扫描所有的FeignClient,并产出流程步骤中所表示的动态代理层的Bean对象;

    定义客户端RPC接口

    在客户端定义接口,去调用服务提供方提供的WEB RESTFUL的服务;

    客户端只需要根据服务提供方提供的WEB API的标准,定义出访问的API,通过对客户端的接口访问,就会处理到动态代理层,动态代理层根据合约对接口进行WEB RESTFUL的封装,然后在methodHandler里通过HttpClient的方式去服务提供方进行WEB调用,从而完成RPC的实现;

    1. @FeignClient("stores")
    2. public interface StoreClient {
    3. @RequestMapping(method = RequestMethod.GET, value = "/stores")
    4. List getStores();
    5. @RequestMapping(method = RequestMethod.GET, value = "/stores")
    6. Page getStores(Pageable pageable);
    7. @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
    8. Store update(@PathVariable("storeId") Long storeId, Store store);
    9. @RequestMapping(method = RequestMethod.DELETE, value = "/stores/{storeId:\\d+}")
    10. void delete(@PathVariable Long storeId);
    11. }

    上面这些都是使用的MVC的合约,使用的annotation都是MVC的annotation; 下面的例子是使用Feign自己的标准annotation; 笔者建议使用这种方式更为标准

    1. // after Hystrix is removed from SpringCloud2021.0.1, the fallback is ineffective
    2. @FeignClient(name = "${codeman.service.name:codeman}", url = "${codeman.service.address:}", fallback = CodeManFallbackImpl.class)
    3. public interface CodeManFeign extends CodeManService {
    4. @RequestLine("GET /codeman/info/version")
    5. public String getVersion();
    6. @RequestLine("GET /codeman/info/author")
    7. public String getAuthor();
    8. @RequestLine("GET /codeman/info/request/{userid}") //对应请求方式和路径
    9. public String requestLine(@Param("userid") String userid);
    10. }

    调用RPC

    1. @Slf4j
    2. @Component("CodeManService")
    3. public class CodeManServiceImpl implements CodeManService {
    4. @Autowired
    5. CodeManFeign codeManFeign;
    6. @Override
    7. @CircuitBreaker(name = "default", fallbackMethod = "getVersionFallback")
    8. public String getVersion() {
    9. return codeManFeign.getVersion();
    10. }
    11. @Override
    12. @CircuitBreaker(name = "default", fallbackMethod = "getAuthorFallback")
    13. public String getAuthor() {
    14. return codeManFeign.getAuthor();
    15. }
    16. @Override
    17. @CircuitBreaker(name = "default", fallbackMethod = "requestLineFallback")
    18. public String requestLine(String userid) {
    19. return codeManFeign.requestLine(userid);
    20. }
    21. public String getVersionFallback(Throwable t) {
    22. log.info("================================= Exception(getVersion): {}", t.getMessage());
    23. return "N/A";
    24. }
    25. public String getAuthorFallback(Throwable t) {
    26. log.info("================================= Exception(getAuthor): {}", t.getMessage());
    27. return "SpringCloud";
    28. }
    29. public String requestLineFallback(String userid, Throwable t){
    30. log.info("================================= Exception(requestLine): {}", t.getMessage());
    31. return "Kill team‘s poison " + userid;
    32. }
    33. }


     

    结束语

    本文主要介绍的是在springcloud最新版本里使用OpenFeign实现RPC调用,作为完整的OpenFeign的RPC调用实现,还有更高级的一些话题,比如Fallback; LoadBalance; 和服务发现集成使用等高级用法,本文篇幅有限,在以后的相关文章会介绍这些OpenFeign使用的高级用法;敬请大家持续关注;

    谢谢大家持续关注,不要错过精彩内容。

  • 相关阅读:
    分发饼干(贪心算法+图解)
    科研教育「双目视觉技术」首选!维视MV-VS220双目立体视觉系统开发平台
    windows 安装多个独立微信,设置不同快捷键
    Rust 流程控制
    数学建模-最优包衣厚度终点判别法-三(Bayes判别分析法和梯度下降算法)
    【JS红宝书学习笔记】第6章 集合引用类型
    C语言 | 类型的基本归类
    后端关卡18 了解JDBC
    AIOS: LLM Agent Operating System
    15-55V输入自动升降压 光伏MPPT自动跟踪充电方案 大功率300瓦
  • 原文地址:https://blog.csdn.net/inthirties/article/details/126798773