网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡

栏目: Java · 发布时间: 6年前

内容简介:网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡

摘要: 原创出处 http://www.iocoder.cn/Spring-Cloud-Gateway/filter-load-balancer-client/ 「芋道源码」欢迎转载,保留摘要,谢谢!

本文主要基于 Spring-Cloud-Gateway 2.0.X M4

网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡

关注 微信公众号:【芋道源码】 有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有 源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言 将得到 认真 回复。 甚至不知道如何读源码也可以请教噢
  4. 新的 源码解析文章 实时 收到通知。 每周更新一篇左右
  5. 认真的 源码交流微信群。

1. 概述

本文主要分享 LoadBalancerClientFilter 的代码实现

LoadBalancerClientFilter 根据 lb:// 前缀过滤处理,使用 serviceId 选择 一个 服务实例,从而实现 负载均衡

推荐 Spring Cloud 书籍:

2. 环境搭建

《Spring-Cloud-Gateway 源码解析 —— 路由(1.4)之 DiscoveryClientRouteDefinitionLocator 注册中心》「2. 环境搭建」 有详细教程。

3. LoadBalancerClientFilter

org.springframework.cloud.gateway.filter.LoadBalancerClientFilter ,代码如下 :

 1: public class LoadBalancerClientFilter implements GlobalFilter, Ordered{
 2: 
 3: private static final Log log = LogFactory.getLog(LoadBalancerClientFilter.class);
 4: public static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10100;
 5: 
 6: private final LoadBalancerClient loadBalancer;
 7: 
 8: public LoadBalancerClientFilter(LoadBalancerClient loadBalancer){
 9: this.loadBalancer = loadBalancer;
10: }
11: 
12: @Override
13: public int getOrder(){
14: return LOAD_BALANCER_CLIENT_FILTER_ORDER;
15: }
16: 
17: @Override
18: public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
19: // 获得 URL
20: URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
21: if (url == null || !url.getScheme().equals("lb")) {
22: return chain.filter(exchange);
23: }
24: // 添加 原始请求URI 到 GATEWAY_ORIGINAL_REQUEST_URL_ATTR
25: //preserve the original url
26: addOriginalRequestUrl(exchange, url);
27: 
28: log.trace("LoadBalancerClientFilter url before: " + url);
29: 
30: // 获取 服务实例
31: final ServiceInstance instance = loadBalancer.choose(url.getHost());
32: if (instance == null) {
33: throw new NotFoundException("Unable to find instance for " + url.getHost());
34: }
35: 
36: /*URI uri = exchange.getRequest().getURI();
37: URI requestUrl = loadBalancer.reconstructURI(instance, uri);*/
38: //
39: URI requestUrl = UriComponentsBuilder.fromUri(url)
40: .scheme(instance.isSecure()? "https" : "http") //TODO: support websockets
41: .host(instance.getHost())
42: .port(instance.getPort())
43: .build(true)
44: .toUri();
45: log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
46: 
47: // 添加 请求URI 到 GATEWAY_REQUEST_URL_ATTR
48: exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
49: 
50: // 提交过滤器链继续过滤
51: return chain.filter(exchange);
52: }
53: 
54: }
  • 第 19 至 23 行 :获得 URL 。 只处理 lb:// 为前缀( Scheme )的地址
  • 第 第 26 行 :调用 ServerWebExchangeUtils#addOriginalRequestUrl(...) 添加原始请求 URI 到 GATEWAY_ORIGINAL_REQUEST_URL_ATTR 。代码如下 :

    public static void addOriginalRequestUrl(ServerWebExchange exchange, URI url){
     exchange.getAttributes().computeIfAbsent(GATEWAY_ORIGINAL_REQUEST_URL_ATTR, s -> new LinkedHashSet<>()); // 数组,考虑多次重写
     LinkedHashSet<URI> uris = exchange.getRequiredAttribute(GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
     uris.add(url);
    }
    
    • 为什么使用 LinkedHashSet ?因为可以使用 RewritePathGatewayFilterFactory / PrefixPathGatewayFilterFactory 多次重写。
  • 第 30 至 34 行 :调用 LoadBalancerClient#choose(String) 方法,获得 一个 服务实例( ServiceInstance ) ,从而实现 负载均衡

    • 熟悉 Spring Cloud 的同学都知道,一般情况下 LoadBalancerClient 实现类为 org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient
    • 举个 instance 例子 : 网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡
  • 第 39 至 45 行 :创建 requestUrl 。举个例子 : 网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡
  • 第 48 行 :设置 requestUrlGATEWAY_REQUEST_URL_ATTR 。后面 Routing 相关的 GatewayFilter 会通过该属性,发起请求。
  • 第 51 行 :提交过滤器链继续过滤。 注意 ,这里不需要创建 的 ServerWebExchange

4. 高能

我们回过头看 《Spring-Cloud-Gateway 源码解析 —— 路由(1.4)之 DiscoveryClientRouteDefinitionLocator 注册中心》「4. 高能」

相同服务( serviceId 相同) ,服务实例的注册或下线,Ribbon 已经处理,所以不用担心。

666. 彩蛋

没有彩蛋,继续往下写!当然,《天才麻将少女》的福利还是有的!

网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡

胖友,分享一波朋友圈可好!


以上所述就是小编给大家介绍的《网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

PHP经典实例

PHP经典实例

(美)斯克拉、(美)切贝特伯格 / 李松峰、秦绪文、李丽 / 中国电力出版社 / 2009-10 / 98.00元

PHP经典实例(第2版)能够为您节省宝贵的Web开发时间。有了这些针对真实问题的解决方案放在手边,大多数编程难题都会迎刃而解。《PHP经典实例(第2版)》将PHP的特性与经典实例丛书的独特形式组合到一起,足以帮您成功地构建跨浏览器的Web应用程序。在这个修订版中,您可以更加方便地找到各种编程问题的解决方案,《PHP经典实例(第2版)》中内容涵盖了:表单处理;Session管理;数据库交互;使用We......一起来看看 《PHP经典实例》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码