Feign
集成工具
- 遠程呼叫:宣告式客戶端
- ribbon 負載均衡和重試
- hystrix 降級和熔斷
feign 宣告式客戶端介面
微服務應用中,ribbon 和 hystrix 總是同時出現,feign 整合了兩者,并提供了宣告式消費者客戶端
- 用 feign 代替 hystrix+ribbon

只需要宣告一個抽象介面,就可以通過介面做遠程呼叫,不需要再使用 RestTemplate 來呼叫
// 呼叫遠程的商品服務,獲取訂單的商品串列
// 通過注解,配置:
// 1. 呼叫哪個服務
// 2. 呼叫服務的哪個路徑
// 3. 向路徑提交什么引數資料
@FeignClient(name="item-service")//item-service指在eureka中注冊的服務名
public interface ItemClient {
@GetMapping("/{orderId}")
JsonResult<List<Item>> getItems(@PathVariable String orderId);//@PathVariable在這里是指向介面傳遞的引數
}
在這里使用 @GetMapping("/{orderId}"), 指定的是向遠程服務呼叫的路徑
Demo
1.新建springboot模塊,添加依賴

2.application.yml配置
# 應用名稱
spring:
application:
name: feign
# Actuator Web 訪問埠
server:
port: 3001
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka,http://eureka2:2002/eureka
1)測驗遠程呼叫(宣告式客戶端介面)
1.啟動類添加Feign注解
@EnableFeignClients

2.新建Feign包,創建ItemFeignService介面
import cn.tedu.sp01.pojo.Item;
import cn.tedu.sp01.util.JsonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
//根據服務id,從注冊表得到主機地址
@FeignClient(name = "item-service")
public interface ItemFeignService {
@GetMapping("/{orderId}")
JsonResult<List<Item>> getItems(@PathVariable(value = "orderId") String orderId);
@PostMapping("/decreaseNumber")
JsonResult<?> decreaseNumber(@RequestBody List<Item> items);
}
創建UserFeignService介面
import cn.tedu.sp01.pojo.User;
import cn.tedu.sp01.util.JsonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name= "user-service")
public interface UserFeignService {
@GetMapping("/{userId}")
JsonResult<User> getUser(@PathVariable(value = "userId") Integer userId);
@GetMapping(value = "/{userId}/score")
JsonResult<?> addScore(@PathVariable(value = "userId") Integer userId,
@RequestParam(value = "score") Integer score);//@RequestParam在Controller中可以省略,此處不能省略
}
創建OrderFeignService介面
import cn.tedu.sp01.pojo.Order;
import cn.tedu.sp01.util.JsonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient("order-service")
public interface OrderFeignService {
@GetMapping("/{orderId}")
JsonResult<Order> getOrder(@PathVariable(value = "orderId") String orderId);
@GetMapping("/")
JsonResult<?> addOrder();
}
3.創建controller
import cn.tedu.sp01.pojo.Item;
import cn.tedu.sp01.pojo.Order;
import cn.tedu.sp01.pojo.User;
import cn.tedu.sp01.util.JsonResult;
import cn.tedu.sp09.feign.ItemFeignService;
import cn.tedu.sp09.feign.OrderFeignService;
import cn.tedu.sp09.feign.UserFeignService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@Slf4j
public class ItemController {
@Autowired
private ItemFeignService itemFeignService;
@Autowired
private UserFeignService userFeignService;
@Autowired
private OrderFeignService orderFeignService;
@GetMapping("/item-service/{orderId}")
public JsonResult<List<Item>> getItems(@PathVariable String orderId){
return itemFeignService.getItems(orderId);
}
@PostMapping("/item-service/descrease")
public JsonResult<?> decreaseNumber(@RequestBody List<Item> items){
return itemFeignService.decreaseNumber(items);
}
@GetMapping("/user-service/{userId}")
public JsonResult<User> getUser(@PathVariable Integer userId){
return userFeignService.getUser(userId);
}
@GetMapping("/user-service/{userId}/score")
public JsonResult<?> addScore(@PathVariable Integer userId,
Integer score){
return userFeignService.addScore(userId, score);
}
@GetMapping("/order-service/{orderId}")
public JsonResult<Order> getOrder(@PathVariable String orderId){
return orderFeignService.getOrder(orderId);
}
@GetMapping("/order-service/")
public JsonResult<?> addOrder(){
return orderFeignService.addOrder();
}
}
測驗:

遠程呼叫成功!!!
呼叫流程:

feign + ribbon 負載均衡和重試
無需額外配置,feign 默認已啟用了 ribbon 負載均衡和重試機制,可以通過配置對引數進行調整
重試的默認配置引數:
ConnectTimeout=1000
ReadTimeout=1000
MaxAutoRetries=0
MaxAutoRetriesNextServer=1
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/250673.html
標籤:java
上一篇:高級JAVA 臨考抱佛腳 自用
