Sentinel 容灾中心的使用

Sentinel 容灾中心的使用

往期文章

  1. Nacos环境搭建
  2. Nacos注册中心的使用
  3. Nacos配置中心的使用

熔断/限流结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Jar

生产者

spring-cloud-alibaba:2021.0.4.0
spring-boot:2.6.8
spring-cloud-loadbalancer:3.1.3
sentinel:2021.0.4.0

<!-- 一定要放在前面 -->
<!--Sentinel -->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- sentinel-dashboard -->
<dependency>
	<groupId>com.alibaba.csp</groupId>
	<artifactId>sentinel-transport-simple-http</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!--Spring Cloud Alibaba Nacos Discovery-->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--Spring Cloud Alibaba Nacos Config-->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--LoadBalancer-->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

消费者

<!-- 一定要放在前面 -->
<!--Sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--Spring Cloud Alibaba Nacos Config-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--LoadBalancer-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--FastJSON-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
</dependency>

yml

生产者

server:
port: 8481
spring:
  application:
	name: nacos-provider
  cloud:
	nacos:
	  discovery:
		server-addr: localhost:8848
		username: devilvan
		password: 741258963hjkl
management:
  endpoints:
	web:
	  exposure:
		include: '*'

消费者

server:
  port: 8581
spring:
  application:
    name: nacos-consumer
  cloud:
    nacos:
      config:
        group: DEFAULT_GROUP
        server-addr: localhost:8848

熔断/流量控制(硬编码限流规则)

【资源】是sentinel限流、熔断的基本单位,可以设置每个资源的阈值。

@Service
public class NacosProviderServiceImpl implements NacosProviderService {
    private static final String[] RESOURCE_NAME_ARR = new String[]{"echo", "echo2"};

    /**
     * 初始化限流规则
     */
    @PostConstruct
    public void initFlowRules() {
        List<FlowRule> flowRules = new ArrayList<>();
        for (String resourceName : RESOURCE_NAME_ARR) {
            FlowRule flowRule = new FlowRule();
            // 设置受保护的资源
            flowRule.setResource(resourceName);
            // 设置流控规则 QPS
            flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
            // 设置受保护的资源阈值
            // Set limit QPS to 1.
            flowRule.setCount(1);
            flowRules.add(flowRule);
        }
        // 加载配置好的规则
        FlowRuleManager.loadRules(flowRules);
    }
}

控制层

其中echo方法使用注解形式定义sentinel资源,并通过自定义类的形式指定熔断和限流的方法。

/**
 * @Description Nacos生产者 控制层
 */
@RestController
@RequestMapping(value = "nacosProviderController")
public class NacosProviderController {
	@Resource(name = "nacosProviderServiceImpl")
	private NacosProviderService nacosProviderService;

	@GetMapping(value = "/echo/{str}")
	@SentinelResource(value = "echo", fallback = "echoFallback", fallbackClass = EchoFallback.class,
			blockHandler = "echoBlockHandler", blockHandlerClass = EchoFallback.class)
	public ResultMessage<String> echo(@PathVariable String str) {
		return nacosProviderService.echo(str);
	}

	@GetMapping(value = "/echo2/{str}")
	public ResultMessage<String> echo2(@PathVariable String str) {
		return nacosProviderService.echo2(str);
	}
}

echo方法对应限流/熔断处理类

/**
 * @Description echo方法 异常回调类
 */
public class EchoFallback {
	/**
	 * 遇到异常走的逻辑
	 *
	 * @param str 原方法的参数
	 * @param e   异常信息
	 * @return 异常回调方法返回值,和原方法返回值一致
	 */
	public static ResultMessage<String> echoFallback(String str, Throwable e) {
		ResultMessage<String> resultMessage = new ResultMessage<>();
		String message = "熔断-echo方法调用异常,str: " + str + "\n" + e;
		resultMessage.setMessage(message);
		return resultMessage;
	}

	/**
	 * 方法限流逻辑
	 *
	 * @param str 原方法的参数
	 * @param e   异常信息
	 * @return 限流回调方法返回值,和原方法返回值一致
	 */
	public static ResultMessage<String> echoBlockHandler(String str, BlockException e) {
		ResultMessage<String> resultMessage = new ResultMessage<>();
		String message = "限流-echo方法进行 限流,str: " + str + "\n" + e;
		resultMessage.setMessage(message);
		return resultMessage;
	}
}

