触发限流或熔断后的请求不一定要直接报错,也可以返回一些默认数据或者友好提示,用户体验会更好。
给FeignClient编写失败后的降级逻辑有两种方式:
- 方式一:FallbackClass,无法对远程调用的异常做处理
- 方式二:FallbackFactory,可以对远程调用的异常做处理,我们一般选择这种方式。
方式一参考链接:通过实现ItemClient接口以实现Fallback逻辑
这里我们演示方式二的失败降级处理。ItemClient代码如下
:
import com.hmall.api.dto.ItemDTO;
import com.hmall.api.dto.OrderDetailDTO;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Collection;
import java.util.List;
/**
* feign接口
* @author: Sakura
* @date 2024-02-28 21:16
*/
@FeignClient(value = "item-service")
public interface ItemClient {
/**
* 等价于GET方式的HTTP请求:http://host:port/items?ids=xxx
*/
@GetMapping("/items")
List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}
步骤一:给ItemClient
定义降级处理类,实现FallbackFactory
接口:
代码如下:
import com.hmall.api.client.ItemClient;
import com.hmall.api.dto.ItemDTO;
import com.hmall.api.dto.OrderDetailDTO;
import com.hmall.common.exception.BizIllegalException;
import com.hmall.common.utils.CollUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import java.util.Collection;
import java.util.List;
@Slf4j
public class ItemClientFallback implements FallbackFactory<ItemClient> {
@Override
public ItemClient create(Throwable cause) {
return new ItemClient() {
@Override
public List<ItemDTO> queryItemByIds(Collection<Long> ids) {
log.error("远程调用ItemClient#queryItemByIds方法出现异常,参数:{}", ids, cause);
// 查询购物车允许失败,查询失败,返回空集合
return CollUtils.emptyList();
}
@Override
public void deductStock(List<OrderDetailDTO> items) {
// 库存扣减业务需要触发事务回滚,查询失败,抛出异常
throw new BizIllegalException(cause);
}
};
}
}
步骤二:将编写的ItemClientFallback
注册为一个Bean
:
/**
* 作为Bean注入spring容器
*/
@Bean
public ItemClientFallback itemClientFallback() {
return new ItemClientFallback();
}
步骤三:ItemClient
接口中配置fallbackFactory
属性为ItemClientFallbackFactory.class
:
@FeignClient(value = "item-service",fallbackFactory = ItemClientFallback.class)
public interface ItemClient {
重启后,再次测试,发现被限流的请求不再报错,走了降级逻辑:
但是未被限流的请求延时依然很高:
导致最终的平局响应时间较长。
注意:这里需要设置jmeter重启
,不要继续之前的测试,否则异常率不为0