# 开启或关闭 @SentinelRestTemplate 注解
resttemplate:
sentinel:
enabled: true
/**
* <h1>开启服务间的调用保护, 需要给 RestTemplate 做一些包装</h1>
* */
@Slf4j
@Configuration
public class SentinelConfig {
/**
* <h2>包装 RestTemplate</h2>
* */
@Bean
// @SentinelRestTemplate(
// fallback = "handleFallback", fallbackClass = RestTemplateExceptionUtil.class,
// blockHandler = "handleBlock", blockHandlerClass = RestTemplateExceptionUtil.class
// )
public RestTemplate restTemplate() {
return new RestTemplate(); // 可以对其做一些业务相关的配置
}
}
import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import com.imooc.ecommerce.vo.JwtToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
/**
* <h1>RestTemplate 在限流或异常时的兜底方法</h1>
* */
@Slf4j
public class RestTemplateExceptionUtil {
/**
* <h2>限流后的处理方法</h2>
* */
public static SentinelClientHttpResponse handleBlock(HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution,
BlockException ex) {
log.error("Handle RestTemplate Block Exception: [{}], [{}]",
request.getURI().getPath(), ex.getClass().getCanonicalName());
return new SentinelClientHttpResponse(
JSON.toJSONString(new JwtToken("qinyi-imooc-block"))
);
}
/**
* <h2>异常降级之后的处理方法</h2>
* */
public static SentinelClientHttpResponse handleFallback(HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution,
BlockException ex) {
log.error("Handle RestTemplate Fallback Exception: [{}], [{}]",
request.getURI().getPath(), ex.getClass().getCanonicalName());
return new SentinelClientHttpResponse(
JSON.toJSONString(new JwtToken("qinyi-imooc-block"))
);
}
}
import com.alibaba.fastjson.JSON;
import com.imooc.ecommerce.vo.JwtToken;
import com.imooc.ecommerce.vo.UsernameAndPassword;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* <h1>使用 Sentinel 保护 RestTemplate 服务间调用</h1>
* */
@Slf4j
@RestController
@RequestMapping("/sentinel-rest-template")
public class SentinelRestTemplateController {
private final RestTemplate restTemplate;
public SentinelRestTemplateController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
/**
* <h2>从授权服务中获取 JwtToken</h2>
* 1. 流控降级:
* 是针对于簇点链路中的 http://127.0.0.1:7000/ecommerce-authority-center/authority/token
* 2. 容错降级: 对于服务不可用时不能生效
* */
@PostMapping("/get-token")
public JwtToken getTokenFromAuthorityService(
@RequestBody UsernameAndPassword usernameAndPassword) {
String requestUrl =
"http://127.0.0.1:7000/ecommerce-authority-center/authority/token";
log.info("RestTemplate request url and body: [{}], [{}]",
requestUrl, JSON.toJSONString(usernameAndPassword));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return restTemplate.postForObject(
requestUrl,
new HttpEntity<>(JSON.toJSONString(usernameAndPassword), headers),
JwtToken.class
);
}
}