暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

OpenFeign集成总结+生产环境使用规范

帅哥趣谈 2021-08-31
1133

前面一期咱们讲解了gateway的集成实战,同时也讲解了微服务集成gateway的重要性,就是统一外部对微服务集群的调用,做统一管理,比如限流,权限校验,日志管理等。这期咱们来学习下web服务调用工具OpenFeign的集成实战。

OpenFeign基础篇

OpenFeign是什么,能干啥

  • 首先带大家看看官网的解释

Feign是声明性的web服务客户端。它使编写web服务客户端更加容易。要使用Feign,请创建一个接口并对其进行注释。它具有可插入的注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud添加了对Spring MVC注释的支持,并支持使用Spring Web中默认使用的同一HttpMessageConverters。Spring Cloud集成了Ribbon和Eureka以在使用Feign时提供负载平衡的http客户端。

  • 白话演绎一下 

1、由于Feign停更,SpringCloud使用Openfeign来替代Feign,在Feign的基础上做了升级和加强 

2、web服务调用的client端 

3、在Feign的基础上添加对SpringMVC和HttpMessageConverters的支持

OpenFeign和Feign的对比

FeignOpenFeign
Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端。Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务OpenFeign是Spring Cloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

<dependency>    

        <groupId>org.springframework.cloud</groupId>    

        <artifactId>spring-cloud-starter-feign</artifactId> 

</dependency>

<dependency>    

        <groupId>org.springframework.cloud</groupId>    

        <artifactId>spring-cloud-starter-openfeign</artifactId> 

</dependency>

集成实战
项目实战
  • 新建module,命名cloud-consumer-openfeign-order9090,Idea怎么新建module过程省略。

  • 修改pom文件,添加OpenFeign的依赖

     <!--openFeign-->
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    • 修改yml配置文件,添加OpenFeign的配置,比如定义超时时间,日志级别等,如果不做这些设置,那就只要基础配置即可,比如注册中心、服务端口等

      server:
      port: 9090
      spring:
      application:
      name: cloud-order-service
      zipkin:
      base-url: http://localhost:9411
      sleuth:
      sampler:
      probaility: 1
      eureka:
      client:
      service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
      register-with-eureka: true
      fetch-registry: true
      instance:
      instance-id: order8080
      prefer-ip-address: true
      • 启动类Application9090修改,主要是使用@EnableFeignClient注解,开启OpenFeign

        @SpringBootApplication
        @EnableEurekaClient
        @EnableFeignClients
        public class Application9090 {
        public static void main(String[] args) {
        SpringApplication.run(Application9090.class,args);
        }
        }
        • 业务类的修改,这里也是使用OpenFeign的重要环节。与Ribbon+RESTfulTemplate的最大区别是,采用OpenFeign注解+面向接口编程。在Service层集成OpenFeign注解,这个接口跟服务提供方的Service接口一样,但是多了@RequestMapping的注解,配置服务生产者的名称,SpringMVC注解中使用服务的URL地址。注意:@FeignClient(“CLOUD-PAYMENT-SERVICE”)是注册中心的服务名称,要一一对应

          @Component
          @FeignClient("CLOUD-PAYMENT-SERVICE")
          public interface PaymentFeignService {
          @GetMapping("/payment/getPayment/{id}")
          public MsgResponseBody getById(@PathVariable("id") Long id);
          }

          • Controller中模拟外部请求,使用上跟普通Controller写法一样,这样就完成了OpenFeign的引用

            @RestController
            @RequestMapping("/consumer")
            public class OpenFeignConsumerController {
            @Resource
            private PaymentFeignService paymentFeignService;


            @GetMapping("/getPayment/{id}")
            public MsgResponseBody getPaymet(@PathVariable("id") Long id){
            return paymentFeignService.getById(id);
            }
            }

            对比下Ribbon+RESTTemplate方式

            • 添加RESTTemplate模板配置,要在RestTemplate上添加@LoadBalance注解,实现客户端负载均衡

              @Configuration
              public class ApplicationConfig {
              @Bean
              @LoadBalanced
              public RestTemplate getRestTemplate(){
              return new RestTemplate();
                  }
              }
              • 在Controller中模拟请求,请求地址,同样是注册中心对应的服务名称,这里是用了gateway

                @RestController
                @RequestMapping("/consumer")
                public class ConsumerCtrol {
                private static String PAYMENTURL = "http://CLOUD-GATEWAY";
                @Resource
                    private RestTemplate restTemplate;
                @GetMapping("/getPayment/{id}")
                public MsgResponseBody getPaymet(@PathVariable("id") Long id){
                System.out.println("adada");
                return restTemplate.getForObject(PAYMENTURL+"/payment/getPayment/"+id+"?userName=123", MsgResponseBody.class);
                }
                }

                编码规范

                • 在我带团队的时候,一般的使用规范是,服务调用要单独抽象成一个工程,比如cloud-service-client为父工程,里面构建多个module,每个module就是微服务的调用实现,比如cloud-service-payment-client就是微服务cloud-payment-serviced的Client端调用。这样在业务侧整合的时候就可以根据实际情况引入相应jar包即可。

                • 我还见过有的团队是把所有的Client调用抽象成一个common工程,供业务集成方调用,这样做有点臃肿就是引用了很多不需要调用的模块,没有实现按需引用。

                • 上面两种方案,各有利弊,第一个按需引入很多包,第二个一起引入有冗余包。不过还是推荐使用第一个。还有就是省略这层抽象,在业务侧冗余写,不推荐这么用。


                总结

                • 通过两种方式的对比能够很明显看到使用上的差别,一个注重restful方式的HTTP请求调用,一个深度集成SpringMVC注解,使服务间调用更像面向接口的调用,感觉就像在本地调用一样。

                • 推荐使用OpenFeign,这样编程代码更加简洁

                • 大家可以一起谈论个问题,现在的框架封装越来越抽象,很多技术细节都屏蔽了,对未来的程序员真的好吗?欢迎大家在留言区留言讨论。


                --END--

                ↑ ↑ ↑点击上方 名片,关注 帅哥趣谈

                回复 资料

                获取T级Java技术资料

                shishuai860505),拉大家进群,一起交流学习

                认真传播技术,真诚结交朋友


                文章转载自帅哥趣谈,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                评论