一,RestTemplate整合Sentinel
yml配置
resttemplate:
sentinel:
#false 关闭@SentinelRestTemplate注解,在做开发调试的时候可以关闭此注解,专注于功能的实现
enabled: true
@Bean
@LoadBalanced
@SentinelRestTemplate
public RestTemplate RestTemplate(){
return new RestTemplate(new HttpComponentsClientHttpRequestFactory());
}
源码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.alibaba.cloud.sentinel.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SentinelRestTemplate {
String blockHandler() default "";
Class<?> blockHandlerClass() default void.class;
String fallback() default "";
Class<?> fallbackClass() default void.class;
String urlCleaner() default "";
Class<?> urlCleanerClass() default void.class;
}
(fallbackClass = ExceptionUtils.class,fallback = "handleFallback",blockHandler = "handleBlock" ,blockHandlerClass = ExceptionUtils.class)这四个属性结合起来处理异常
@Bean
@LoadBalanced
@SentinelRestTemplate(fallbackClass = ExceptionUtils.class,fallback = "handleFallback",blockHandler = "handleBlock" ,blockHandlerClass = ExceptionUtils.class)
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
package com.liu.entities;
import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
public class ExceptionUtils {
/**
* 静态方法
* 返回值: SentinelClientHttpResponse
* 参数 : request , byte[] , clientRquestExcetion , blockException
*/
//限流熔断业务逻辑
public static SentinelClientHttpResponse handleBlock(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
return new SentinelClientHttpResponse("custom block info");
}
//异常降级业务逻辑
public static SentinelClientHttpResponse handleFallback(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution, BlockException ex) {
return new SentinelClientHttpResponse("custom fallback info");
}
}
二,Feign整合Sentinel
yml
feign:
sentinel:
#为feign整合Sentinel
enabled: true
package com.liu.servcie;
import com.liu.servcie.impl.ConstomerSentinelService;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
@Component
@FeignClient(value = "sentinel-service", fallback = ConstomerSentinelService.class)
public interface SentinelFeignService {
@GetMapping(value = "/hello")
public String hello();
}
package com.liu.servcie.impl;
import com.liu.servcie.SentinelFeignService;
import org.springframework.stereotype.Component;
@Component
public class ConstomerSentinelService implements SentinelFeignService {
public String hello(){
return "进入兜底方法";
}
}
@SentinelResource注解的blockHandler只处理sentinel控制台的错误,不能处理程序错误,程序错误会走fallback。
使用@FeignClient的fallbackFactory属性,推荐使用这种方案**
@FeignClient(name = "user-center",
//fallback = UserCenterFeignClientFallback.class
fallbackFactory = UserCenterFeignClientFallbackFactory.class)
public interface UserCenterFeignClient {
/**
*
* @param id
* @return
*/
@GetMapping("/users/{id}")
UserDTO findById(@PathVariable Integer id);
}
/**
* 发生限流降级时,自定义处理逻辑
* 一旦PriceFeignClient中远程调用的getPrice()方法被流控了或发生异常了,就会进入此方法
* 这就相当于一个兜底的行为,保证了服务的可用
* 相比于FeignClient中的fallback属性而言,fallbackFactory属性在fallback的基础上可以拿到异常信息
*/
@Component
@Slf4j
public class UserCenterFeignClientFallbackFactory
implements FallbackFactory<UserCenterFeignClient> {
@Override
public UserCenterFeignClient create(Throwable throwable) {
return new UserCenterFeignClient() {
/**
* @param id
* @return
*/
@Override
public UserDTO findById(Integer id) {
log.warn("远程调用被限流/降级了",throwable);
UserDTO userDTO = new UserDTO();
userDTO.setWxNickname("一个默认用户");
return userDTO;
}
};
}
}
Sentinel使用方式总结
使用方式
- 编码方式 API try…catch…finally
- 注解方式 @SentinelResource blockHandler / fallback
- RestTemplate @SentinelRestTemplate blockHandler / fallback
- Feign feign.sentinel.enabled=true fallback / fallbackFactory