解决微服务网关Ocelot使用AddStoreOcelotConfigurationInConsul后请求404问题
一个小插曲,最近研究 netcore 微服务网关,在使用AddStoreOcelotConfigurationInConsul将配置存到consul后,任何经过网关的请求都出现404,并且没有任何有用的异常信息打印。这里先简单讲讲这个问题是如何发生的,及如何解决。
之前在 ASP.NET Core 2 学习笔记(三)中间件 提到过大部分扩展的Middleware都会用一个静态方法包装,如:UseMvc()、UseRewriter()等,而微服务网关Ocelot 包装了两个静态的异步方法 UseOcelot。
OcelotMiddlewareExtensions.cs
public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder)
{
await builder.UseOcelot(new OcelotPipelineConfiguration()); return builder;
} public static async Task<IApplicationBuilder> UseOcelot(this IApplicationBuilder builder, OcelotPipelineConfiguration pipelineConfiguration)
{
var configuration = await CreateConfiguration(builder); CreateAdministrationArea(builder, configuration); if(UsingRafty(builder))
{
SetUpRafty(builder);
} if (UsingEurekaServiceDiscoveryProvider(configuration))
{
builder.UseDiscoveryClient();
} ConfigureDiagnosticListener(builder); var pipelineBuilder = new OcelotPipelineBuilder(builder.ApplicationServices); pipelineBuilder.BuildOcelotPipeline(pipelineConfiguration); var firstDelegate = pipelineBuilder.Build(); /*
inject first delegate into first piece of asp.net middleware..maybe not like this
then because we are updating the http context in ocelot it comes out correct for
rest of asp.net..
*/ builder.Properties["analysis.NextMiddlewareName"] = "TransitionToOcelotMiddleware"; builder.Use(async (context, task) =>
{
var downstreamContext = new DownstreamContext(context);
await firstDelegate.Invoke(downstreamContext);
}); return builder;
}
为什么会封装成异步的方法,可能是因为从底层一步一步写上来的。但是我个人认为 UseOcelot 是完全可以封装成同步方法,以避免误用。
误用情形,如下:
Startup.cs
public async void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug(); if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} await app.UseOcelot();
}
这里将 Startup.Configure() 方法写成了一个不规范的异步方法,其实是不被支持的。但是由于不规范,绕过了检测。
规范写法,如下
Startup.cs
public async Task Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug(); if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} await app.UseOcelot();
}
检测到Configure返回类型非Void,直接异常:
System.InvalidOperationException:“The 'Configure' method in the type 'OcelotConsul.ApiGateway.Core.Startup' must have a return type of 'Void'.”
这里可以参考aspnet/Hosting关于Configure 异步问题的讨论:
由于用到了不规范的异步方法,使得线程并没有等待 UseOcelot 内部初始化完成就Host了起来,而造成了一些奇怪的异常,诸如:AddStoreOcelotConfigurationInConsul后请求404等问题。
解决方案就是用 Task.Wait() 方法 阻塞线程,等待 UseOcelot 执行完成,再Host。如下:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug(); if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseOcelot().Wait();
}
也许 UseOcelot 封装成同步方法会更好。已经给作者提了Issue
解决微服务网关Ocelot使用AddStoreOcelotConfigurationInConsul后请求404问题的更多相关文章
- 微服务网关Ocelot加入IdentityServer4鉴权-.NetCore(.NET5)中使用
Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Consul服务注册,服务发现 Consul+Ocelot+Polly在.NetCore中使用(.NET5)-网关Ocel ...
- Bumblebee微服务网关的部署和扩展
Bumblebee是.netcore下开源基于BeetleX.FastHttpApi扩展的HTTP微服务网关组件,它的主要作用是针对WebAPI集群服务作一个集中的转发和管理:作为应用网关它提供了应用 ...
- springcloud(十)-Zuul微服务网关
为什么要使用微服务网关 前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服 ...
- 微服务网关实战——Spring Cloud Gateway
导读 作为Netflix Zuul的替代者,Spring Cloud Gateway是一款非常实用的微服务网关,在Spring Cloud微服务架构体系中发挥非常大的作用.本文对Spring Clou ...
- 【SpringCloud构建微服务系列】微服务网关Zuul
一.为什么要用微服务网关 在微服务架构中,一般不同的微服务有不同的网络地址,而外部客户端(如手机APP)可能需要调用多个接口才能完成一次业务需求.例如一个电影购票的手机APP,可能会调用多个微服务的接 ...
- .net core中使用Bumblebee架设微服务网关
Bumblebee是款基于.net core开发开源的http服务网关,经过最近版本的完善在功能足以满足作为微服务网关的需要.在微服务网关功能中它提供了应用服务负载,故障迁移,安全控制,监控跟踪和日志 ...
- 王院生:Apache APISIX 微服务网关极致性能架构解析
2019 年 10 月 27 日,又拍云联合 Apache APISIX 社区举办 API 网关与高性能服务最佳实践丨Open Talk 杭州站活动,Apache APISIX PPMC 成员王院生做 ...
- 畅购商城(八):微服务网关和JWT令牌
好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 畅购商城(一):环境搭建 畅购商 ...
- SpringCloud Gateway微服务网关实战与源码分析-上
概述 定义 Spring Cloud Gateway 官网地址 https://spring.io/projects/spring-cloud-gateway/ 最新版本3.1.3 Spring Cl ...
随机推荐
- Oracle数据库迁移的几种方式
面试: 一.exp/imp逻辑备份与恢复: 二.Storage存储迁移: 将数据文件.控制文件.日志文件.spfile挂到新机器上,然后在新机器上启动数据库. 三.利用data guard迁移: 四. ...
- RigidBody组件的Is Kinematic
RigidBody组件的Is Kinematic属性打上勾(设为true,使其不受物理引擎驱动,Wall是为了防止其移动,Person是为了防止其受到力不断旋转—看的心塞=v=) .is kinema ...
- iOS 网络请求中的空类型字符串转换
创建一个工具类, .h: #import <Foundation/Foundation.h> @interface MySetNullWithStrTool : NSObject +( ...
- android环境安装及配置
直接从网上下载适合当前系统的jdk(eclipse需要一个java虚拟器的环境) 直接从android上下载最新的adt-bundle-windows-x86(64)-xxxxxx.zip(集成好的e ...
- VR
- Spring_AOP动态代理详解(转)
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- WCF生成客户端代理对象的两种方法的解释
最近在封装WCF,有一些很好的实践就记录下来,大家可以放心使用,所有代码都已经调试过.如果有高手可以大家探讨一下. 在WCF中有两种不同的方法可以用于创建客户端服务对象,他们分别为: 1. 代理构造法 ...
- loadrunner12.5-添加检查点
1.点击缩略图资源管理器,找到需要添加检查点的页面. 2.选中需要添加检查点的页面,切换到快照tab,选择“树”型显示方式. 3.在响应窗口下,找到需要添加的检查点的内容,选中--右键--添加文本检查 ...
- JAVA Get UUID
UUID是通用唯一标识码(Universally Unique Identifier),通过开源软件基金会(OSF)设立的一种算法生成.它的主要作用就是保证生成的字符串在同一时空中所有机器上都是唯一的 ...
- tmux配置与用法整理
tmux常用命令与快捷键 http://www.111cn.net/sys/linux/59058.htm http://www.360doc.com/content/13/0709/13/13047 ...