内容简介:网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡
摘要: 原创出处 http://www.iocoder.cn/Spring-Cloud-Gateway/filter-load-balancer-client/ 「芋道源码」欢迎转载,保留摘要,谢谢!
本文主要基于 Spring-Cloud-Gateway 2.0.X M4
关注 微信公众号:【芋道源码】 有福利:
- RocketMQ / MyCAT / Sharding-JDBC 所有 源码分析文章列表
- RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
- 您对于源码的疑问每条留言 都 将得到 认真 回复。 甚至不知道如何读源码也可以请教噢 。
- 新的 源码解析文章 实时 收到通知。 每周更新一篇左右 。
- 认真的 源码交流微信群。
1. 概述
本文主要分享 LoadBalancerClientFilter 的代码实现 。
LoadBalancerClientFilter 根据 lb://
前缀过滤处理,使用 serviceId
选择 一个 服务实例,从而实现 负载均衡 。
推荐 Spring Cloud 书籍:
- 请支持正版。下载盗版, 等于主动编写低级 BUG 。
- 程序猿DD —— 《Spring Cloud微服务实战》
- 周立 —— 《Spring Cloud与 Docker 微服务架构实战》
- 两书齐买,京东包邮。
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 的同学都知道,一般情况下 LoadBalancerClient 实现类为
- 第 39 至 45 行 :创建
requestUrl
。举个例子 : - 第 48 行 :设置
requestUrl
到GATEWAY_REQUEST_URL_ATTR
。后面 Routing 相关的 GatewayFilter 会通过该属性,发起请求。 - 第 51 行 :提交过滤器链继续过滤。 注意 ,这里不需要创建 新 的 ServerWebExchange
4. 高能
我们回过头看 《Spring-Cloud-Gateway 源码解析 —— 路由(1.4)之 DiscoveryClientRouteDefinitionLocator 注册中心》「4. 高能」
相同服务( serviceId
相同) ,服务实例的注册或下线,Ribbon 已经处理,所以不用担心。
666. 彩蛋
没有彩蛋,继续往下写!当然,《天才麻将少女》的福利还是有的!
胖友,分享一波朋友圈可好!
以上所述就是小编给大家介绍的《网关 Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Jboot v3.1.8 发布,新增门户网关动态配置和负载均衡
- NGINX访谈:软件负载均衡、API网关和服务网格的企业采用状况
- Soul 网关发布 2.2.0,让高性能网关变得如此简单!
- 远行API网关(200428)
- zuul网关实现解析
- 设计一个HTTP网关
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
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》 这本书的介绍吧!