feign是什么 ?
在微服架构下,一个大型业务服务会被拆分程多个微服务,各个服务之间相互通信才能完成整体的功能。比如说商城系统一个订单的完成,是需要商品系统、订单系统、库存系统、支付系统共同完成的,对于客户端来说它是无法感知的,可能只是点了一个按钮,发送了一个请求,但是在微服务系统内部几个相关联的微服务相互调用,才能完成这个请求。而Feign就是专门负责服务和服务之间相互通讯,相互调用的框架。如下图所示:
Feign 是Spring Cloud组件中一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡。Feign工作时,会去注册中心(nacos)中去寻找服务,然后在调用服务。Feign的使用方式非常简单,使用Feign的注解 定义接口,调用接口,就可以调用服务注册中心的服务。
除了feign之外,你也可以使用dubbo 这样的RPC框架完成服务和服务之间的调用,feign和dubbo 都是完成类似的功能,只是实现的方式不一样。
openFeign是什么?
OpenFeign目前是Spring Cloud 二级子项目,平时说的Feign指的是Netflix下的Feign,现在我们学习的是OpenFeign,是Spring官网提供的标准框架。Feign是对RestTemplate和ribbon的封装,用接口的方式实现远程调用,是面向接口编程的体现,不用每次都去写RestTemplate。Openfeign 是SpringCloud对feign进一步封装,在Feign的基础上支持了Spring MVC的注解,如@RequesMapping等等,是SpringCloud中的第二代负载均衡客户端,使用Openfeign可以实现,服务发现,负载均衡,服务调用等功能。
如何集成OpenFeign?
例如:在zeus(宙斯)微服务中,调用远程的apollo(阿波罗)微服中的sayHell() 接口
第一步在zeus模块下,添加openfeign依赖
<!-- 微服务:Feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
第二步:在zeus模块启动类上,添加@EnableFeignCliens 注解
该注解可以启动Feign工作,basePackages 指定扫描Feign接口所在目录,
在这个目录下所有带有 @FeignClient注解的接口 将通过动态代理技术产生代理对象,注入到容器中。
第三步:在zeus工程下,建Feign包,在feign包下建service包。所有feign接口都定义在service包下,如下图:
第四步:编写Feign接口
使用@FeignClient 注解定义该接口 ,FeignClient 注解要传入“被调用的微服务名称”,也就是spring.application.name 指定的名称,因为要调用apollo服务的sayHello接口,所以@FeignClient 要传入 apollo 微服务的服务名称 “olympics-apollo”。
OpenFeign 比Feign高级的地方在于支持SpringMVC中的注解,这里面的@GetMapping(“/say”) 指的是通过GET方式调用apollo服务的"/say" 指向的接口,我门建议保持跟被调用接口一致的形式即可
package org.lanqiao.zeus.feign.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
/**
* 专门用来调用“olympics-apollo”微服务的Feign客户端服务
*/
@FeignClient(name = "olympics-apollo")
public interface ApolloFeignService {
/**
* 调用"olympics-apollo" 微服务的"/say"接口
* 此方法参数保持和被调用接口一致
* @return
*/
@GetMapping("/say")
String sayHello();
}
第五步:使用Feign接口,实现远程调用
@Autowired
ApolloFeignService apolloFeignService;
/**
* 测试案例二(测试zeus微服务和apollo微服务之间通过openFeign通讯)
* @return
*/
@GetMapping("/feignSay")
public String feignSayHello(){
//通过Feign客户端,调用apollo微服中的sayHello接口
String message = apolloFeignService.sayHello();
//把返回结果输出到后台日志中
logger.info("通过Feign调用从apollo微服务返回的消息是:[{}]",message);
//把Feign调用结果加工后返回给网关,通过网关输出到浏览器或其他客户端
return "Feign say:"+message;
}