OpenFeign
<h1>概述</h1>
<h2>Feign</h2>
<pre><code>Feign是Spring Cloud组件中的一个轻量级RESTful的HTTP服务客户端
Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。
Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务
Feign支持的注解和用法请参考官方文档:https://github.com/OpenFeign/feign
Feign本身不支持Spring MVC的注解,它有一套自己的注解</code></pre>
<h2>OpenFeign</h2>
<pre><code>OpenFeign是Spring Cloud 在Feign的基础上支持了Spring MVC的注解,如@RequesMapping等等。
OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,
并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。</code></pre>
<h1>环境安装</h1>
<h2>服务提供者和服务消费者都引入相关依赖</h2>
<pre><code><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency></code></pre>
<h2>确保服务提供者和服务消费者连接的是相同的eureka</h2>
<p><img src="https://www.showdoc.cc/server/api/common/visitfile/sign/9d1c55e394bbda716e4146bcc5e82fca?showdoc=.jpg" alt="" /></p>
<h1>场景预览</h1>
<h3>未使用OpenFeign:</h3>
<pre><code>@Autowired
private RestTemplate httpClientTemplate;
httpClientTemplate.postForObject("http://host:port");</code></pre>
<p><img src="https://www.showdoc.cc/server/api/common/visitfile/sign/943467f435fe1696a4e73547aabd65fa?showdoc=.jpg" alt="" /></p>
<h3>使用OpenFeign:</h3>
<pre><code>@Autowired
private GoodRPCService goodRPCService;
goodRPCService.findGoodNameById(7l);</code></pre>
<p><img src="https://www.showdoc.cc/server/api/common/visitfile/sign/290637a5b36de1f90dde980b5b98eb99?showdoc=.jpg" alt="" /></p>
<h3>通过对比可发现,如果未使用OpenFeign,比方使用RestTemplate:</h3>
<pre><code>无法做到高可用:服务消费者和服务提供者必须是一对一的关系,无法拓展多个服务提供者比如做负载均衡的需求
维护困难:服务调用者需要知道服务提供者的域名(ip地址)以及端口,如果服务提供者更改了域名或者端口,那么所有的服务消费者都需要更改调用的域名或者端口</code></pre>
<h1>快速入门</h1>
<h2>服务提供者</h2>
<h3>a.参照springmvc接口的写法,实际就是springmvc的接口,如下:</h3>
<pre><code>@RestController
@RequestMapping("/goodRPC")
public class GoodRPCServiceImpl{
@RequestMapping("/findGoodNameById/{id}")
@ResponseBody
public String findGoodNameById(@PathVariable Long id) {
return "";
}
}</code></pre>
<h3>b.启动该服务</h3>
<h2>服务消费者</h2>
<h3>a.springboot启动类打上注解</h3>
<pre><code>@EnableFeignClients(basePackages = "com.nisbos")
@EnableDiscoveryClient</code></pre>
<h3>b.定义调用接口</h3>
<h4>nisbos-feign-provider必须与服务提供者的application.yml文件中的spring:application:name相同</h4>
<h4>/goodRPC/findGoodNameById必须与服务提供者提供的springmvc签名相同</h4>
<pre><code>@FeignClient(contextId="goodRPCService",name = "nisbos-feign-provider")
public interface GoodRPCService {
@RequestMapping(value = "/goodRPC/findGoodNameById/{id}")
String findGoodNameById(@PathVariable("id") Long id);
}</code></pre>
<h3>c.调用</h3>
<pre><code>@Autowired
private GoodRPCService goodRPCService;
goodRPCService.findGoodNameById(7l);</code></pre>
<h2>项目中应用</h2>
<h5>项目开发中,提供者需要提供统一的返回对象给消费者,统一处理运行异常,业务异常等</h5>
<h5>不同微服务的中,提供者也需要提供不同的接口以及入参对象</h5>
<h5>所以可以参考项目nisbos-feign-provider,提供者和消费者都引用如下依赖</h5>
<h3>a.抽离出微服务的公共依赖</h3>
<pre><code> <dependency>
<groupId>com.nisbos</groupId>
<artifactId>nisbos-rpc-framework</artifactId>
</dependency></code></pre>
<h3>a.定义微服务自己提供的接口,vo类等,对外开放</h3>
<pre><code><dependency>
<groupId>com.nisbos</groupId>
<artifactId>nisbos-feign-provider-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency></code></pre>