美文网首页后端java
程序员,你知道Sentinel限流、降级的统一处理吗?

程序员,你知道Sentinel限流、降级的统一处理吗?

作者: 享学课堂 | 来源:发表于2020-06-22 18:02 被阅读0次

    前言

    之前老顾介绍了sentinel的fallback、blockhandler;不知道小伙伴们有没有注意到一个问题?老顾带着大家来看看。

    问题一

    sentinel的默认流控返回的是:

    
    1.  `BlockedbySentinel(flow limiting)`
    
    

    当然我们可以通过@SentinelResource设置定制的fallback、blockhandler方法

    但是我们也不可能每个限制的方法上面,都要去设置@SentinelResource;这样代码太冗余了。

    解决方案

    自定义限流页面

    默认情况下,当请求被限流时会返回默认的提示页面。可通过二种方式设置自定义的跳转 URL。

    方式一:

    
    1.  `WebServletConfig.setBlockPage(blockPage)方法`
    
    

    方式二:

    
    1.  `JVM -Dcsp.sentinel.web.servlet.block.page=xxx`
    
    

    在启动应用的时候,加入启动参数:

    1.  `//设置全局生效,被流控的所有页面都会跳转到这里。`
    
    2.  `-Dcsp.sentinel.web.servlet.block.page=https://www.x.com`
    
    

    上面的两种方式,都能够做到一旦出现流控异常,就会跳转到指定页面。

    更灵活的处理方式

    上面的解决方案,只是跳转到另一个页面,但如果我们只要得到json返回值呢;那就需要此方式了,定义UrlBlockHandler接口限流处理逻辑,并将其注册至 WebCallbackManager

    首先自定义一个UrlBlockHandler实现类

    在一个初始化方法里面注册此UrlBlockHandler

    来看看效果

    注意此解决方案:需要引入一个jar包,这个是基于servlet

    
    1.  `<dependency>`
    
    2.  `<groupId>com.alibaba.csp</groupId>`
    
    3.  `<artifactId>sentinel-web-servlet</artifactId>`
    
    4.  `</dependency>`
    
    

    问题二

    在spring cloud中我们会经常使用到feign,在@FeignClient中我们可以指定fallback,我们来看看案例:

    以上就是常规的在使用@FeignClient注解时,加上fallbackFactory;但每次都要为其设置fallbackFactory参数。导致项目中会多出很多冗余代码。那我们能不能有一个自己定制化的默认Fallback去处理这些相同的事情呢?

    解决方案

    在使用sentinel时,需要引入一个jar包:

    1.  `<dependency>`
    
    2.  `<groupId>com.alibaba.cloud</groupId>`
    
    3.  `<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>`
    
    4.  `</dependency>`
    
    

    在这个jar包中,有一段源码:

    从源码我们可以看出,在没有配置fallback时,并没有向SentinelInvocationHandler构造方法中传入FallbackFactory。这样的话我们就有了思路:

    • 编写公共FallbackFactory

    • 改写SentinelFeign使得fallbackFactory为void.class时,我们传入自己的公共FallbackFactory实例

    让我们一起上代码吧!

    先定义全局的fallback处理器

    再定义一个全局的FallbackFactory

    再后面我们需要重新实现spring-cloud-starter-alibaba-sentinel下的SentinelFeign

    上面的代码其实是仿照SentinelFeign源码的,唯一的区别就是画上红色的框的。

    注意:其中有个方法setAccessible,这个是因为SentinelInvocationHandler的构造方法是私有方法。

    其实还有一种方案,就是把重写 的SentinelFeign类,放到com.alibaba.cloud.sentinel.feign包下,也就是在自己的项目中,新建com.alibaba.cloud.sentinel.feign包

    最后注入我们的SentinelFeign Bean

    注意:一定要在配置文件中配置feign.sentinel.enabled=true

    到这里就可以了,以后只要定义基本属性@FeignClient,不需要再配置fallBackFactory了哦。

    当然你还有特殊的需求,再自定义的可以了。

    总结

    通过此文章,小伙伴就可以更好的使用Sentinel了,更方便的编写统一的兜底方法了。如果有人使用dubbo时,sentinel也有对应的适配器;有空老顾再写一篇文章。谢谢!!!


    相关文章

      网友评论

        本文标题:程序员,你知道Sentinel限流、降级的统一处理吗?

        本文链接:https://www.haomeiwen.com/subject/vbcffktx.html