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

Java 使用Spring云网关和Nginx作为反向代理的网关超时,java,nginx,spring-cloud,nginx-reverse-proxy,spring-cloud-gateway,Java,Nginx,Spring Cloud,Nginx Reverse Proxy,Spring Cloud Gateway,我为我的应用程序创建了一个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;

我为我的应用程序创建了一个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;
Spring云网关渐变文件:

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);
    }
}
问题陈述:

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

卷曲:

错误:

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:

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

编辑:


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

似乎请求超时不是您的问题。连接超时。 我想我们需要看一下这首歌的标题

联系

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

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

这应该是nginx在日志中显示499的原因HTTP499是nginx中的一个cutom错误,表示客户端关闭了连接。在您的情况下,
curl
将其关闭。为什么
curl
关闭它?因为nginx没有响应60秒的TCP ping,因为没有启用保持活动

keepalive\u timeout
添加到~500或高于应用程序超时的值可以解决您的问题

现在,为什么它直接与tomcat合作?我认为spring允许活动超时为无限大或更高的值。通常在tomcat中,它也会运行60秒


我希望这能解决你的问题

由于配置缺少代理\u http\u版本密钥,可能仍无法为上游启用Keepalive

引自:

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


我也会像Kris建议的那样将keepalive\u超时保存在配置中。

尝试将超时设置放在/etc/nginx/conf.d/timeout.conf中(如果没有设置,则创建一个)。设置以下设置

proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;

我想这是由于许多其他原因可能发生的问题之一。这是一个适合我的解决方案(我在
/var/log/nginx/error.log中也遇到了错误):

2020/12/30 21:47:47[错误]26765#26765:*13064上游超时 (110:连接超时)连接到上游时,客户端:XXX, 服务器:example.com,请求:“GET/eshop HTTP/1.0”,上游: “http://[::1]:8080/error_50x.html”,主机:“example.com”

奇怪的是,这种情况并没有发生在我的笔记本电脑上,而只是发生在我的服务器上。所以我检查了IPs,结果发现可能是因为缺少::1地址。当我将其添加到lo网络设备时,我无法复制超时

sudo ip a add ::1/128 dev lo
下一步:(这是我的理解,我不是100%确定:)此外,由于保持与localhost Java服务的连接的开销似乎比删除该连接并在发出另一个请求时再次连接要高,因此建议对代理使用以下设置(在nginx的site.conf中):


当您通过反向代理
curl
时,请参阅API网关和nginx错误日志中的错误日志?nginx和网关中没有错误日志,添加了访问日志扫描您尝试在服务器块服务器中添加代理读取超时300s{proxy_read_timeout 300s;@RadhaMohanMaheshwari已尝试,不工作您能否尝试用api替换nginx设置中的localhost:8080.example.com:8080?设置
keepalive_timeout 500;
未工作,检查响应头时发现连接头为
connection时出现相同的错误→关闭
设置为keepalive\u timeout 500s;将其保留在服务器部分或位置。我认为单元的“s”必须在那里。在使用
keepalive\u timeout 500s放入服务器和位置部分后尝试;
但相同的错误可能是您应该在curl中尝试使用
--no keepalive
选项。我假设Nginx不尊重Keep-a实时连接。您也可以与其他一些客户端(如http client/Fiddler或任何类似的客户端)进行相同的检查。只有在使用同一连接执行多个操作时,才可以使用保持活动状态。
connection
只需在响应完成后告诉源服务器如何处理TCP套接字,即客户端我将沿着流发送更多请求。在这种情况下,这将介于curl/postman和nginx之间。我认为nginx更有可能只是变得无聊并终止请求,这很奇怪,因为读取超时为5分钟。您可能有格式问题。示例配置显示“服务器”块通常被包装在“http{}”块中,“keepalive_timeout”键是
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
sudo ip a add ::1/128 dev lo
proxy_http_version 1.1;
proxy_set_header Connection "";