一个小插曲,最近研究 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 异步问题的讨论:

aspnet/Hosting#27

aspnet/Hosting#29

aspnet/Hosting#373

aspnet/Hosting#1088

由于用到了不规范的异步方法,使得线程并没有等待 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问题的更多相关文章

  1. 微服务网关Ocelot加入IdentityServer4鉴权-.NetCore(.NET5)中使用

    Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Consul服务注册,服务发现 Consul+Ocelot+Polly在.NetCore中使用(.NET5)-网关Ocel ...

  2. Bumblebee微服务网关的部署和扩展

    Bumblebee是.netcore下开源基于BeetleX.FastHttpApi扩展的HTTP微服务网关组件,它的主要作用是针对WebAPI集群服务作一个集中的转发和管理:作为应用网关它提供了应用 ...

  3. springcloud(十)-Zuul微服务网关

    为什么要使用微服务网关 前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服 ...

  4. 微服务网关实战——Spring Cloud Gateway

    导读 作为Netflix Zuul的替代者,Spring Cloud Gateway是一款非常实用的微服务网关,在Spring Cloud微服务架构体系中发挥非常大的作用.本文对Spring Clou ...

  5. 【SpringCloud构建微服务系列】微服务网关Zuul

    一.为什么要用微服务网关 在微服务架构中,一般不同的微服务有不同的网络地址,而外部客户端(如手机APP)可能需要调用多个接口才能完成一次业务需求.例如一个电影购票的手机APP,可能会调用多个微服务的接 ...

  6. .net core中使用Bumblebee架设微服务网关

    Bumblebee是款基于.net core开发开源的http服务网关,经过最近版本的完善在功能足以满足作为微服务网关的需要.在微服务网关功能中它提供了应用服务负载,故障迁移,安全控制,监控跟踪和日志 ...

  7. 王院生:Apache APISIX 微服务网关极致性能架构解析

    2019 年 10 月 27 日,又拍云联合 Apache APISIX 社区举办 API 网关与高性能服务最佳实践丨Open Talk 杭州站活动,Apache APISIX PPMC 成员王院生做 ...

  8. 畅购商城(八):微服务网关和JWT令牌

    好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 畅购商城(一):环境搭建 畅购商 ...

  9. SpringCloud Gateway微服务网关实战与源码分析-上

    概述 定义 Spring Cloud Gateway 官网地址 https://spring.io/projects/spring-cloud-gateway/ 最新版本3.1.3 Spring Cl ...

随机推荐

  1. Redis网络协议

    Redis网络协议较为简单,易于阅读. 命令或数据已\r\n结尾,但除了状态回复,其他数据都是二进制安全的(包含长度) 头部如下: + 正确的状态信息,具体信息是当前行+后面的字符. -  一条错误信 ...

  2. Unable to get the default Bean Validation factory

    前几天看了一下教程 ,自己试着配置了一下web下的hibernate,悲剧的时,出错了提示下面: 信息: Hibernate Validator bean-validator-3.0-JBoss-4. ...

  3. php Pthread 多线程 (一) 基本介绍

    我们可以通过安装Pthread扩展来让PHP支持多线程.   线程,有时称为轻量级进程,是程序执行的最小单元.线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,它与同属 ...

  4. dede中arcurl的解析

    有时候我们需要在dede中通过$dsql查询出文章数据,并生成文章的地址. 但是dede默认的dede_archives和附加表dede_addonarticle都没有存放arcurl的字段. 说明a ...

  5. windows 10 WSL 安装 Centos

    1. 打开 WSL,没啥好说的 使用管理员权限打开 powershell,执行 Enable-WindowsOptionalFeature -Online -FeatureName Microsoft ...

  6. DNA binding motif比对算法

    DNA binding motif比对算法 2012-08-31 ~ ADMIN 之前介绍了序列比对的一些算法.本节主要讲述motif(有人翻译成结构模式,但本文一律使用基模)的比对算法. 那么什么是 ...

  7. 将Win7笔记本设置成WiFi热点(无线路由器)

    查看是否能启动WiFi网卡: S1:运行cmd命令,打开命令提示符窗口(以管理员身份运行). S2:在命令行输入:netsh wlan show drivers. 若“支持的承载网络”后为“是”,则可 ...

  8. Loadrunner脚本回放无法准确定位欲删除元素

    Loadrunner脚本回放无法准确定位欲删除元素 问题: loadrunner脚本回放无法准确定位欲删除元素 详细: 我司ocrm系统,我的工作台菜单->我的综合工作台子页面下,工作日志页面删 ...

  9. Debian8 下面 muduo库编译与使用

    其实<Linux 多线程服务端编程>已经写得很详细 但是考虑到代码版本的更新和操作系统的不同 可能部分位置会有些许出入 这里做个记录 方便以后学习运行 我使用的虚拟 安装的是debian系 ...

  10. springmvc 测试项目示例

    新建一个 maven项目 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=" ...