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
转载自CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/qq_45273552/article/details/112761439