网关 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 负载均衡》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

How to Build a Billion Dollar App

How to Build a Billion Dollar App

George Berkowski / Little, Brown Book Group / 2015-4-1 / USD 24.95

Apps have changed the way we communicate, shop, play, interact and travel and their phenomenal popularity has presented possibly the biggest business opportunity in history. In How to Build a Billi......一起来看看 《How to Build a Billion Dollar App》 这本书的介绍吧!

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

多种字符组合密码

MD5 加密
MD5 加密

MD5 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具