为什么找不到反向代理后面的这些 Swagger 端点?
Why are these Swagger endpoints behind a reverse-proxy not found?
我有少量 ASP.NET 核心服务,所有 运行 都在 Docker 中(通过 Docker Compose)。所有服务当前都使用前缀路由(它们自己的服务名称)。它们都在 Docker Compose 中设置为使用它们自己的服务名称作为它们的主机名(服务容器之间的连接正常)。
/api-docs
端点由Swashbuckle提供;我们也在这里设置前缀路由。
app.UseSwagger(options =>
{
options.RouteTemplate = "scheduler/api-docs/{documentName}/swagger.json";
});
app.UseSwaggerUI(options =>
{
options.RoutePrefix = "scheduler/api-docs";
options.SwaggerEndpoint("/scheduler/api-docs/v1/swagger.json", "Scheduler API v1");
});
我正在尝试在容器网络中配置 Nginx 反向代理,这样我就可以去...
http://localhost/<service-name>/api-docs
它会在容器网络内部重定向到...
http://<service-name>:5000/<service-name>/api-docs
所以,这是我提出的 Nginx 配置...基本上,匹配请求 URI 的第一部分,它应该是服务名称,并代理到与 Nginx 名称相同的主机 应该自动添加$request_uri
。
server {
listen 80;
location ~* ^/(?<target>.+)/ {
proxy_pass http://$target:5000;
proxy_redirect off;
resolver 127.0.0.11;
}
}
这是我得到的 /scheduler/healthcheck
端点。一切顺利!
api-gateway_1 | 172.19.0.1 - - [27/Mar/2018:17:50:24 +0000] "GET /scheduler/healthcheck HTTP/1.1" 200 491 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
但是,当我尝试转到 /scheduler/api-docs
时,我遇到了问题。我们到达服务容器,Swashbuckle 执行从 /scheduler/api-docs
到 /scheduler/api-docs/
.
的 301 重定向
api-gateway_1 | 172.19.0.1 - - [27/Mar/2018:17:51:18 +0000] "GET /scheduler/api-docs HTTP/1.1" 301 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
然后,事情变糟了...我们 "lose" 路线的 /scheduler
部分!
api-gateway_1 | 172.19.0.1 - - [27/Mar/2018:17:51:18 +0000] "GET /scheduler/api-docs/ HTTP/1.1" 502 576 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
api-gateway_1 | 2018/03/27 17:51:18 [error] 5#5: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.1, server: , request: "GET /scheduler/api-docs/ HTTP/1.1", upstream: "http://172.19.0.5:80/api-docs:5000", host: "localhost:4000"
为什么 Swashbuckle 重定向通过 Nginx 将请求发回,我认为这将由本地服务处理,为什么 Nginx 会从该请求中剥离必要的路由前缀?
我如何让它运行?!
我试图重建 "whole" URI,只是为了看看会发生什么...
- proxy_pass http://$target:5000;
+ proxy_pass http://$target:5000$request_uri;
而且 甚至 更糟!
api-gateway_1 | 172.19.0.1 - - [27/Mar/2018:18:03:48 +0000] "GET /scheduler/api-docs HTTP/1.1" 301 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
api-gateway_1 | 172.19.0.1 - - [27/Mar/2018:18:03:48 +0000] "GET /scheduler/api-docs/ HTTP/1.1" 502 576 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
api-gateway_1 | 2018/03/27 18:03:48 [error] 5#5: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.1, server: , request: "GET /scheduler/api-docs/ HTTP/1.1", upstream: "http://172.19.0.5:80/api-docs:5000/scheduler/api-docs/", host: "localhost:4000"
仅供参考,如果我直接访问网站(通过 Docker 等发布端口后),在我的浏览器中一切正常)
咳咳...问题是 "greedy" 正则表达式。根据定义,正则表达式捕获组 .+
将消耗 所有内容 直到 last forward-slash.
您应该使用 "lazy" 正则表达式捕获组 .+?
来捕获两个 forward-slash 之间的单个 URI 段,而不是 所有内容 到 last forward-slash!
我有少量 ASP.NET 核心服务,所有 运行 都在 Docker 中(通过 Docker Compose)。所有服务当前都使用前缀路由(它们自己的服务名称)。它们都在 Docker Compose 中设置为使用它们自己的服务名称作为它们的主机名(服务容器之间的连接正常)。
/api-docs
端点由Swashbuckle提供;我们也在这里设置前缀路由。
app.UseSwagger(options =>
{
options.RouteTemplate = "scheduler/api-docs/{documentName}/swagger.json";
});
app.UseSwaggerUI(options =>
{
options.RoutePrefix = "scheduler/api-docs";
options.SwaggerEndpoint("/scheduler/api-docs/v1/swagger.json", "Scheduler API v1");
});
我正在尝试在容器网络中配置 Nginx 反向代理,这样我就可以去...
http://localhost/<service-name>/api-docs
它会在容器网络内部重定向到...
http://<service-name>:5000/<service-name>/api-docs
所以,这是我提出的 Nginx 配置...基本上,匹配请求 URI 的第一部分,它应该是服务名称,并代理到与 Nginx 名称相同的主机 应该自动添加$request_uri
。
server {
listen 80;
location ~* ^/(?<target>.+)/ {
proxy_pass http://$target:5000;
proxy_redirect off;
resolver 127.0.0.11;
}
}
这是我得到的 /scheduler/healthcheck
端点。一切顺利!
api-gateway_1 | 172.19.0.1 - - [27/Mar/2018:17:50:24 +0000] "GET /scheduler/healthcheck HTTP/1.1" 200 491 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
但是,当我尝试转到 /scheduler/api-docs
时,我遇到了问题。我们到达服务容器,Swashbuckle 执行从 /scheduler/api-docs
到 /scheduler/api-docs/
.
api-gateway_1 | 172.19.0.1 - - [27/Mar/2018:17:51:18 +0000] "GET /scheduler/api-docs HTTP/1.1" 301 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
然后,事情变糟了...我们 "lose" 路线的 /scheduler
部分!
api-gateway_1 | 172.19.0.1 - - [27/Mar/2018:17:51:18 +0000] "GET /scheduler/api-docs/ HTTP/1.1" 502 576 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
api-gateway_1 | 2018/03/27 17:51:18 [error] 5#5: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.1, server: , request: "GET /scheduler/api-docs/ HTTP/1.1", upstream: "http://172.19.0.5:80/api-docs:5000", host: "localhost:4000"
为什么 Swashbuckle 重定向通过 Nginx 将请求发回,我认为这将由本地服务处理,为什么 Nginx 会从该请求中剥离必要的路由前缀?
我如何让它运行?!
我试图重建 "whole" URI,只是为了看看会发生什么...
- proxy_pass http://$target:5000;
+ proxy_pass http://$target:5000$request_uri;
而且 甚至 更糟!
api-gateway_1 | 172.19.0.1 - - [27/Mar/2018:18:03:48 +0000] "GET /scheduler/api-docs HTTP/1.1" 301 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
api-gateway_1 | 172.19.0.1 - - [27/Mar/2018:18:03:48 +0000] "GET /scheduler/api-docs/ HTTP/1.1" 502 576 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" "-"
api-gateway_1 | 2018/03/27 18:03:48 [error] 5#5: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.1, server: , request: "GET /scheduler/api-docs/ HTTP/1.1", upstream: "http://172.19.0.5:80/api-docs:5000/scheduler/api-docs/", host: "localhost:4000"
仅供参考,如果我直接访问网站(通过 Docker 等发布端口后),在我的浏览器中一切正常)
咳咳...问题是 "greedy" 正则表达式。根据定义,正则表达式捕获组 .+
将消耗 所有内容 直到 last forward-slash.
您应该使用 "lazy" 正则表达式捕获组 .+?
来捕获两个 forward-slash 之间的单个 URI 段,而不是 所有内容 到 last forward-slash!