Sentinel 整合zuul

加入zuul-adapter依赖:


    com.alibaba.csp
    sentinel-zuul-adapter
    1.6.0

配置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 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

如果想修改提示内容可以自己实现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中的代码,如下:
Sentinel 整合zuul_第1张图片
这边是构造了BlockResponse,然后设置到ResponseBody中,但是没有进行编码设置,我自己改了下源码,加了一行代码:

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

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

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

你可能感兴趣的:(sentinel,spring-cloud,java)