业务逻辑层

echo2方法则使用官方案例的写法,先在初始化initFlowRules()方法中定义echo2资源,然后在实现类中编写对该资源熔断、限流的逻辑

/**
 * @Description Nacos生产者 业务逻辑实现类
 */
@Service
public class NacosProviderServiceImpl implements NacosProviderService {
	private static final String[] RESOURCE_NAME_ARR = new String[]{"echo", "echo2"};

	/**
	 * 初始化限流规则
	 */
	@PostConstruct
	public void initFlowRules() {
		List<FlowRule> flowRules = new ArrayList<>();
		for (String resourceName : RESOURCE_NAME_ARR) {
			FlowRule flowRule = new FlowRule();
			// 设置受保护的资源
			flowRule.setResource(resourceName);
			// 设置流控规则 QPS
			flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
			// 设置受保护的资源阈值
			// Set limit QPS to 1.
			flowRule.setCount(1);
			flowRules.add(flowRule);
		}
		// 加载配置好的规则
		FlowRuleManager.loadRules(flowRules);
	}

	/**
	 * 测试限流/熔断的方法
	 *
	 * @param str 原方法的参数
	 * @return 回调
	 */
	@Override
	public ResultMessage<String> echo(String str) {
		ResultMessage<String> resultMessage = new ResultMessage<>();
		if ("devilvan".equals(str)) {
			String msg = "Hello Nacos Discovery " + str;
			resultMessage.setMessage(msg);
		} else {
			throw new RuntimeException();
		}
		return resultMessage;
	}

	/**
	 * 测试sentinel设置资源并使用的方法
	 *
	 * @param str 入参字符串
	 * @return 回调
	 */
	@Override
	public ResultMessage<String> echo2(String str) {
		String resource = "echo2";
		ResultMessage<String> resultMessage = new ResultMessage<>();
		Entry entry = null;
		try {
			entry = SphU.entry(resource);
			if ("devilvan".equals(str)) {
				String msg = "Hello Nacos Discovery " + str;
				resultMessage.setMessage(msg);
			} else {
				throw new RuntimeException();
			}
		} catch (BlockException e) {
			String msg = "限流-echo2方法调用异常,str: " + str + "\n" + e;
			resultMessage.setMessage(msg);
		} catch (Exception e) {
			String msg = "熔断-echo2方法调用异常,str: " + str + "\n" + e;
			resultMessage.setMessage(msg);
		} finally {
			if (entry != null) {
				entry.exit();
			}
		}
		return resultMessage;
	}
}

对于使用异常的解释

以上两个方法案例中都涉及到对异常的处理(高亮部分),熔断的方法对应使用Throwable的异常捕获,限流的方法只使用BlockException异常进行捕获。

消费者代码

控制层

/**
 * @Description Nacos消费者 控制层
 */
@RestController
@RequestMapping(value = "nacosConsumerController")
public class NacosConsumerController {
	private NacosFeignService nacosFeignService;

	@Autowired
	public void setNacosFeignService(NacosFeignService nacosFeignService) {
		this.nacosFeignService = nacosFeignService;
	}

	@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
	public String echo(@PathVariable String str) {
		return nacosFeignService.echo(str);
	}

	@RequestMapping(value = "/echo2/{str}", method = RequestMethod.GET)
	public String echo2(@PathVariable String str) {
		return nacosFeignService.echo2(str);
	}
}

feign远程调用层

/**
 * @author Evad.Wu
 * @Description Nacos Feign 远程调用接口
 * @date 2022-11-05
 */
@FeignClient(value = "nacos-provider")
public interface NacosFeignService {
	/**
	 * 远程调用的测试方法
	 *
	 * @param str 路由下的参数
	 * @return 返回值
	 * @author Evad.Wu
	 * @Description 远程调用的测试方法
	 * @date 2022-11-05
	 */
	@GetMapping(value = "nacosProviderController/echo/{str}")
	String echo(@PathVariable String str);

	/**
	 * 远程调用的测试方法2
	 *
	 * @param str 路由下的参数
	 * @return 返回值
	 * @author Evad.Wu
	 * @Description 远程调用的测试方法2
	 * @date 2022-11-05
	 */
	@GetMapping(value = "nacosProviderController/echo2/{str}")
	String echo2(@PathVariable String str);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加把劲骑士RideOn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值