You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker-Compose配置YARP网关转发微服务时出现503及地址分配错误

Docker + YARP 部署HTTP 503错误解决

本人是Docker与YARP新手,可能犯了基础错误。用ASP.NET Core搭建了YARP网关和一个微服务,单独运行两个容器时可正常工作,但使用docker-compose部署时出现HTTP 503错误(无法分配请求地址)。

网关appsettings.json配置

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ReverseProxy": {
    "Routes": {
      "route1": {
        "ClusterId": "cluster1",
        "Match": {
          "Path": "{**catch-all}"
        },
        "Transforms": [
          { "PathPattern": "{**catch-all}" }
        ]
      }
      //"route2": {
      //  "ClusterId": "cluster2",
      //  "Match": {
      //    "Path": "/2/{**catch-all}"
      //  },
      //  "Transforms": [
      //    { "PathPattern": "{**catch-all}" }
      //  ]
      //}
    },
    "Clusters": {
      "cluster1": {
        "LoadBalancingPolicy": "RoundRobin",
        "Destinations": {
          "destination1": {
            "Address": "http://host.docker.internal:5100/weatherforecast"
          }
        }
      }
      //"cluster2": {
      //  "LoadBalancingPolicy": "RoundRobin",
      //  "Destinations": {
      //    "destination2": {
      //      "Address": "https://172.35.0.2:5101/PageCall"
      //    }
      //  }
      //}
    }
  }
}

docker-compose.yml配置

version: '3.4'

services:
  gateway:
    image: ${DOCKER_REGISTRY-}gateway
    build:
      context: .
      dockerfile: Gateway/Dockerfile
    #ports:
    #- "5000:5000"
    #- "5001:5001"
    networks:
     proxybackend:
  posting-service:
    image: ${DOCKER_REGISTRY-}postingservice
    build:
      context: .
      dockerfile: Posting-service/Dockerfile
    #ports:
    #- "5100:5100"
    #- "5101:5101"
    networks:
     proxybackend:

networks:
  proxybackend:
    name: proxybackend
    driver: bridge

docker-compose.override.yml配置

version: '3.4'

services:
  gateway:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
    ports:
      - "5000:80"   
      - "5001:443"
    volumes:
      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
  posting-service:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
    ports:
      - "5100:80"
      - "5101:443"
    volumes:
      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro

错误日志

System.Net.Http.HttpRequestException: Cannot assign requested address (localhost:5101)
2024-03-12 10:06:02        ---> System.Net.Sockets.SocketException (99): Cannot assign requested address
2024-03-12 10:06:02          at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
2024-03-12 10:06:02          at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
2024-03-12 10:06:02          at System.Net.Sockets.Socket.<ConnectAsync>g__WaitForConnectWithCancellation|277_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken)
2024-03-12 10:06:02          at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
2024-03-12 10:06:02          --- End of inner exception stack trace ---
2024-03-12 10:06:02          at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
2024-03-12 10:06:02          at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
2024-03-12 10:06:02          at System.Net.Http.HttpConnectionPool.AddHttp2ConnectionAsync(HttpRequestMessage request)
2024-03-12 10:06:02          at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)
2024-03-12 10:06:02          at System.Net.Http.HttpConnectionPool.GetHttp2ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
2024-03-12 10:06:02          at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
2024-03-12 10:06:02          at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
2024-03-12 10:06:02          at Yarp.ReverseProxy.Forwarder.HttpForwarder.SendAsync(HttpContext context, String destinationPrefix, HttpMessageInvoker httpClient, ForwarderRequestConfig requestConfig, HttpTransformer transformer, CancellationToken cancellationToken)

问题根源

  1. 容器间通信地址错误:docker-compose创建的内部网络中,容器不能通过host.docker.internal或宿主机端口访问其他容器,必须使用服务名(posting-service)+容器内部监听端口。
  2. YARP地址配置冗余:Destination的Address不应包含具体路径(/weatherforecast),路径转发应由路由规则处理。

修复步骤

1. 修改网关appsettings.json配置

更新ReverseProxy的Cluster地址,替换为服务名+容器内部端口,去掉路径部分:

"Clusters": {
  "cluster1": {
    "LoadBalancingPolicy": "RoundRobin",
    "Destinations": {
      "destination1": {
        "Address": "http://posting-service:80"
      }
    }
  }
}

当前路由的{**catch-all}规则会将网关收到的所有路径原样转发到微服务,确保微服务的接口路径(如/weatherforecast)能正常响应即可。

2. 验证容器网络连通性

进入网关容器执行命令,测试与微服务的连通性:

docker exec -it <gateway-container-id> curl http://posting-service:80/weatherforecast

如果能收到微服务的响应,说明网络连通正常。

3. 重新部署容器

修改配置后,重新构建并启动容器:

docker-compose down
docker-compose up --build

4. 测试转发效果

访问网关地址http://localhost:5000/weatherforecast,此时YARP应能正确转发请求到微服务,返回预期结果。


内容的提问来源于stack exchange,提问作者coen donk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 03:17:02