当前位置:首页 > 技术分析 > 正文内容

SpringCloud集成OpenFeign,轻松RPC

ruisui885个月前 (02-03)技术分析30

前言

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包



    org.springframework.cloud
    spring-cloud-starter-openfeign



    org.springframework.cloud
    spring-cloud-starter-loadbalancer



    org.springframework.cloud
    spring-cloud-loadbalancer



    org.springframework.cloud
    spring-cloud-starter-circuitbreaker-resilience4j



    io.github.resilience4j
    resilience4j-feign
    1.7.0



?


启动类引入Feign支持


@SpringBootApplication
@EnableFeignClients
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}



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



定义客户端RPC接口


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


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


@FeignClient("stores")
public interface StoreClient {
    @RequestMapping(method = RequestMethod.GET, value = "/stores")
    List getStores();

    @RequestMapping(method = RequestMethod.GET, value = "/stores")
    Page getStores(Pageable pageable);

    @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
    Store update(@PathVariable("storeId") Long storeId, Store store);

    @RequestMapping(method = RequestMethod.DELETE, value = "/stores/{storeId:\\d+}")
    void delete(@PathVariable Long storeId);
}



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


// after Hystrix is removed from SpringCloud2021.0.1, the fallback is ineffective
@FeignClient(name = "${codeman.service.name:codeman}", url = "${codeman.service.address:}", fallback = CodeManFallbackImpl.class)
public interface CodeManFeign extends CodeManService {

    @RequestLine("GET /codeman/info/version")
    public String getVersion();

    @RequestLine("GET /codeman/info/author")
    public String getAuthor();

    @RequestLine("GET /codeman/info/request/{userid}")    //对应请求方式和路径
    public String requestLine(@Param("userid") String userid);
}



调用RPC


@Slf4j
@Component("CodeManService")
public class CodeManServiceImpl implements CodeManService {

    @Autowired
    CodeManFeign codeManFeign;

    @Override
    @CircuitBreaker(name = "default", fallbackMethod = "getVersionFallback")
    public String getVersion() {

        return codeManFeign.getVersion();
    }

    @Override
    @CircuitBreaker(name = "default", fallbackMethod = "getAuthorFallback")
    public String getAuthor() {
        return codeManFeign.getAuthor();
    }

    @Override
    @CircuitBreaker(name = "default", fallbackMethod = "requestLineFallback")
    public String requestLine(String userid) {
        return codeManFeign.requestLine(userid);
    }


    public String getVersionFallback(Throwable t) {
        log.info("=================================  Exception(getVersion): {}", t.getMessage());
        return "N/A";
    }

    public String getAuthorFallback(Throwable t) {
        log.info("=================================  Exception(getAuthor): {}", t.getMessage());
        return "SpringCloud";
    }

    public String requestLineFallback(String userid, Throwable t){
        log.info("=================================  Exception(requestLine): {}", t.getMessage());
        return "Kill team‘s poison " + userid;
    }
}





结束语


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


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

?

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/1195.html

标签: feign 使用
分享给朋友:

“SpringCloud集成OpenFeign,轻松RPC” 的相关文章

Ubuntu 24.10发行版登场:Linux 6.11内核、GNOME 47桌面环境

IT之家 10 月 11 日消息,Canonical 昨日发布新闻稿,正式推出代号为 Oracular Oriole 的 Ubuntu 24.10 发行版。新版在内核方面升级到最新 6.11 版本,并采用 GNOME 47 桌面环境。Ubuntu 24.10 发行版调整了内核策略,开始选择最新的上游...

基于gitlab的PR操作教程

基于gitlab的PR操作教程注:该教程主要基于git命令行操作,其他图形化工具也可完成以下所有操作步骤,顺手即可。推荐工具:Source Tree ,TortoiseGit参考:gitflow一 . 基于分支的PR操作1. 本地切换到master分支1. 拉取最新代码2. 基于master创建ho...

10分钟搞定gitlab-ci自动化部署

gitlab-ci 是持续集成工具/自动化部署工具,类似 jenkins。持续集成 是将代码集成到共享存储库并尽可能早地自动构建/测试每个更改的实践 - 通常一天几次。概述在编码完成时都会进行打包发布过程,如果每次都手动操作这一步骤就会浪费时间,效率低下。所以就有了持续集成。准备事项请提前安装以下软...

佳能 EOS R8 深度评测

佳能 EOS R8 的定位是入门级全画幅无反光镜可换镜头相机。尽管在产品阵容中处于这一位置,R8 仍然是一个强大的相机,配备了先进的 R6 II 同款成像传感器、快速处理器和令人难以置信的自动对焦系统,体积小、重量轻、价格低。这款相机是发烧友、旅行者、家庭以及任何想要全画幅传感器相机的人的绝佳选择。...

微信外H5跳转小程序——组件(vue项目)

场景有个H5(vue项目),需要实现点击商品item跳转到小程序,微信内和微信外都要支持,这里我们只介绍一下H5在微信外的跳转。如图所示,红框内是一个商品,就是点击这里,要跳转小程序:配置微信小程序云开发(云函数)1、开通云开发然后选择免费额度2、云开发权限设置找到权限设置,把这里的「未登录用户访问...

同步和异步的区别是什么,同步和异步的代码

同步和异步的区别在于程序执行操作时是否需要等待操作完成。同步操作意味着程序在执行一个操作时会一直等待操作完成才继续执行下一个操作,而异步操作则是指程序执行一个操作时,不会等待操作完成,而是立即返回,继续执行后面的操作。以下是同步和异步的代码示例:同步代码示例:console.log("sta...