解决微服务网关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 ...
随机推荐
- python作业(第十一周)基于RabbitMQ rpc实现的主机管理
作业需求: 可以对指定机器异步的执行多个命令 例子: >>:run "df -h" --hosts 192.168.3.55 10.4.3.4 task id: 453 ...
- 实验1:c++简单程序设计(1)
//文中有格式错误请无视 //这个编辑器一言难尽 实验目的 1. 掌握c++中类c部分的编程知识: 数据类型,常量,变量,运算符,表达式,分支结构,循环结构 2. 掌握C++中数据输入和输出的基本方法 ...
- thinkphp下多语言
这里指定2种语言 ,zh-cn 和 zh-tw 1.在配置文件中写入 'LANG_SWITCH_ON' => true, // 开启语言包功能 'LANG_AUTO_DETECT' => ...
- SSH三大框架需要的配置文件
1. Struts2框架 * 在web.xml中配置核心的过滤器 <filter> <filter-name>struts2</filter-name> <f ...
- Redis的复制特性
对于有扩展平台以适应更高负载经验的工程师和管理员来说,复制(replication)是不可或缺的.复制可以让其他服务器拥有一个不断更新的数据副本,从而使得拥有数据副本的服务器可以用于处理客户端发送的读 ...
- 03 解析库之Beautifulsoup模块
Beautifulsoup模块 一 介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式 ...
- [BAT]通过schtasks.exe远程调用windows 2008 server上的计划任务,提示ERROR : Access is denied
在windows 2008 server 上建了一个计划任务,想通过命令 schtasks /run /tn "IPADForAdvisor_QA_APITest" /s SZPC ...
- asio 广播代码示例
代码网络收集 修改了一个编译的小问题 客户端 // Client.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include < ...
- 什么是Jenkins 以及如何使用?
Jenkins是什么? Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台.这是一个免费的源代码,可以处理任何类型的构建或持续集成.集成Jenkins可以用于一些测 ...
- VS快捷键以及Reshaper快捷键
VS快捷键: Resharper 快捷键(此图是保存他人的[具体是谁忘记了]): 参考: http://msdn.microsoft.com/zh-cn/library/da5kh0wa.aspx