soul源码学习(十一)-divide插件分析

探活机制分析

探活即用来和后端代理的相关服务进行心跳检测,以确定其是否能够进行正常服务,由于该部分功能不在整个调用链上,因此首先进行分析

  1. 探活服务默认在soul-admin开启,相关类为UpstreamCheckService,在该类被spring自动装配后,会进行启动线程对后端服务进行检查,默认每隔10s检查一次
    在这里插入图片描述
    检查时,如果发现服务不可用时,则会从数据库将该服务剔除,并且发布相关事件,通过数据同步至网关,网关收到后,会同步缓存中相关服务,相关关键代码如下:
private void check(final String selectorName, final List<DivideUpstream> upstreamList) {
        List<DivideUpstream> successList = Lists.newArrayListWithCapacity(upstreamList.size());
        for (DivideUpstream divideUpstream : upstreamList) {//会逐个判断代理的服务
            final boolean pass = UpstreamCheckUtils.checkUrl(divideUpstream.getUpstreamUrl());//通过socket探活
            if (pass) {
               //前后代码省略
                successList.add(divideUpstream);
            }
            //代码省略,
        if (successList.size() == upstreamList.size()) {
            return;
        }
        if (successList.size() > 0) {
            UPSTREAM_MAP.put(selectorName, successList);
            updateSelectorHandler(selectorName, successList);
        } else {
            UPSTREAM_MAP.remove(selectorName);
            updateSelectorHandler(selectorName, null);//更新数据库,并发布相关事件
        }
    }

在网关侧,通过CommonPluginDataSubscriber中的subscribeDataHandler方法根据相关操作事件分发至DividePluginDataHandler中的相关方法中,
在这里插入图片描述关键类UpstreamCacheManager,该类主要作用是更新或删除网关内存中对应的代理服务,该类中同样也存在探活检测,默认30s,但是不开启,探活过程大致与soul-admin一致,不同的是,采用了双map缓存机制,一个保存全量代理,一个保存活的代理放在临时map中,这样设计应该是保证网络有问题时,摘除服务,故障排除后会再次加入。soul-admin如遇故障必须重启后才能加入。一般情况下探活机制只用在soul-admin开启就行,减轻网关压力

调用链分析

url请求过来后,在soul中的相关入口处为SoulWebHandler类,soul-admin默认会引入大部分插件,插件通过boot-starter最终会被注入进SoulWebHandler类中,关键代码
在这里插入图片描述
前后加入的是监控相关的代码,暂时不分析,主要看DefaultSoulPluginChain类,为内部类,插件执行链在该类的方法中
在这里插入图片描述
可以看出,该方法是按照调用链根据相关条件会一直往下调用,插件调用时是具有顺序的,插件顺序在PluginEnum类中

public enum PluginEnum {
    GLOBAL(1, 0, "global"),
    SIGN(2, 0, "sign"),
    WAF(10, 0, "waf"),
    RATE_LIMITER(20, 0, "rate_limiter"),
    CONTEXTPATH_MAPPING(25, 0, "context_path"),
    REWRITE(30, 0, "rewrite"),
    REDIRECT(40, 0, "redirect"),
    HYSTRIX(45, 0, "hystrix"),
    SENTINEL(45, 0, "sentinel"),  
    RESILIENCE4J(45, 0, "resilience4j"),
    DIVIDE(50, 0, "divide"),
    SPRING_CLOUD(50, 0, "springCloud"),

根据插件顺序可以发现,先走的是global插件,全局插件,该插件会做一些通用处理,区分请求的协议,并存储在上下文中,供后续插件使用,代码不再贴出,现在直接分析divide插件,注意divide插件和springclcoud插件的顺序是一致的,这点很关键,先看divide插件处理链
在这里插入图片描述
该方法为divide插件入口核心方法,主要作用是从缓存中拿到后端代理,通过负载均衡拿到对应的url,并将相关信息put到exchange中,供后续插件使用,那么是哪个插件来负责发起代理请求,经过分析可知下一个插件是soul-plugin-httpcient插件,有两种实现,WebClientPlugin和NettyHttpClient,默认使用WebClientPlugin,主要该插件的顺序:
在这里插入图片描述
会紧跟着divide插件,该插件负责具体发起代理请求,由于springcloud和divide插件都需要被代理请求,这也就解释了springcloud和divide插件的顺序为什么是一致的,而且需要在soul-plugin-httpcient插件前边。后续流程之后再分析

负载均衡算法

divide插件提供了三种负载均衡算法

  1. HashLoadBalance(hash算法)
  2. RandomLoadBalance(随机算法)
  3. RoundRobinLoadBalance(轮询算法)
    通过spi机制注入,soul自定义了加载spi的相关类ExtensionLoader,具体相关实现过程后续分析

与springcloud调用对比

springcloud与divide插件处理过程基本一致,这里贴出相关代码
在这里插入图片描述
不同的点是画红线处,divide插件的后端代理直接注册在soul-admin上,网关可以直接拿到并通过均衡负载算出,springcloud的网关拿不到,只能通过springcloud提供的相关负载均衡客户端方法去相关注册中心去拿到相关的服务,并获取相关url等信息放到exchange中,后续流程与divide插件一致

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值