nacos+gateway服务发现lb路由报503 Service Unavailable
问题产生背景
使用 Nacos 作为注册中心,gateway 作为网关,网关通过lb的方式进行服务路由,在网关报503服务不可用Service Unavailable。
现象版本
SpringCloud2020.0.3
Nacos 1.4.1
深入问题
是因为 ReactiveLoadBalancerClientFilter
全局过滤器没有加载。官方对其的解释是:
The ReactiveLoadBalancerClientFilter looks for a URI in the exchange attribute named ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR. If the URL has a lb scheme (such as lb://myservice), it uses the Spring Cloud ReactorLoadBalancer to resolve the name (myservice in this example) to an actual host and port and replaces the URI in the same attribute. The unmodified original URL is appended to the list in the ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR attribute. The filter also looks in the ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR attribute to see if it equals lb. If so, the same rules apply.
大概意思是 将请求过来的 URL 是 LB 方式的通过从服务注册中心获取到服务配置,并将原来未修改的 URL 中的 IP 和 端口解析为目标服务的。截取部分 ReactiveLoadBalancerClientFilter
过滤器代码:
URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);if (url == null || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {// 不是 lb 的方式直接出去return chain.filter(exchange);}// preserve the original urladdOriginalRequestUrl(exchange, url);if (log.isTraceEnabled()) {log.trace(ReactiveLoadBalancerClientFilter.class.getSimpleName() + " url before: " + url);}URI requestUri = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);String serviceId = requestUri.getHost();Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator.getSupportedLifecycleProcessors(clientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),RequestDataContext.class, ResponseData.class, ServiceInstance.class);// 构造 lb 的请求 DefaultRequest<RequestDataContext> lbRequest = new DefaultRequest<>(new RequestDataContext(new RequestData(exchange.getRequest()), getHint(serviceId, loadBalancerProperties.getHint())));// 获取服务中心配置并解析真正的地址return choose(lbRequest, serviceId, supportedLifecycleProcessors).doOnNext(response -> {if (!response.hasServer()) {supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.DISCARD, lbRequest, response)));throw NotFoundException.create(properties.isUse404(), "Unable to find instance for " + url.getHost());}ServiceInstance retrievedInstance = response.getServer();URI uri = exchange.getRequest().getURI();// if the `lb:<scheme>` mechanism was used, use `<scheme>` as the default,// if the loadbalancer doesn't provide one.String overrideScheme = retrievedInstance.isSecure() ? "https" : "http";if (schemePrefix != null) {overrideScheme = url.getScheme();}DelegatingServiceInstance serviceInstance = new DelegatingServiceInstance(retrievedInstance,overrideScheme);URI requestUrl = reconstructURI(serviceInstance, uri);if (log.isTraceEnabled()) {log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);}exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);exchange.getAttributes().put(GATEWAY_LOADBALANCER_RESPONSE_ATTR, response);supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, response));}).then(chain.filter(exchange)).doOnError(throwable -> supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<ResponseData, ServiceInstance, RequestDataContext>(CompletionContext.Status.FAILED, throwable, lbRequest,exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR))))).doOnSuccess(aVoid -> supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<ResponseData, ServiceInstance, RequestDataContext>(CompletionContext.Status.SUCCESS, lbRequest,exchange.getAttribute(GATEWAY_LOADBALANCER_RESPONSE_ATTR),new ResponseData(exchange.getResponse(), new RequestData(exchange.getRequest()))))));
其次,取决于是否加载 ReactiveLoadBalancerClientFilter
的是类 GatewayReactiveLoadBalancerClientAutoConfiguration
中关键代码:
@Bean@ConditionalOnBean(LoadBalancerClientFactory.class)@ConditionalOnMissingBean(ReactiveLoadBalancerClientFilter.class)@ConditionalOnEnabledGlobalFilterpublic ReactiveLoadBalancerClientFilter gatewayLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory,GatewayLoadBalancerProperties properties, LoadBalancerProperties loadBalancerProperties) {return new ReactiveLoadBalancerClientFilter(clientFactory, properties, loadBalancerProperties);}
上述源代码中类 LoadBalancerClientFactory
是包 spring-cloud-loadbalancer
的,所以如果缺少则不会注入过滤器 ReactiveLoadBalancerClientFilter
。
如此简单的解决方案
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
nacos+gateway服务发现lb路由报503 Service Unavailable相关推荐
- 解决gateway使用nacos重启报503 Service Unavailable问题
问题描述 项目使用spring cloud gateway作为网关,nacos作为微服务注册中心,项目搭建好后正常访问都没问题,但是有个很烦人的小瑕疵: 当某个微服务重启后,通过网关调用这个服务时有时 ...
- 网页报503 service unavailable错误怎么解决
有时候访问某些互联网网页时会出现"503 service unavailable"的错误提示,造成503 error的原因并不止一个,针对不同的情况有不同的解决办法.下面介绍一下面 ...
- 《Nacos(2) - 服务发现》
<Nacos(2) - 服务发现> 提示: 本材料只做个人学习参考,不作为系统的学习流程,请注意识别!!! <Nacos-服务发现> <Nacos(2) - 服务发现&g ...
- nacos的服务发现详解
Nacos源码系列整体栏目 [一]nacos服务注册底层源码详解 [二]nacos服务发现底层源码详解 [三]nacos的心跳机制底层源码详解 [四]nacos配置中心的底层源码详解 nacos的服务 ...
- VCSA 上的 vmware-vpxd 服务失败,Web端提示503 服务不可用 (503 Service Unavailable)
昨晚VCSA碰到一个很诡异的问题: 使用 vSphere Web Client 连接到 vCenter Server Appliance时失败,提示: 503 服务不可用 (503 Service U ...
- VCSA访问web报错 503 Service Unavailable
问题描述: 运行好好的VCSA突然无法访问,web页面报错: 503 Service Unavailable (Failed to connect to endpoint: [[N7Vmacore4H ...
- 转)VCSA 6.5重启无法访问,报错“503 Service Unavailable”的解决方法
转)VCSA 6.5重启无法访问,报错"503 Service Unavailable"的解决方法 1. 问题 重启vcenter,登陆vsphere client,提示 &quo ...
- ESXi 6.7 的https服务挂掉处理方法 503 Service Unavailable (Failed to connect to endpoint: [N7Vmacore4Http16Loc
ESXi 6.7 的https服务挂掉处理方法 503 Service Unavailable (Failed to connect to endpoint: [N7Vmacore4Http16Loc ...
- apache php 503,宝塔linux面板 apache网站访问报错503 Service Unavailable解决
宝塔linux面板 apache网站访问报错: 503 Service Unavailable Service Unavailable The server is temporarily unable ...
最新文章
- docker安装kafka消息队列
- kset_create_and_add
- 老生常谈--GetROProperty,GetTOProperty,SetTOProperty的区别
- C#生成CHM文件(应用篇)之代码库编辑器(5)【总结、程序、源代码】
- Hystrix配置参数查找方式
- mysql数据库密码错误_MySQL数据库经典错误六 数据库密码忘记的问题
- 最好浏览器_Windows最好的浏览器!只有你想不到,没有它做不到
- 【翻译】IdentityServer4:基于资源的配置
- IJCAI 2019 融合角色信息的多样性对话生成
- 经典算法归纳(c语言)
- Pygame实战之外星人入侵NO.12——点击按钮开始游戏
- 柏诚股份冲刺上交所:年营收27.4亿 拟募资4.7亿
- python实现王者荣耀游戏框架
- html + layui 打开word文档
- 川信计算机组装维护,凉山州中学生技能大赛信息技术类竞赛总结
- 3、需求调研 - 产品管理系列文章
- 又是一年总结时-2007年总结及2008年计划
- 奥斯汀大学计算机专业怎么样,美国计算机专业大学排名是怎样的?
- MyDockFinder Steam版的新增功能和下载
- 浮点数陷阱——小数计算时与主观感觉不相符的异常