强强联合:OpenFeign 整合 Sentinel
前言书接前文微服务间的远程接口调用OpenFeign 的使用当项目中使用了OpenFeign后可以很方便的进行远程服务调用现在有个问题假如远程服务出现故障了调不了远程的接口这边又着急等着返回结果怎么办呢当然是使用服务降级本篇就使用OpenFeign进行远程调用并结合Sentinel对出现的异常、故障等问题进行服务降级。准备本章代码仓库https://github.com/iweidujiang/spring-cloud-alibaba-lab示例模块08-feign-sentinel在feign-sentinel-service中整合 OpenFeign 与 Sentinel。仍以前面第 7 章open-feign-service的思路为调用方、nacos-provider为提供方来进行操练本章代码位于08-feign-sentinel目录。Jar 包依赖feign-sentinel-service除引入spring-cloud-starter-openfeign外再引入spring-cloud-starter-alibaba-sentinel组件使用 Nacos 配置中心做 Sentinel 限流规则持久化还需引入spring-cloud-alibaba-sentinel-datasource和sentinel-datasource-nacosdependencygroupIdio.github.iweidujiang/groupIdartifactIdfeign-sentinel-common/artifactIdversion1.0.0/version/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-alibaba-sentinel-datasource/artifactId/dependencydependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactId/dependency配置文件配置文件application.ymlspring:application:name:open-feign-servicecloud:nacos:discovery:server-addr:${NACOS_SERVER:127.0.0.1:8848}sentinel:transport:dashboard:${SENTINEL_DASHBOARD:localhost:8080}port:8723web-context-unify:falsedatasource:flow:nacos:server-addr:${NACOS_SERVER:127.0.0.1:8848}groupId:DEFAULT_GROUPdataId:sentinelFlowRule.jsonrule-type:flowfeign:client:config:default:connectTimeout:5000readTimeout:5000nacos-provider:connectTimeout:1000readTimeout:1000loggerLevel:fullsentinel:enabled:true限流规则 JSON 示例见仓库08-feign-sentinel/config/sentinelFlowRule.json。这里增加了Sentinel的数据持久化内容以及激活OpenFeign与Sentinel联合使用的feign.sentinel.enabledtrue配置。全局统一异常处理不管是Sentinel限流后返回还是OpenFeign的fallback返回本质上他们都是出现异常了这里配置一下全局的统一异常处理。首先增加一个业务异常类io.github.iweidujiang.lab08.common.exception.BusinessException/** * 业务异常。 * * author 苏渡苇 */publicclassBusinessExceptionextendsRuntimeException{privatefinalStringcode;privatefinalStringmessage;publicBusinessException(Stringcode,Stringmessage){super(message);this.codecode;this.messagemessage;}publicStringgetCode(){returncode;}OverridepublicStringgetMessage(){returnmessage;}}然后使用RestControllerAdvice进行全局异常处理ExceptionHandler(BusinessException.class)publicResponseResultStringbusinessException(BusinessExceptione){LOGGER.info(code{}, message{},e.getCode(),e.getMessage());returnResponseResult.fail(e.getCode(),e.getMessage());}这样只要指定了抛出的异常类型就会返回统一的响应格式。操练FeignClient 的 fallback在上一篇文章中我们通过FeignClient接口调用远程的服务FeignClient(namenacos-provider,fallbackProductServiceImpl.class)publicinterfaceProductService{GetMapping(/product/{id})StringgetProductById(PathVariable(id)Longid);}定义 fallback 实现类ComponentpublicclassProductServiceImplimplementsProductService{OverridepublicStringgetProductById(Longid){log.error(调用接口 getProduct 失败id{},id);thrownewBusinessException(ResponseCode.RPC_ERROR.getCode(),ResponseCode.RPC_ERROR.getMessage());}}TipsResponseCode.RPC_ERROR在feign-sentinel-common模块中定义C0001/ 远程调用失败。OK不启动服务提供方nacos-provider直接调用接口测试。接口返回控制台打印信息这样就实现了fallback的容错处理即时远程服务不可用也能进行降级处理。SentinelResource 限流在 Controller 层使用 FeignClient 定义的接口进行远程调用服务时还可以定义 Sentinel 资源并设置规则对资源进行限流。SentinelResource的一些使用方法在前几篇文章中已有提及这里再结合OpenFeign使用本例中有如下定义GetMapping(/product/{id})SentinelResource(valuegetProduct,blockHandlergetProductBlock,fallbackgetProductFallback)publicStringgetProduct(PathVariable(id)Longid){returnproductService.getProductById(id);}publicStringgetProductBlock(Longid,BlockExceptione){log.error(访问资源 getProduct 被限流id{},id);thrownewBusinessException(C0002,访问资源 getProduct 被限流);}publicStringgetProductFallback(Longid){log.error(访问资源 getProduct fallback);return请稍后重试;}在前面的准备工作中我们已经配置了 Sentinel 资源限流规则持久化到 Nacos现在 Nacos 中配置一下资源getProduct的限流规则[{resource:getProduct,limitApp:default,grade:1,count:1,strategy:0,controlBehavior:0,clusterMode:false}]限流规则是 QPS 阈值为1只要我1秒大于1次请求就会被限流。启动远程服务nacos-provider下面来验证一下。1秒只发一个请求的结果1秒内快速刷新几次造成QPS大于1将会被限流小结OpenFeign整合Sentinel需要引入Sentinel相关依赖包在配置文件通过feign.sentinel.enabledtrue来开启 Feign 与 Sentinel的结合使用在FeignClient注解中增加fallback属性该属性定义远程接口访问有问题时的容错处理逻辑的类fallback定义的类需实现FeignClient定义的接口。点个赞再走吧~先赞后看养成习惯。举手之劳赞有余香。本文创作于 2022-08-19 。代码仓库已更新https://github.com/iweidujiang/spring-cloud-alibaba-lab