
前面一期咱们讲解了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的对比
| Feign | OpenFeign |
|---|---|
| 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: 9090spring:application:name: cloud-order-servicezipkin:base-url: http://localhost:9411sleuth:sampler:probaility: 1eureka:client:service-url:defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/register-with-eureka: truefetch-registry: trueinstance:instance-id: order8080prefer-ip-address: true
启动类Application9090修改,主要是使用@EnableFeignClient注解,开启OpenFeign
@SpringBootApplication@EnableEurekaClient@EnableFeignClientspublic 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 {@Resourceprivate PaymentFeignService paymentFeignService;@GetMapping("/getPayment/{id}")public MsgResponseBody getPaymet(@PathVariable("id") Long id){return paymentFeignService.getById(id);}}
对比下Ribbon+RESTTemplate方式
添加RESTTemplate模板配置,要在RestTemplate上添加@LoadBalance注解,实现客户端负载均衡
@Configurationpublic class ApplicationConfig {@Bean@LoadBalancedpublic RestTemplate getRestTemplate(){return new RestTemplate();}}
在Controller中模拟请求,请求地址,同样是注册中心对应的服务名称,这里是用了gateway
@RestController@RequestMapping("/consumer")public class ConsumerCtrol {private static String PAYMENTURL = "http://CLOUD-GATEWAY";@Resourceprivate 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,这样编程代码更加简洁
大家可以一起谈论个问题,现在的框架封装越来越抽象,很多技术细节都屏蔽了,对未来的程序员真的好吗?欢迎大家在留言区留言讨论。
↑ ↑ ↑点击上方 名片,关注 帅哥趣谈
回复 “资料”
获取T级Java技术资料

(shishuai860505),拉大家进群,一起交流学习
认真传播技术,真诚结交朋友




