I.FALLBACK
1、准备两个提供者9003、9004,和一个服务消费者
配置参照:https://www.aimaboge.com/article/717
2、编写接口
- 服务提供者:
package com.laoxu.springcloud.controller;
import com.laoxu.springcloud.entities.CommonResult;
import com.laoxu.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}")
public String serverPort;
public static HashMap<Long, Payment> hashMap = new HashMap<Long, Payment>();
static
{
hashMap.put(1L, new Payment(1L, "a"));
hashMap.put(2L, new Payment(2L, "b"));
hashMap.put(3L, new Payment(3L, "c"));
}
@GetMapping("/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;
}
}
- 服务消费者
package com.laoxu.springcloud.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.laoxu.springcloud.entities.CommonResult;
import com.laoxu.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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;
@RestController
@Slf4j
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/consumer/fallback/{id}")
@SentinelResource(value = "fallback", fallback = "handleFallback")
public CommonResult<Payment> fallback(@PathVariable("id") Long id){
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class);
if(id == 4){
throw new IllegalArgumentException("IllegalArgumentException, 非法参数异常。。。");
}else if(id > 4 && id < 8){
throw new NullPointerException("NullPointerException, 该id没有对应的记录,空指针异常");
}
return result;
}
public CommonResult<Payment> handleFallback(@PathVariable("id") Long id, Throwable e){
Payment payment = new Payment(id, "null");
return new CommonResult<Payment>(444, "fallback异常, 异常内容:"+ e.getMessage(), payment);
}
}
3、测试访问:http://localhost:84/consumer/fallback/1
负载均衡配置完成。
4、测试访问:http://localhost:84/consumer/fallback/4
5、测试访问:http://localhost:84/consumer/fallback/5
II.BLOCKEXCEPTION
1、服务提供者接口不变
package com.laoxu.springcloud.controller;
import com.laoxu.springcloud.entities.CommonResult;
import com.laoxu.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}")
public String serverPort;
public static HashMap<Long, Payment> hashMap = new HashMap<Long, Payment>();
static
{
hashMap.put(1L, new Payment(1L, "a"));
hashMap.put(2L, new Payment(2L, "b"));
hashMap.put(3L, new Payment(3L, "c"));
}
@GetMapping("/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、消费者改变
package com.laoxu.springcloud.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.laoxu.springcloud.entities.CommonResult;
import com.laoxu.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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;
@RestController
@Slf4j
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/consumer/fallback/{id}")
// @SentinelResource(value = "fallback", fallback = "handleFallback")
@SentinelResource(value = "fallback", blockHandler = "blockHandler")
public CommonResult<Payment> fallback(@PathVariable("id") Long id){
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class);
if(id == 4){
throw new IllegalArgumentException("IllegalArgumentException, 非法参数异常。。。");
}else if(id > 4 && id < 8){
throw new NullPointerException("NullPointerException, 该id没有对应的记录,空指针异常");
}
return result;
}
public CommonResult<Payment> handleFallback(@PathVariable("id") Long id, Throwable e){
Payment payment = new Payment(id, "null");
return new CommonResult<Payment>(444, "fallback异常, 异常内容:"+ e.getMessage(), payment);
}
public CommonResult<Payment> blockHandler(@PathVariable Long id, BlockException exception){
Payment payment = new Payment(id, "null");
return new CommonResult<Payment>(445, "blockHandler-sentinel限流, 无此流水 异常内容:"+ exception.getMessage(), payment);
}
}
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.laoxu.springcloud.entities.CommonResult;
import com.laoxu.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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;
@RestController
@Slf4j
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/consumer/fallback/{id}")
// @SentinelResource(value = "fallback", fallback = "handleFallback")
@SentinelResource(value = "fallback", blockHandler = "blockHandler")
public CommonResult<Payment> fallback(@PathVariable("id") Long id){
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class);
if(id == 4){
throw new IllegalArgumentException("IllegalArgumentException, 非法参数异常。。。");
}else if(id > 4 && id < 8){
throw new NullPointerException("NullPointerException, 该id没有对应的记录,空指针异常");
}
return result;
}
public CommonResult<Payment> handleFallback(@PathVariable("id") Long id, Throwable e){
Payment payment = new Payment(id, "null");
return new CommonResult<Payment>(444, "fallback异常, 异常内容:"+ e.getMessage(), payment);
}
public CommonResult<Payment> blockHandler(@PathVariable Long id, BlockException exception){
Payment payment = new Payment(id, "null");
return new CommonResult<Payment>(445, "blockHandler-sentinel限流, 无此流水 异常内容:"+ exception.getMessage(), payment);
}
}
3、配置sentinel限流
4、测试访问:http://localhost:84/consumer/fallback/4
会看到error page,java运行报错页面,blockException只管配置违规,不管java报错
当2s内访问次数超过2次那么触发blockException
III.BLOCKEXCEPTION && FALLBACK
1、服务提供者接口不变
package com.laoxu.springcloud.controller;
import com.laoxu.springcloud.entities.CommonResult;
import com.laoxu.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}")
public String serverPort;
public static HashMap<Long, Payment> hashMap = new HashMap<Long, Payment>();
static
{
hashMap.put(1L, new Payment(1L, "a"));
hashMap.put(2L, new Payment(2L, "b"));
hashMap.put(3L, new Payment(3L, "c"));
}
@GetMapping("/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、消费者改变
package com.laoxu.springcloud.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.laoxu.springcloud.entities.CommonResult;
import com.laoxu.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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;
@RestController
@Slf4j
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/consumer/fallback/{id}")
// @SentinelResource(value = "fallback", fallback = "handleFallback")
// @SentinelResource(value = "fallback", blockHandler = "blockHandler")
@SentinelResource(value = "fallback", fallback = "handleFallback", blockHandler = "blockHandler")
public CommonResult<Payment> fallback(@PathVariable("id") Long id){
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class);
if(id == 4){
throw new IllegalArgumentException("IllegalArgumentException, 非法参数异常。。。");
}else if(id > 4 && id < 8){
throw new NullPointerException("NullPointerException, 该id没有对应的记录,空指针异常");
}
return result;
}
public CommonResult<Payment> handleFallback(@PathVariable("id") Long id, Throwable e){
Payment payment = new Payment(id, "null");
return new CommonResult<Payment>(444, "fallback异常, 异常内容:"+ e.getMessage(), payment);
}
public CommonResult<Payment> blockHandler(@PathVariable Long id, BlockException exception){
Payment payment = new Payment(id, "null");
return new CommonResult<Payment>(445, "blockHandler-sentinel限流, 无此流水 异常内容:"+ exception.getMessage(), payment);
}
}
3、配置sentinel限流
4、测试访问:http://localhost:84/consumer/fallback/4
当没有达到限流规则的条件的情况下,走fallback异常
当达到限流规则的条件的情况下,走blockException异常
结论:sentinel平台违规优先级大于java报错
5、异常忽略
- 修改接口
异常忽略:exceptionsToIgnore = IllegalArgumentException.class
加上后,出现IllegalArgumentException后不会走handleFallback
@RestController
@Slf4j
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/consumer/fallback/{id}")
// @SentinelResource(value = "fallback", fallback = "handleFallback")
// @SentinelResource(value = "fallback", blockHandler = "blockHandler")
// @SentinelResource(value = "fallback", fallback = "handleFallback", blockHandler = "blockHandler")
@SentinelResource(value = "fallback", fallback = "handleFallback",
blockHandler = "blockHandler", exceptionsToIgnore = IllegalArgumentException.class)
public CommonResult<Payment> fallback(@PathVariable("id") Long id){
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class);
if(id == 4){
throw new IllegalArgumentException("IllegalArgumentException, 非法参数异常。。。");
}else if(id > 4 && id < 8){
throw new NullPointerException("NullPointerException, 该id没有对应的记录,空指针异常");
}
return result;
}
public CommonResult<Payment> handleFallback(@PathVariable("id") Long id, Throwable e){
Payment payment = new Payment(id, "null");
return new CommonResult<Payment>(444, "fallback异常, 异常内容:"+ e.getMessage(), payment);
}
public CommonResult<Payment> blockHandler(@PathVariable Long id, BlockException exception){
Payment payment = new Payment(id, "null");
return new CommonResult<Payment>(445, "blockHandler-sentinel限流, 无此流水 异常内容:"+ exception.getMessage(), payment);
}
}