ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ocelot 托管与部署避坑指南:IIS/Kestrel 托管场景的 Gotchas 与不支持特性全解析

Ocelot 托管与部署避坑指南:IIS/Kestrel 托管场景的 Gotchas 与不支持特性全解析 API网关后端微服务【免费下载链接】Ocelot.NET API Gateway项目地址https://gitcode.com/gh_mirrors/oc/Ocelot点击查看免费下载Ocelot.NET API Gateway的绝大多数错误与事故gotchas都与 Web 服务器托管场景密切相关。本文基于 Ocelot 官方文档的Hosting Gotchas章节系统梳理 IIS 与 Kestrel 两种托管方式下的已知陷阱与官方推荐做法并对照当前仓库源码解释其底层原理同时完整覆盖Not Supported章节中 Ocelot 明确不支持的特性Chunked Encoding、Host 头转发、Swagger帮助你在部署网关时避开最常见的坑并掌握大文件代理、请求体上限配置等实战方案。IIS 托管不推荐但若必须使用请牢记以下陷阱Ocelot 官方文档明确不推荐将 Ocelot 应用部署到 IIS 环境但如果确实需要必须注意以下三个已知问题详见 gotchas.rstASP.NET Core 2.2 使用 In-Process 托管时会启动失败若要在 ASP.NET Core 2.2 及以上版本中使用 In-Process 托管必须将UseIISIntegration()替换为UseIIS()否则会报启动错误。In-Process 模型会导致响应极慢官方建议使用Out-of-process 托管模型IIS 反向代理到 Kestrel否则会得到非常缓慢的响应对应官方 issue 1657。下游主机的 DNS 必须全部在线且工作正常如果任何下游主机的 DNS 服务器不可用或异常网关会得到缓慢的响应对应官方 issue 1630。社区持续报告与 IIS 相关的各类问题。如果遇到 IIS 环境下的托管问题官方建议的排查顺序是先阅读仓库中已开/已关闭的相关 issue然后在仓库中搜索IIS相关代码对象如 WebSocketsProxyMiddleware、DownstreamRequest 等大概率能找到社区成员给出的现成解决方案。仓库还维护了专门的IIS标签可用于给相关 issue、pull request 和 discussion 打标。从当前仓库的 Dockerfile.windows 与 Dockerfile.base 可以看出Ocelot 官方的主要发布载体是自托管/Docker 场景这也印证了“不推荐 IIS”的立场——Windows 镜像仅作为备用发布渠道存在。Kestrel自托管/Docker推荐场景及其两个关键 GotchaOcelot推荐部署到自托管环境Kestrel通常配合 Docker。官方一直在针对 Kestrel 与 Docker 托管场景优化 Ocelot 应用但仍有两个高频陷阱需要留意Gotcha 1大文件上传与下载网关代理大文件静态文件等时存在明显的性能代价消耗内存与 CPU、产生长延迟、给下游流式传输制造网络错误、并影响其他路由的响应。官方明确不推荐通过网关泵送 100MB 甚至 1GB 的大文件并建议客户端应用直接对接文件持久化存储远程/分布式文件系统、CDN、静态文件与 Blob 存储等而不是绕道网关。社区持续报告与 large file、application/octet-stream内容类型以及 Chunked Encoding 相关的问题官方 issue 749、1472。若确实需要通过 Ocelot 网关泵送大文件请使用 23.0 及以上版本官方认为 PR 1724、1769 修复并稳定了 22.0.1 及更低版本的大内容代理问题。Gotcha 2最大请求体大小MaxRequestBodySize当应用实例没有正确配置 Kestrel 的MaxRequestBodySize选项却泵送了超出限制的、大小不可预知的大文件时ASP.NET 的HttpRequest会产生异常行为。官方给出的快速修复配置如下var builder WebApplication.CreateBuilder(args); builder.WebHost.ConfigureKestrel((context, serverOptions) { int myVideoFileMaxSize 1_073_741_824; // 假设你的文件存储最大文件大小为 1 GB (1_073_741_824) int totalSize myVideoFileMaxSize 26_258_176; // 再加上一些额外余量 serverOptions.Limits.MaxRequestBodySize totalSize; // 1_100_000_000 从而 1 GB 文件不会超过限制 });要点MaxRequestBodySize的单位是字节需要给业务文件大小留出额外的协议开销余量示例中 1 GB 文件加了约 25 MB 余量以避免恰好卡在临界值上。从源码层面看Ocelot 的大内容请求处理依赖 StreamHttpContent它以 65536 字节64 KB为默认缓冲区大小DefaultBufferSize通过ArrayPoolbyte.Shared租用缓冲并按内容声明长度动态调整最小缓冲大小从而以流式方式把请求体搬运到下游请求体映射的完整逻辑位于 RequestMapper其中对无请求体request.Body null或既无ContentLength也无Transfer-Encoding的情况直接返回空内容对ContentLength 0的情况返回空ByteArrayContent其余情况才走流式StreamHttpContent。这也是为什么超大文件经过网关时内存与 CPU 开销明显——内容被逐块缓冲并复制。明确不支持的特性Chunked Encoding、Host 头转发与 Swagger除了托管陷阱官方文档Not Supported见 notsupported.rst还列出了三类明确不支持、且不会改变设计的特性理解这些边界可以避免在设计网关方案时走弯路Chunked Encoding总是回填 Content-LengthOcelot总是会获取响应体大小并返回Content-Length头不会向下游/客户端转发Transfer-Encoding: chunked。这一点有清晰的源码证据在请求映射阶段RequestMapper 将host与transfer-encoding列入UnsupportedHeaders从上游请求中剥离在响应阶段HttpContextResponder 从下游响应的Content.Headers.ContentLength取值若存在则显式写入Content-Length响应头RemoveOutputHeaders 会在写响应前统一移除Transfer-Encoding头注释明确指出当 ASP.NET 不以该方式返回响应时transfer-encoding chunked这类头不能被转发给客户端。若你的用例依赖 Chunked Encoding如服务器推送型流式响应Ocelot 目前无法满足。转发 Host 头不会转发否则一切都会坏掉你发送给 Ocelot 的Host头不会被转发到下游服务——官方直言“Obviously this would break everything”显然这会破坏一切。原因很直观网关必须把请求重写到下游地址若原样转发客户端的Host头下游服务将无法正确路由与虚拟主机解析。源码佐证RequestMapper 同样把host从上游请求头中排除DownstreamRequest 在构造下游请求时使用_request.RequestUri.Host即下游目标主机重建Host而不是沿用上游的值。Swagger官方不内置需自建 swagger.json 或使用社区方案Ocelot 团队多次评估过从ocelot.json生成swagger.json的方案但认为这与团队愿景不符官方不提供内置 Swagger 支持。原因包括Ocelot 的路由定义已经“手工打磨”在ocelot.json中把路由解析成 Swagger 路径并不能真实描述可用接口——例如很多用户会用/products/{everything}把全部流量代理到某个服务这种路由解析出来的 Swagger 路径毫无意义Ocelot 没有下游服务返回模型的概念同一个端点可能返回多种模型Ocelot 也不知道 POST/PUT 等请求可能使用哪些模型Swashbuckle 在运行时不会重载swagger.json而 Ocelot 的配置支持运行时变更二者信息会失配——除非团队自研 Swagger 实现。若你确实需要 Swagger官方给出的做法是自建swagger.json并在 Program.cs 中注册中间件。先安装 Swashbuckle 包dotnet add package Swashbuckle.AspNetCore --version 10.2.x再在Program.cs中加入以下代码其中builder与app沿用 samples/Basic/Program.cs 的标准 Ocelot 启动方式var builder WebApplication.CreateBuilder(args); // ... 常规的 AddOcelot() 与服务注册 ... var app builder.Build(); app.Map(/swagger/v1/swagger.json, builder builder.Run(async context { var json await File.ReadAllTextAsync(swagger.json); await context.Response.WriteAsync(json); })); app.UseSwaggerUI(c c.SwaggerEndpoint(/swagger/v1/swagger.json, Ocelot)); await app.UseOcelot(); await app.RunAsync();官方推荐的两条替代路线Postman对于只想快速测试 Ocelot API 的开发者官方推荐使用 Postman。虽然从ocelot.json生成 Postman collection 理论上可行但官方目前没有计划支持该功能。MMLib.SwaggerForOcelot社区包由 Miňo Martiniak/Burgyn 维护覆盖了在 Ocelot API 网关上生成 Swagger 文档的诸多常见场景是官方认可的健壮替代方案。另外官方建议与其纠结 Swagger不如直接把ocelot.json分享给前端/下游开发者如同步仓库权限一样简单或者使用 Ocelot 的管理AdministrationAPI见 administration.rst让调用方直接查询配置详见 FileConfigurationController。与托管相关的仓库证据与配置参考托管陷阱原文gotchas.rst本文所有 IIS/Kestrel Gotcha 均出自该文档不支持特性原文notsupported.rst请求体流式处理与头过滤RequestMapper.cs、StreamHttpContent.cs响应 Content-Length 回填与 Transfer-Encoding 移除HttpContextResponder.cs、RemoveOutputHeaders.csHost 头重建DownstreamRequest.cs行为验证测试RequestMapperTests.cs覆盖无内容、带 Content-Length、chunked 内容与空 chunked 内容四种请求映射场景其中 chunked 场景对应官方 issue 928标准启动骨架samples/Basic/Program.cs 与路由配置 samples/Basic/ocelot.jsonDocker 发布载体Dockerfile.base、Dockerfile.release小结一句话总结本指南托管优先选 Kestrel/Docker大文件不要走网关若必须走请升级 23.0 并配好MaxRequestBodySizeIIS 场景务必用 Out-of-process 模型并确保下游 DNS 健康同时接受 Ocelot 在 Chunked Encoding、Host 转发与内置 Swagger 三方面的设计边界。在实际项目中先对照这些 Gotcha 做一次部署前自检能显著降低网关上线后的响应缓慢与异常行为风险。赞分享API网关后端微服务【免费下载链接】Ocelot.NET API Gateway项目地址https://gitcode.com/gh_mirrors/oc/Ocelot点击查看免费下载相关推荐linkding 托管部署指南托管服务、托管平台与自托管方案全解析linkding 托管部署指南托管服务、托管平台与自托管方案全解析 linkding 是一个定位为极简、快速、易于用 Docker 部署的自托管书签管理器后端前端Cloudflare Containers 部署避坑指南Gotchas 全解析与最佳实践Cloudflare Containers 部署避坑指南Gotchas 全解析与最佳实践 导读 Cloudflare Containers 允许你以容器即人工智能AI 技能AI 插件Vitess 分离部署指南VTTablet 与 MySQL 解耦托管 MySQL 场景Vitess 分离部署指南VTTablet 与 MySQL 解耦托管 MySQL 场景 本文基于 Vitess 官方设计文档 SeparatingVtta数据库分布式数据库云原生后端数据存储上一篇WeMod Pro免费解锁终极指南一键获取完整教程下一篇腾讯开源SongGenerationLeVo架构重构AI音乐创作30亿参数实现专业级歌曲生成创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表