zoukankan      html  css  js  c++  java
  • sentinel篇2资源注解使用结合SpringAOP

    前言

    • 上篇进行了快速的入门使用,可以知道的是:
      • 使用 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和fallback的方法,参数和返回值需注意,如果指定另外一个类的方法,则必须是static方法!
      • 2)同时配置 blockHandler 和 fallback 的话,只会 blockHandler 起作用
      • 3)“注意 blockHandler 函数会在原方法被限流/降级/系统保护的时候调用,而 fallback 函数会针对所有类型的异常。”
      • 官方说明参考:https://sentinelguard.io/zh-cn/docs/annotation-support.html

    有效参考

  • 相关阅读:
    SQL注入过滤
    ASP.NET长文章分页
    简单的权限管理类
    不错的面试题
    【转载】【重要】Ubuntu Linux 下 Ffmpeg 及 Mencoder 安装使用小结
    回到xwindows
    suse11 linux不自动启动xwindows
    flash的几种工具
    mencoder和ffmpeg参数详解
    ffmpeg和Mencoder使用实例小全
  • 原文地址:https://www.cnblogs.com/noodlerkun/p/15541115.html
Copyright © 2011-2022 走看看