使用Spring云网关和Nginx作为反向代理的网关超时

我为我的应用程序创建了一个 API 网关,它将充当其他微服务的前端控制器。在我的生产设置中,我使用Nginx作为网关的反向代理

API 网关在端口 8080 上运行

Nginx配置如下:

gateway-api.conf:

server {
    listen 80;
    server_name api.example.com;
    location / {
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_pass http://localhost:30010/;
        keepalive_timeout 500s;
    }
    keepalive_timeout 500s;
    access_log /var/log/nginx/api.log;  
    error_log /var/log/nginx/api_error.log;
}

nginx.conf 中的超时设置:

proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;

春云网关文件:

compile('org.springframework.cloud:spring-cloud-starter-gateway')
 compile('org.springframework.cloud:spring-cloud-starter-openfeign')
 compile("org.springframework.boot:spring-boot-starter-actuator")
 compile('org.springframework.boot:spring-boot-starter-security')

springBootVersion=2.0.3.RELEASE
springDMPVersion=1.0.4.RELEASE
springPlatformBomVersion=Cairo-SR2
springCloudVersion=Finchley.RELEASE

网关应用:

@SpringBootApplication
@ComponentScan(basePackages = {"com.example"})
@EntityScan(basePackages = {"com.example"})
@EnableFeignClients(basePackages = "com.example")
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

问题陈述:

在我的一个微服务中,一个 REST API 需要 3 分钟以上才能完成。如果我通过 调用此 API,它会在 1 分钟后恰好失败,并给出 HTTP 状态 504。nginx(api.example.com)

卷曲:

curl --request GET \
  --url http://api.example.com/hellomicroservice/api/take/moretime

错误:

504 Timeout while reading the response from Server

nginx或API网关中没有错误日志。

来自nginx的访问日志:

203.129.213.102 - - [01/Apr/2019:08:14:33 +0000] "GET hellomicroservice/api/take/moretime HTTP/1.1" 499 0 "-" "PostmanRuntime/7.3.0"

但是,当我直接调用网关(在网关端口 8080 上)的同一 API 时,请求将得到成功处理。

带网关端口的卷曲:

curl --request GET \
  --url http://api.example.com:8080/hellomicroservice/api/take/moretime

编辑:

如果我将Nginx超时设置应用于小于60秒(例如30秒),则请求将在指定的时间间隔内超时。但是,如果我将Nginx超时设置为超过60秒,则为300秒,请求将在60秒后超时。


答案 1

请求超时似乎不是您的问题。它是连接超时。我认为我们需要看看标题

连接

标头定义 AFAIK,连接应该是持久的,或者谁有权维护/关闭它。如果连接是 ,则该连接将是持久的。对于保持活动状态的连接,客户端偶尔会发送 TCP ping,以确保服务器仍处于活动状态并保持连接。根据卷曲,默认情况下,此时间是每60秒一次。Connectionkeep-alive

现在必须将 配置为接受连接,并使用 keepalive_timeout 指令将其保持活动状态一段时间。如果不存在,则不会使连接保持活动状态nginxnginx

这应该是nginx在日志中说499的原因。HTTP499是nginx中的一个cutom错误,它说客户端关闭了连接。在你的情况下关闭了它。为什么要关闭它?因为nginx没有响应60秒的TCP ping,因为没有启用保持活动状态。curlcurl

keepalive_timeout添加到 ~500 或大于应用程序超时的值应该可以解决您的问题。

那么,为什么它直接与雄猫一起工作?我认为春天使活态超时是无限的或非常高的值。通常在雄猫也是它的60秒。

我希望这能解决您的问题。


答案 2

由于您的配置缺少proxy_http_version键,可能仍未为上游启用 Keepalive。

引用自: https://www.nginx.com/blog/tuning-nginx/#proxy_http_version

若要启用与上游服务器的保持连接,还必须在配置中包含以下指令:

proxy_http_version 1.1;
proxy_set_header Connection "";

我也会按照Kris的建议将keepalive_timeout保留在配置中。


推荐