【Sentinel-1.8.6】 基于生产实践遇到的坑

最近基于sentinel-1.8.6搭建了一套供生产使用。在开发的过程中遇到了一些问题并进行了改造,在此记录一下。

1、http访问支持ip级别限流

如果是基于servlet容器的,可以手动复制com.alibaba.csp.sentinel.adapter.servlet.CommonFilter,自定义一个filter,加载自定义的filter,重写com.alibaba.csp.sentinel.adapter.servlet.CommonFilter#parseOrigin方法

private String parseOrigin(HttpServletRequest request) {
    
    
        String origin = IPUtils.getIpAddress(request);
        if (StringUtil.isEmpty(origin)) {
    
    
            return EMPTY_ORIGIN;
        }
        return origin;
    }

如果是springmvc

@Configuration
public class SentinelInterceptorConfig extends WebMvcConfigurerAdapter {
    
    

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        // Add Sentinel interceptor
        addSpringMvcInterceptor(registry);
    }

    private void addSpringMvcInterceptor(InterceptorRegistry registry) {
    
    
        SentinelWebMvcConfig config = new SentinelWebMvcConfig();
        config.setBlockExceptionHandler(new CustomBlockExceptionHandler());
        config.setHttpMethodSpecify(true);
        config.setWebContextUnify(true);
        //设置来源解析
        config.setOriginParser(request -> {
    
    
            //针对IP解析
            return IPUtils.getIpAddress(request);
        });
        // Add sentinel interceptor
        registry.addInterceptor(new SentinelWebInterceptor(config)).addPathPatterns("/**");
    }
}

2、热点参数、授权规则,数据结构不一致的情况

在原有的内存方式实现,dashboard会通过调用接口方式将rule传递到客户端,

com.gongdao.csp.sentinel.dashboard.client.SentinelApiClient#executeCommand(java.lang.String, java.lang.String, int, java.lang.String, java.util.Map<java.lang.String,java.lang.String>, boolean)

但是生产lz使用的是push模式,规则配置持久化至nacos,因此也就序列化了AuthorityRuleEntity这个实体,后来发现,授权规则,热点参数,与其他流控,熔断,系统保护规则不一致,授权/热点参数对应的序列化entity中存在rule字段,客户端进行反序列化的entity是对应的rule实体是没有rule字段,会导致rule字段丢失。

最小的改造成本就是在dashboard中保存热点参数规则以及授权规则的时候,将rule字段内的内容提升至最外围的entity字段层级(即模仿流控,熔断的实现方式)。

在dashboard的页面回显/传参等操作上也要处理。

3、实体id的持久化

在进行respository.save()方法时,会生成对应id,内存实现是维护了一个atomic,如果应用重启,会导致id丢失错乱的情况。

改造方法可以选择集中式持久化,比如db,redis等方式

猜你喜欢

转载自blog.csdn.net/qq_31426247/article/details/128389516