H5W3
当前位置:H5W3 > java > 正文

【Java】【Soul网关探秘】springcloud插件原理

【Soul网关探秘】springcloud插件原理

腾业发布于 2 月 4 日

一、插件概述

插件定位

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 实现。

java分布式soul
阅读 12发布于 2 月 4 日
本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
avatar

腾业
1 声望
0 粉丝

0 条评论
得票时间

avatar

腾业
1 声望
0 粉丝

宣传栏

一、插件概述

插件定位

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 实现。

本文地址:H5W3 » 【Java】【Soul网关探秘】springcloud插件原理

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址