zoukankan      html  css  js  c++  java
  • 阿里Sentinel整合Zuul网关详解

    前面我们讲解了Sentinel整合Spring Cloud Gateway,详细请查看文章:阿里Sentinel支持Spring Cloud Gateway啦

    目前来说,大部分公司线上的网关应该是Zuul,所以今天我们就来看看如何在Zuul中整合Sentinel。本来想基于Spring Cloud Alibaba来进行整合讲解,整合的时候发现目前还没更新版本,依赖还是之前的版本,咱们就以最原生的方式进行整合吧,等Spring Cloud Alibaba更新之后,Sentinel的整合只会变得更简单。

    加入zuul-adapter依赖:

    <dependency>
    	<groupId>com.alibaba.csp</groupId>
    	<artifactId>sentinel-zuul-adapter</artifactId>
    	<version>1.6.0</version>
    </dependency>
    

    配置Sentinel提供的限流过滤器和限流规则:

    @Configuration
    public class ZuulConfig {
    
    	@Bean
    	public ZuulFilter sentinelZuulPreFilter() {
    		return new SentinelZuulPreFilter();
    	}
    
    	@Bean
    	public ZuulFilter sentinelZuulPostFilter() {
    		return new SentinelZuulPostFilter();
    	}
    
    	@Bean
    	public ZuulFilter sentinelZuulErrorFilter() {
    		return new SentinelZuulErrorFilter();
    	}
    
    	@PostConstruct
    	public void doInit() {
    		// 注册 FallbackProvider
    		ZuulBlockFallbackManager.registerProvider(new MyBlockFallbackProvider());
    		initGatewayRules();
    	}
    
    	/**
    	 * 配置限流规则
    	 */
    	private void initGatewayRules() {
    		Set<GatewayFlowRule> rules = new HashSet<>();
    		rules.add(new GatewayFlowRule("yinjihuan").setCount(1) // 限流阈值
    				.setIntervalSec(1) // 统计时间窗口,单位是秒,默认是 1 秒
    		);
    
    		GatewayRuleManager.loadRules(rules);
    	}
    }
    
    • SentinelZuulPreFilter
      pre过滤器,在请求路由之前匹配routeId和api,进行限流操作
    • SentinelZuulPostFilter
      post过滤器,路由之后恢复资源
    • SentinelZuulErrorFilter
      error过滤器,异常后的处理

    最后再配置一个简单的路由,路由名称yinjihuan,跟上面规则中的名称一致:

    zuul.routes.yinjihuan.path=/cxytiandi/**
    zuul.routes.yinjihuan.url=http://cxytiandi.com
    

    触发限流后会返回固定的提示:

    {
        "code":429,
        "message":"Sentinel block exception",
        "route":"yinjihuan"
    }
    

    如果想修改提示内容可以自己实现ZuulBlockFallbackProvider接口,框架默认提供的实现是DefaultBlockFallbackProvider,源码如下:

    public class DefaultBlockFallbackProvider implements ZuulBlockFallbackProvider {
    
        @Override
        public String getRoute() {
            return "*";
        }
    
        @Override
        public BlockResponse fallbackResponse(String route, Throwable cause) {
            if (cause instanceof BlockException) {
                return new BlockResponse(429, "Sentinel block exception", route);
            } else {
                return new BlockResponse(500, "System Error", route);
            }
        }
    }
    

    用法其实跟Zuul中的FallbackProvider一致,但是FallbackProvider比较好的是返回的ClientHttpResponse,我们可以自定义响应内容。

    Sentinel提供的ZuulBlockFallbackProvider接口中定义的返回对象是BlockResponse ,也就意味着限制了响应的字段,BlockResponse中有code,message,route三个字段,如果我想返回status, msg这两个字段目前我没找到其它的方式,不知道后续会不会支持,其实最好的是也返回ClientHttpResponse,这样就可以自定义响应内容了。

    这边有个小插曲,就是我们自定义fallbackResponse的时候如果用中文message的话,响应内容是乱码,如下:

    {
    code: 429,
    message: "??????",
    route: "yinjihuan"
    }
    

    我看了下SentinelZuulPreFilter中的代码,如下:

    这边是构造了BlockResponse,然后设置到ResponseBody中,但是没有进行编码设置,我自己改了下源码,加了一行代码:

      ctx.getResponse().setContentType("application/json; charset=utf-8");
    

    加了上面的代码后,中文就不会乱码了,效果如下:

    {
    code: 429,
    message: "访问太频繁啦",
    route: "yinjihuan"
    }
    

    不说了,我还是去提个issues吧: https://github.com/alibaba/Sentinel/issues/733

    欢迎加入我的知识星球,一起交流技术,免费学习猿天地的课程(http://cxytiandi.com/course)

    PS:目前星球中正在星主的带领下组队学习Spring Cloud,等你哦!

    微信扫码加入猿天地知识星球

    猿天地

  • 相关阅读:
    预处理与编译阶段
    联合体
    linux shell
    二维数组、字符数组、指针数组涉及字符串和具体元素问题
    二级指针的简单运用
    halcon算子翻译——get_image_type
    halcon算子翻译——get_image_time
    halcon算子翻译——get_image_size
    Halcon算子翻译——get_image_pointer3
    Halcon算子翻译——get_image_pointer1_rect
  • 原文地址:https://www.cnblogs.com/yinjihuan/p/10842522.html
Copyright © 2011-2022 走看看