ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

sentinel篇2-资源注解使用-结合SpringAOP

2021-11-11 18:35:48  阅读:165  来源: 互联网

标签:return String class sentinel SpringAOP 注解 resource1 public


前言

  • 上篇进行了快速的入门使用,可以知道的是:
    • 使用 sentinel 主要就是 定义资源、配置资源规则、验证配置的有效性
    • 资源在 sentinel 中,“可以是任何东西,服务,服务里的方法,甚至是一段代码。”
  • 本篇将使用 sentinel 注解进行资源的定义,这需要引入切面相关依赖。流控的监控和规则配置则是通过 sentinel-dashboard

springboot应用集成sentinel

  • pom依赖
<dependency>
	<groupId>com.alibaba.csp</groupId>
	<artifactId>sentinel-core</artifactId>
	<version>${sentinel.version}</version>
</dependency>
<dependency>
	<groupId>com.alibaba.csp</groupId>
	<artifactId>sentinel-annotation-aspectj</artifactId>
	<version>${sentinel.version}</version>
</dependency>
<dependency>
	<groupId>com.alibaba.csp</groupId>
	<artifactId>sentinel-transport-simple-http</artifactId>
	<version>${sentinel.version}</version>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • 注入sentinel资源注册切面 SentinelResourceAspect
@Configuration
public class SentinelAspectConfiguration {

    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
}
  • 使用 @SentinelResource 定义资源
@Service
public class TestService {
	@SentinelResource(value = "resource1")
	public String resource1() {
		System.out.println("resource1");
		return "resource1";
	}
	
	public String notResource() {
		System.out.println("notResource");
		return "resource1";
	}
}

@RestController
public class Demo1Controller {
	@Autowired
    private TestService service;
	
	@GetMapping("/resource1")
    public String resource1() {
		
        return service.resource1() + " " + LocalDateTime.now().toString();
    }
	
	@GetMapping("/notResource")
    public String notResource() {
		
        return service.notResource() + " " + LocalDateTime.now().toString();
    }
}
  • 启动应用(启动参数配置-Dcsp.sentinel.dashboard.server=localhost:8080或者springboot启动类main方法设置系统参数System.setProperty("csp.sentinel.dashboard.server", "localhost:8080");
  • 密集请求目标资源,观察dashboard资源请求情况,因为没有配置任何流控规则,所以只是监控,没有阻断效果,图示 ↓
    sentinel002.jpg
  • dashboard 配置资源的流控规则(FlowRule),限制为QPS=1,密集请求查看效果,图示 ↓
    sentinel003.jpg
    sentinel004.jpg
  • 代码配置资源的阻断处理(blockHandler)和或降级处理(fallback)并进行验证
    @Service
    public class TestService {
    	@SentinelResource(value = "resource1", blockHandler = "handleException", blockHandlerClass = { ExceptionUtil2.class })
    	public String resource1() {
    		System.out.println("resource1");
    		return "resource1";
    	}
    	
    	public String notResource() {
    		System.out.println("notResource");
    		return "notResource";
    	}
    
    	@SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = { ExceptionUtil.class })
    	public void test() {
    		System.out.println("Test");
    	}
    
    	@SentinelResource(value = "hello", fallback = "helloFallback")
    	public String hello(long s) {
    		if (s < 0) {
    			throw new IllegalArgumentException("invalid arg");
    		}
    		return String.format("Hello at %d", s);
    	}
    
    	@SentinelResource(value = "helloAnother", defaultFallback = "defaultFallback", exceptionsToIgnore = {
    			IllegalStateException.class })
    	public String helloAnother(String name) {
    		if (name == null || "bad".equals(name)) {
    			throw new IllegalArgumentException("oops");
    		}
    		if ("foo".equals(name)) {
    			throw new IllegalStateException("oops");
    		}
    		return "Hello, " + name;
    	}
    
    	public String helloFallback(long s, Throwable ex) {
    		// Do some log here.
    		ex.printStackTrace();
    		return "Oops, error occurred at " + s;
    	}
    
    	public String defaultFallback() {
    		System.err.println("Go to default fallback");
    		return "default_fallback";
    	}
    }
    
    public final class ExceptionUtil2 {
    	public static String handleException(BlockException ex) {
            // Handler method that handles BlockException when blocked.
            // The method parameter list should match original method, with the last additional
            // parameter with type BlockException. The return type should be same as the original method.
            // The block handler method should be located in the same class with original method by default.
            // If you want to use method in other classes, you can set the blockHandlerClass
            // with corresponding Class (Note the method in other classes must be static).
            System.err.println("Oops: " + ex.getClass().getCanonicalName());
            
            return ex.getClass().getSimpleName();
        }
    }
    
    • 踩坑注意点:
    • 1)blockHandler的方法必须为静态方法,且返回值和“资源”相同
    • 2)fallback的方法需要和“资源”在同一个类中(除非再指定 fallbackClass),且参数和返回类型都要一致
    • 3)同时配置 blockHandler 和 fallback 的话,只会 blockHandler 起作用
    • 4)从使用上看,blockHandler 针对限流,强调快速异常(明确告诉调用端这样不可用);fallback 针对降级,强调友好的备用响应(保持调用链路完整性)。归根到底都是对目标资源进行高可用保护!(PS:blockHandler 使用下来的话,感觉用全局异常处理-ControllerAdvice代替更加方便)
    • 官方说明参考:https://sentinelguard.io/zh-cn/docs/annotation-support.html

有效参考

标签:return,String,class,sentinel,SpringAOP,注解,resource1,public
来源: https://www.cnblogs.com/noodlerkun/p/15541115.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有