在SpringCloud中使用Feign進行服務的訪問
之前已經說過了SpringCloud作為“分布式微服務”的解決方案時的大概原理和方法了。就是一個個web應用之間的訪問,之前的訪問方式有兩種:
- 使用RestTemplate這個封裝好的類,使用ip+端口+服務地址進行訪問,這是最簡單的訪問方式了
@GetMapping("demo1/consumer/hello/{id}")
public String hello(@PathVariable("id") String id){
//遠程調用provider中的接口
return restTemplate.getForObject("http://localhost:8001/demo1/provider/hello/"+id,String.class);
}
- 使用Ribbon進行訪問負載均衡,也就是將“提供者”注冊到注冊中心,然后“消費者”使用微服務名進行訪問
@GetMapping("demo3/consumer/hello/{id}")
public String hello(@PathVariable("id") String id){
//遠程調用provider中的接口
return restTemplate.getForObject("http://demo3-ribbon-provider/demo3/provider/hello/"+id,String.class);
}
但是呢?這么訪問還是很麻煩,使用restTemplate訪問時,要對參數進行拼接。那么有沒有更好的方法呢?
而且,如果我們想和RPC框架一樣(比如Dubbo等),使用本地接口就可以訪問呢?那么我們就要引入Feign
1. 創建一個服務訪問的接口
既然我們想像在本地訪問一樣來調用遠程“微服務”接口,當然,將遠程代碼寫在本項目中是不可能的,那么就創建一個接口來訪問
- 創建一個新的項目 demo4-feign-interface
其實你創建這個項目就是為了讓消費者微服務進行依賴的,當然你可以直接在你的消費者項目中創建這個接口,但是並不利於管理,所以就新創建了一個項目,專門用來寫feign的接口
- pom.xml(導入Feign客戶端的依賴)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
- 然后編寫接口的Service類
package cn.lyn4ever.provider;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* 這個注解表明這是一個Feign的客戶端,
* 其中的value屬性就是目標微服務的服務名
*/
@FeignClient(value = "demo3-ribbon-provider")
public interface ProviderService {
/**
* 這個其實是provider提供者中的方法
*
* @param id
* @return
*/
@GetMapping("demo3/provider/hello/{id}")
public String hello(@PathVariable("id") Integer id);
}
主要看一下上邊的FeignClient注解中的value值,就是目標微服務中的服務名
這個hello()方法以及注解中的內容,全部都是項目demo3-ribbon-provider中的
- 然后,使用maven的命令,clean 然后install到本地倉庫中以便於其他的項目進行調用
- 這個應用只是做為一個消費者的依賴,所以並不需要啟動類
2.創建一個新的項目,使用Feign進行訪問
- 創建新的使用Feign的消費者項目,將之前的demo3-consumer復制一份,然后修改如下:
- pom.xml添加feign的依賴和我們之前創建的demo4-feign-interface
<!--之前的依賴省略,請查看源碼-->
<!--feign的依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!--之前創建的feign接口項目-->
<dependency>
<groupId>cn.lyn4ever</groupId>
<artifactId>demo4-feign-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
- application.yml 不用修改,還是將之前的配置文件復制過來
- 在啟動類上添加注解,聲明Feign的調用包名
@EnableFeignClients(basePackages= {"cn.lyn4ever.provider"})
- 接下來就是修改我們的controller類,可以使用本地接口進行訪問了
@RestController
public class HelloConsumerController {
@Autowired
private ProviderService providerService;
@GetMapping("demo4/consumer/hello/{id}")
public String hello(@PathVariable("id") Integer id){
//直接使用本地的接口就可以訪問了
return providerService.hello(id);
}
}
這們,啟動Eureka集群、三個provicder的服務提供者、剛才創建的這個服務消費者,然后使用瀏覽器進行訪問
3.使用Feign進行訪問有什么好處及其原理?
- 使用FeignClient訪問時,可以不用再使用ip+port或者使用微服務名進行訪問。可以直接在Autowired后,在本地調用方法
- 其實就是Feign在本地生成了動態代理,可以直接使用Autowired調用。其本質還是使用Ribbon進行負載均衡訪問
- Feign中內置了Ribbon進行負載均衡,所以也同樣可以像Ribbon一樣進行自定義負載均衡算法
更多關於SpringCloud的學習筆記以及代碼地址,關注微信公眾號“小魚與Java”回復“SpringCloud”獲取