代碼地址:代碼地址
一:Feign的介紹
Feign 是一個聲明式的僞RPC的REST客戶端,它用了基於接口的註解方式,很方便的客戶端配置。Spring Cloud 給 Feign 添加了支持Spring MVC註解,並整合Ribbon及Eureka進行支持負載均衡。它讓微服務之間的調用變得更簡單了。
二:Feign的使用
接着之前關於Eureka+Ribbon+Hystrix的實例(Hystrix使用博文)來看,我們之前在消費者服務中調用生產服務者用的一直是Ribbon中的調用方式,代碼如下:
@HystrixCommand(commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000"),
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "10"),
@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "10000")
})
@GetMapping("/getAllProduct/{id}")
public String getAllProduct(@PathVariable int id){
//使用Ribbon請求第一種方式: 我們把地址換成服務id即可
String uri="http://EUREKA-SERVICE.PRODUCER/getProducts";
String vos = restTemplate.getForObject(uri, String.class);
return vos;
}
我們把調用的地址直接寫在代碼裏了,雖然地址裏沒有出現ip地址而是一個服務id,但是後面還是出現了類似路徑的內容。
String uri="http://EUREKA-SERVICE.PRODUCER/getProducts";
不能說這樣不好,只能說這樣不夠優雅,爲了所謂的優雅(哈哈)就需要使用Fegin啦,它可以更優雅的調用服務。
1)在消費者服務pom.xml中引入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2)在啓動類上添加註解: @EnableFeignClients
3)我們試想一下,要調用一個接口我們需要知道:地址,調用方式,參數,返回結果這四個內容。因爲Fegin基於註解接口實現的,
我們先定義一個接口:接口中定義一個方法,這個方法告訴feign上面四個內容。注意這個地址的配置:@FeignClient配置的服務id,
裏面方法的配置就參考生產者服務中的寫法,地址以及請求參數的配置,但是注意如果生產者服務的controller類上也有地址也要在這裏寫上。
@FeignClient("EUREKA-SERVICE.PRODUCER")
public interface ProductFeginInterface {
@GetMapping("/getProducts")
public String getAllProducts();
}
這樣就會從Eureka中拉取服務進行調用。
4)調用方式:
直接在controller中引入定義的接口並調用,就像調用本地方法一樣。
@Autowired
ProductFeginInterface productFeginInterface;
@GetMapping("/getFeign")
public String getAllproduct(){
return productFeginInterface.getAllProducts();
}
測試也是可以成功的:
而且速度也不慢。
三:Feign中使用服務降級和熔斷
上面我們新定義的方法來調用生產服務者,但是這樣的話,我們之前的服務降級和熔斷就不會起作用了。在Feign中使用這些就需要另外一些配置了。
1)Feign中的Ribbon有個默認超時時長,默認1s我們可以配置一下:
#使用Feign之後ribbon的超時時長配置
ribbon:
ConnectionTimeOut: 500 #ribbon在500毫秒內沒有建立連接就超時
ReadTimeOut: 2000 #ribbon在1s內沒有響應就超時
2)hystrix在feign中默認是關閉,我們需要開啓這個功能:
#使用feign之後開啓hystrix功能
feign:
hystrix:
enabled: true
3)配置熔斷類。沒錯在feign中熔斷是配置在類中的。
上面定義接口用到的註解@FeignClient有一個屬性fallback,屬性值是一個實現了當前接口的類,這個類就是我們服務熔斷時調用的類。
這個實現類還要交給spring管理。
@FeignClient(value = "EUREKA-SERVICE.PRODUCER",fallback = ProductFeginFallbackImpl.class)
public interface ProductFeginInterface {
@GetMapping("/getProducts")
public String getAllProducts();
}
@Component
public class ProductFeginFallbackImpl implements ProductFeginInterface {
public String getAllProducts() {
return "Feign的服務過忙,請稍後重試。";
}
}
4)測試
我們把生產服務停掉之後訪問可以看到服務降級了。
注意這個時候我們之前hystrix中配置的服務降級超時時長還是有效的。
#Hystrix的超時時間
hystrix:
command:
default:
execution:
isolation :
thread :
timeoutInMilliseconds: 3000
服務的熔斷測試我們在生產服務中增加如下代碼:
@GetMapping("/getProducts/{id}")
public String getAllProduct(@PathVariable Long id){
if (id%2==0){
throw new RuntimeException();
}
return productService.getAllProduct().toString();
}
消費者服務中增加如下代碼:
@GetMapping("/getFeign/{id}")
public String getAllproduct(@PathVariable Long id){
return productFeginInterface.getAllProducts(id);
}
我們連續訪問http://localhost:8012/getFeign/2一定次數,快速返回都是服務降級的內容。然後我們快速去訪問:http://localhost:8012/getFeign/1,也會快速返回服務降級的內容,只是過幾秒就會恢復正常結果。服務熔斷即驗證。