8.SentinelResource配置
①按資源名稱限流
(1)建立controller
package com.hry.springcloud.alibaba.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.hry.springcloud.entities.CommonResult;
import com.hry.springcloud.entities.Payment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RateLimitController {
@GetMapping(value = "/byResource")
@SentinelResource(value = "byResource",blockHandler = "handleException")
public CommonResult byResource(){
return new CommonResult(200,"按資源名稱限流測試OK",new Payment(202L,"serial001"));
}
public CommonResult handleException(BlockException exception){
return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服務不可用");
}
}
(2)建立流控規則
(3)測試
②按資源名稱限流
(1)在RateLimitController添加方法
@GetMapping("/rateLimit/byUrl")
@SentinelResource(value = "byUrl")
public CommonResult byUrl(){
return new CommonResult(200,"按url限流測試OK",new Payment(2020L,"serial002"));
}
(2)建立流控規則
(3)測試
③問題
跟之前的Hystrix一樣
④客戶自定義限流處理邏輯
(1)建立CustomerBlockHandler類
package com.hry.springcloud.alibaba.handler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.hry.springcloud.entities.CommonResult;
import com.hry.springcloud.entities.Payment;
public class CustomerBlockHandler {
public static CommonResult handlerException(BlockException exception){
return new CommonResult(1234567,"按客戶自定義全局-----Global-----1");
}
public static CommonResult handlerException2(BlockException exception){
return new CommonResult(7654321,"按客戶自定義全局-----Global-----2");
}
}
(2)在RateLimitController添加方法
@GetMapping("/rateLimit/customerBlockHandler")
@SentinelResource(value = "customerBlockHandler",
blockHandlerClass = CustomerBlockHandler.class, //指定我們剛才建立的類
blockHandler = "handlerException2") //使用第二個方法處理
public CommonResult customerBlockHandler(){
return new CommonResult(200,"自定義",new Payment(2020L,"serial003"));
}
(3)建立流控規則
(4)測試
9.服務熔斷
Sentinel+Ribbon+OpenFeign+fallback
Ribbon:
①Sentinel服務熔斷無配置
(1)cloudalibaba-provider-payment9003,cloudalibaba-provider-payment9004
這個與9002相似不同處下面會給出,其他直接複制原來的9002即可
controller
package com.hry.springcloud.alibaba.controller;
import com.hry.springcloud.entities.CommonResult;
import com.hry.springcloud.entities.Payment;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
@RestController
public class PaymentController {
@Value("${server.port}")
private String serverPort;
public static HashMap<Long, Payment> hashMap = new HashMap<>();
//模拟dao層 偷懶
static {
hashMap.put(1001L,new Payment(1001L,"1001abcd"));
hashMap.put(1002L,new Payment(1002L,"1002abcd"));
hashMap.put(1003L,new Payment(1003L,"1003abcd"));
}
@GetMapping(value = "/paymentSQL/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id){
Payment payment = hashMap.get(id);
CommonResult<Payment> result = new CommonResult<Payment>(200,"from MySQL , serverPort: "+serverPort,payment);
return result;
}
}
(2)cloudalibaba-consumer-nacos-order84
與83相似,沒有給出的的都與83内容一緻。
yml
server:
port: 84
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置nacos位址
sentinel:
transport:
#配置sentinel dashboard位址
dashboard: localhost:8080
#預設8719端口,端口被占用會自動從8719開始依次+1開始掃描,直至找到未被占用的端口
port: 8719
service-url:
nacos-user-service: http://nacos-payment-provider
controller
package com.hry.springcloud.alibaba.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.hry.springcloud.entities.CommonResult;
import com.hry.springcloud.entities.Payment;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@RestController
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Resource
private RestTemplate restTemplate;
@RequestMapping(value = "/consumer/fallback/{id}")
@SentinelResource(value = "fallback") //不配置的
public CommonResult<Payment> fallback(@PathVariable("id") Long id){
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL+"/paymentSQL/"+id,CommonResult.class,id);
if (id == 1004){
throw new IllegalArgumentException("IllegalArgumentException , 非法參數異常......");
}else if (result.getData() == null){
throw new NullPointerException("NullPointerException , 該ID沒有對應記錄,空指針異常");
}
return result;
}
}
(3)測試
1004
其他
②Sentinel服務熔斷隻配置fallback
(1)修改controller
修改
添加方法
public CommonResult<Payment> handlerFallback(@PathVariable("id") Long id,Throwable e){
Payment payment = new Payment(id,"null");
return new CommonResult<>(444,"handlerFallback兜底方法 , 異常"+e.getMessage(),payment);
}
(2)測試
③Sentinel服務熔斷隻配置blockHandler
(1)修改controller
修改
添加方法
public CommonResult<Payment> blockHandler(@PathVariable("id") Long id, BlockException blockException){
Payment payment = new Payment(id,"null");
return new CommonResult<>(4444,"blockHandler-sentinel限流,無此流水 , blockException"+blockException.getMessage(),payment);
}
(2)添加流控規則(或降級規則都可)
(3)測試
可以看到,流量異常能夠處理,但是運作時異常無法解決,是預設的
④Sentinel服務熔斷配置fallback和blockHandler
(1)修改controller
(2)添加流控規則(或降級規則都可)
(3)測試
這次完美了
①-④注解:
⑤Sentinel服務熔斷exceptionsToIgnore
(1)修改controller 在注解中添加exceptionsToIgnore 并指定哪些 異常
(2)測試
我們配置忽略非法參數異常之後找1004,會正常報錯。進到error page
OpenFeign:
①Sentinel服務熔斷OpenFeign
(1)修改84的yml
添加配置
#激活
feign:
sentinel:
enabled: true
(2)修改84的主啟動類
添加注解
(3)修改84的業務類
建立service包
建立接口PaymentService
package com.hry.springcloud.alibaba.service;
import com.hry.springcloud.alibaba.service.Impl.PaymentServiceImpl;
import com.hry.springcloud.entities.CommonResult;
import com.hry.springcloud.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "nacos-payment-provider",fallback = PaymentServiceImpl.class)
public interface PaymentService {
@GetMapping(value = "/paymentSQL/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id);
}
建立實作類PaymentServiceImpl
package com.hry.springcloud.alibaba.service.Impl;
import com.hry.springcloud.alibaba.service.PaymentService;
import com.hry.springcloud.entities.CommonResult;
import com.hry.springcloud.entities.Payment;
import org.springframework.stereotype.Component;
@Component
public class PaymentServiceImpl implements PaymentService {
@Override
public CommonResult<Payment> paymentSQL(Long id) {
return new CommonResult<>(55555,"服務降級傳回---來自PaymentServiceImpl",new Payment(id,"error"));
}
}
修改controller,添加如下代碼
@Resource
private PaymentService paymentService;
@GetMapping(value = "/consumer/paymentSQL/{id}")
public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id){
return paymentService.paymentSQL(id);
}
(4)測試
關閉9003,服務降級