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 服务不可用");
}
}
@GetMapping("/rateLimit/byUrl")
@SentinelResource(value = "byUrl")
public CommonResult byUrl(){
return new CommonResult(200,"按url限流测试OK",new Payment(2020L,"serial002"));
}
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");
}
}
@GetMapping("/rateLimit/customerBlockHandler")
@SentinelResource(value = "customerBlockHandler",
blockHandlerClass = CustomerBlockHandler.class, //指定我们刚才创建的类
blockHandler = "handlerException2") //使用第二个方法处理
public CommonResult customerBlockHandler(){
return new CommonResult(200,"自定义",new Payment(2020L,"serial003"));
}
Sentinel+Ribbon+OpenFeign+fallback
这个与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;
}
}
与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;
}
}
修改
@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
添加方法
public CommonResult<Payment> handlerFallback(@PathVariable("id") Long id,Throwable e){
Payment payment = new Payment(id,"null");
return new CommonResult<>(444,"handlerFallback兜底方法 , 异常"+e.getMessage(),payment);
}
修改
@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
添加方法
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);
}
可以看到,流量异常能够处理,但是运行时异常无法解决,是默认的
@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler")
@SentinelResource(value = "fallback",fallback = "handlerFallback",blockHandler = "blockHandler",exceptionsToIgnore = {IllegalArgumentException.class})
我们配置忽略非法参数异常之后找1004,会正常报错。进到error page
添加配置
#激活
feign:
sentinel:
enabled: true
添加注解
@EnableFeignClients
新建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);
}