Azure 容器应用环境中Nginx http调用部分传输

问题描述 投票:0回答:1

我有 2 个 docker 容器:1 个 nginx (repro-nginx) 和 1 个 dotnet webapi,可产生“大响应”(repro-large-response) (73.7 kB)。

repro-nginx 部署在这里:https://repro-nginx.lemonsea-adf71d13.westeurope.azurecontainerapps.io/ 和 repro-large-response 部署在这里:https://repro-large-response.lemonsea -adf71d13.westeurope.azurecontainerapps.io/。 两者都部署在同一个容器应用程序环境中。 这意味着容器可以使用它们的服务名称相互通信。 理想情况下,repro-large-response 不会暴露给外界,这仅用于演示目的。

repro-nginx 配置如下: https://repro-nginx.lemonsea-adf71d13.westeurope.azurecontainerapps.io/:

上有 3 条路线
  • /repro-internal/ => 使用内部服务名称访问 repro-large-response。
  • /repro-external-http/ => 通过 http 使用入口访问 repro-large-response。
  • /repro-external-https/ => 通过 https 使用入口访问 repro-large-response。

问题: 每当您尝试 /repro-internal/ (https://repro-nginx.lemonsea-adf71d13.westeurope.azurecontainerapps.io/repro-internal/) 它有时会返回部分响应,您会看到总响应大小为 65.5 kB 与 73.7 kB,json 数据在某些时候被截断,并且在某些浏览器中错误代码为 NS_ERROR_NET_PARTIAL_TRANSFER。 其他外部端点没有这个问题。

我们创建了一个演示:

图像托管在 docker hub 上,您可以根据需要检查它们:

repro-nginx 配置:

cors-options.conf

proxy_hide_header Access-Control-Allow-Origin;
add_header 'Access-Control-Allow-Origin' $allow_origin;
add_header Vary Origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With';

cors-map.conf

map $http_origin $allow_origin {
  default "";
}

/etc/nginx/conf.d/default.conf

include snippets/cors-map.conf;

server { 
  listen 80;
#   server_name frontend;

#   error_log /home/logs/error.log debug;

  location / {
    root /usr/share/nginx/html;
    try_files $uri /index.html;
  }

  location /health {
    access_log off;
    error_log   off;
    add_header 'Content-Type' 'application/json';
    return 200 '{"status":"UP"}';
  }

  proxy_read_timeout 300;
  proxy_connect_timeout 300;
  proxy_send_timeout 300; 

  client_max_body_size 500M;
  client_body_buffer_size 500M;

  client_body_timeout 300;
  client_header_timeout 300;

  keepalive_timeout 300;

  proxy_buffer_size                            128k;
  proxy_buffers                                4 256k;
  proxy_busy_buffers_size                      256k;


  location /repro-internal/ {
    include snippets/cors-options.conf;

    proxy_ssl_server_name on;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Authorization "Bearer null";
    proxy_pass http://repro-large-response/;
    proxy_http_version 1.1;
  }

  location /repro-external-http/ {
    include snippets/cors-options.conf;

    proxy_ssl_server_name on;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Authorization "Bearer null";
    proxy_pass http://repro-large-response.lemonsea-adf71d13.westeurope.azurecontainerapps.io/;
    proxy_redirect off;
    proxy_http_version 1.1;
  }

  location /repro-external-https/ {
    include snippets/cors-options.conf;

    proxy_ssl_server_name on;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Authorization "Bearer null";
    proxy_pass https://repro-large-response.lemonsea-adf71d13.westeurope.azurecontainerapps.io/;
    proxy_redirect off;
    proxy_http_version 1.1;
  }
}

图像是使用 terraform 部署的,以下是部署计划的相关部分:

// Container app - repro-large-response
resource "azurerm_container_app" "repro-large-response" {
  name                         = "repro-large-response"
  container_app_environment_id = azurerm_container_app_environment.main.id
  resource_group_name          = azurerm_resource_group.main.name
  revision_mode                = "Single"

  identity {
    type = "SystemAssigned"
  }

  ## Issue when deploying inmediately with ingress enabled 
  ingress {
    external_enabled = true
    target_port      = 8080
    allow_insecure_connections = true
    traffic_weight {
      percentage = 100
      latest_revision = true
    }
  }

  template {
    min_replicas = 1
    max_replicas = 1

    container {
      name   = "repro-large-response"
      image  = "techorama2021cegeka/repro-large-response:3"
      cpu    = 0.25
      memory = "0.5Gi"
    }
  }
  
  tags = {
    "container" = "repro-large-response"
  }
}

// Container app - repro-nginx
resource "azurerm_container_app" "repro-nginx" {
  name                         = "repro-nginx"
  container_app_environment_id = azurerm_container_app_environment.main.id
  resource_group_name          = azurerm_resource_group.main.name
  revision_mode                = "Single"

  identity {
    type = "SystemAssigned"
  }

  ## Issue when deploying inmediately with ingress enabled 
  ingress {
    external_enabled = true
    target_port      = 80
    allow_insecure_connections = false
    traffic_weight {
      percentage = 100
      latest_revision = true
    }
  }

  template {
    min_replicas = 1
    max_replicas = 1

    container {
      name   = "repro-nginx"
      image  = "techorama2021cegeka/repro-nginx:4"
      cpu    = 0.25
      memory = "0.5Gi"
    }
  }
  
  tags = {
    "container" = "repro-nginx"
  }
}

如果您需要更多信息,请告诉我。

nginx azure-container-apps
1个回答
0
投票

Azure 容器应用环境中 Nginx http 调用部分传输

Nginx 配置中的部分响应问题,尤其是在

/repro-internal/
路由上,似乎与 Nginx 的缓冲处理以及后端服务的 keepalive 设置有关。

由于使用外部路由(

/repro-external-http/
/repro-external-https/
)时不存在该问题,因此表明内部网络或内部路由的特定配置可能是根本问题。

要解决 Nginx 设置中的部分响应问题,请尝试以下操作: 增加缓冲区大小(如

proxy_buffers
)以处理更大的响应。通过设置
proxy_set_header Connection "keep-alive";
,确保 Nginx 和 Dotnet 应用程序正确使用 keepalive 设置。

增强型 Nginx 配置示例

server {
  listen 80;

  location / {
    root /usr/share/nginx/html;
    try_files $uri /index.html;
  }

  location /health {
    access_log off;
    error_log off;
    add_header 'Content-Type' 'application/json';
    return 200 '{"status":"UP"}';
  }

  proxy_read_timeout 300;
  proxy_connect_timeout 300;
  proxy_send_timeout 300;

  client_max_body_size 500M;
  client_body_buffer_size 500M;

  client_body_timeout 300;
  client_header_timeout 300;

  keepalive_timeout 650s;
  proxy_http_version 1.1;
  proxy_set_header Connection "keep-alive";  # Ensuring keep-alive is used

  proxy_buffer_size 512k;
  proxy_buffers 16 512k;
  proxy_busy_buffers_size 1m;

  location /repro-internal/ {
    include snippets/cors-options.conf;
    proxy_ssl_server_name on;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Authorization "Bearer null";
    proxy_pass http://repro-large-response/;
  }

  location /repro-external-http/ {
    include snippets/cors-options.conf;
    proxy_ssl_server_name on;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Authorization "Bearer null";
    proxy_pass http://repro-large-response.lemonsea-adf71d13.westeurope.azurecontainerapps.io/;
    proxy_redirect off;
  }

  location /repro-external-https/ {
    include snippets/cors-options.conf;
    proxy_ssl_server_name on;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Authorization "Bearer null";
    proxy_pass https://repro-large-response.lemonsea-adf71d13.westeurope.azurecontainerapps.io/;
    proxy_redirect off;
  }
}

我的示例地形配置:

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "main" {
  name     = "vksb-rg"
  location = "East US2"
}

resource "azurerm_container_app_environment" "main" {
  name                = "testvk-container-app-env"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location

  # Configuration specific to your environment
}

resource "azurerm_container_app" "repro-large-response" {
  name                         = "repro-large-response"
  container_app_environment_id = azurerm_container_app_environment.main.id
  resource_group_name          = azurerm_resource_group.main.name
  revision_mode                = "Single"

  identity {
    type = "SystemAssigned"
  }

  ingress {
    external_enabled = true
    target_port      = 8080
    allow_insecure_connections = true
    traffic_weight {
      percentage = 100
      latest_revision = true
    }
  }

  template {
    min_replicas = 1
    max_replicas = 1

    container {
      name   = "repro-large-response"
      image  = "techorama2021cegeka/repro-large-response:3"
      cpu    = 0.25
      memory = "0.5Gi"
    }
  }

  tags = {
    "container" = "repro-large-response"
  }
}

resource "azurerm_container_app" "repro-nginx" {
  name                         = "repro-nginx"
  container_app_environment_id = azurerm_container_app_environment.main.id
  resource_group_name          = azurerm_resource_group.main.name
  revision_mode                = "Single"

  identity {
    type = "SystemAssigned"
  }

  ingress {
    external_enabled = true
    target_port      = 80
    allow_insecure_connections = false
    traffic_weight {
      percentage = 100
      latest_revision = true
    }
  }

  template {
    min_replicas = 1
    max_replicas = 1

    container {
      name   = "repro-nginx"
      image  = "techorama2021cegeka/repro-nginx:4"
      cpu    = 0.25
      memory = "0.5Gi"
    }
  }

  tags = {
    "container" = "repro-nginx"
  }
}

部署成功:

enter image description here

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.