乐趣区

关于java:Soul网关探秘springcloud插件原理

一、插件概述

插件定位

springcloud 插件是一个 springcloud 正向代理插件,所有的 springcloud 申请都由该插件进行负载平衡解决。

失效机会

当申请头的 rpcType = springcloud 且插件启用时,它将依据申请参数匹配规定,最终交由上游插件进行响应式代理调用。

二、插件解决流程

1)先回顾下申请解决类插件的通用流程(AbstractSoulPlugin # execute):

public Mono<Void> execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
    // 获取插件数据
    String pluginName = named();
    final PluginData pluginData = BaseDataCache.getInstance().obtainPluginData(pluginName);
    // 插件失效断定
    if (pluginData != null && pluginData.getEnabled()) {
        // 获取选择器数据
        final Collection<SelectorData> selectors = BaseDataCache.getInstance().obtainSelectorData(pluginName);
        ...
        // 匹配选择器
        final SelectorData selectorData = matchSelector(exchange, selectors);
        ...
        // 获取规定数据
        final List<RuleData> rules = BaseDataCache.getInstance().obtainRuleData(selectorData.getId());
        ...
        // 匹配规定
        RuleData rule;
        if (selectorData.getType() == SelectorTypeEnum.FULL_FLOW.getCode()) {
            //get last
            rule = rules.get(rules.size() - 1);
        } else {rule = matchRule(exchange, rules);
        }
        ...
        // 执行自定义解决
        return doExecute(exchange, chain, selectorData, rule);
    }
    // 继续执行插件链解决
    return chain.execute(exchange);
}

AbstractSoulPlugin 判断插件是否存在且启用:

  • 判断通过,则开始执行该插件解决

    1. 匹配选择器
    2. 匹配规定
    3. 执行自定义解决
  • 否则,继续执行插件链解决。

2)再来看看 springcloud 插件的自定义解决流程(SpringCloudPlugin # doExecute):

protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
    ...
    // 获取规定解决对象
    final SpringCloudRuleHandle ruleHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), SpringCloudRuleHandle.class);
    // 获取选择器解决对象
    final SpringCloudSelectorHandle selectorHandle = GsonUtils.getInstance().fromJson(selector.getHandle(), SpringCloudSelectorHandle.class);
    ...
    // 负载均衡器抉择服务实例
    final ServiceInstance serviceInstance = loadBalancer.choose(selectorHandle.getServiceId());
    ...
    // 重建 URI
    final URI uri = loadBalancer.reconstructURI(serviceInstance, URI.create(soulContext.getRealUrl()));
    // 生成实在的 URL
    String realURL = buildRealURL(uri.toASCIIString(), soulContext.getHttpMethod(), exchange.getRequest().getURI().getQuery());
    // 设置实在 url 和超时工夫
    exchange.getAttributes().put(Constants.HTTP_URL, realURL);
    exchange.getAttributes().put(Constants.HTTP_TIME_OUT, ruleHandle.getTimeout());
    // 继续执行插件链解决
    return chain.execute(exchange);
}

SpringCloudPlugin 先获取到选择器解决对象,而后应用负载均衡器依据解决对象的服务 id 抉择服务实例并重建 URI,据此 URI 生成实在的 URL,最初设置最终的 url 和超时工夫交由插件链上游进行解决。

留神:

springcloud 插件本身只是负责依据选择器、规定和注入的负载均衡器选出待散发的服务器实例,并不间接向后端服务发动申请。

三、负载均衡器

springcloud 插件在处理过程中,插件自身并不承当如 divide 插件个别的探活和负载平衡的职责,而是交由一个负载均衡器去解决。

该负载均衡器须要实现 org.springframework.cloud.client.loadbalancer.LoadBalancerClient,官网应用的是 org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient。

3.1 Ribbon 是什么?

Ribbon 是 Netflix 公布的一个开源的客户端负载均衡器,是 SpringCloud-Netflix 中重要的一环,通过它将 Netflix 的中间层服务连贯在一起。
Ribbon 客户端组件提供一系列欠缺的配置项,如连贯超时、重试等。简略的说,就是在配置文件中列出 Load Balancer 前面所有的服务,Ribbon 会主动的基于某种规定(如简略轮询,随机连贯等)去连贯这些服务,也很容易实现自定义的负载平衡算法。

3.2 Ribbon 能干什么?

Ribbon 是在客户端来实现负载平衡的拜访服务,次要的性能:

  • 服务发现,发现依赖服务的列表
  • 服务抉择规定,在多个服务中如何抉择一个无效服务
  • 服务监听,检测生效的服务,高效剔除生效服务

3.3 Ribbon 在插件中的职责

通过集成 ribbon,springcloud 插件能够轻易地实现 springcloud 服务的服务发现及负载平衡策略。

在 springcloud 插件中,ribbon 次要承当以下职责:

  • 服务发现:主动发现依赖的服务列表
  • 服务监听:主动剔除生效服务,保护无效服务列表
  • 服务抉择:依据某种规定抉择一个无效服务(负载平衡)

四、小结

springcloud 插件通过负载均衡器,实现了对 springcloud 服务的负载平衡,抉择出一个无效服务的实在 URL 后,交由插件链上游进行解决。

负载均衡器是 springcloud 插件中至关重要的一环,插件的负载均衡器默认应用 ribbon 实现。

退出移动版