两个客户端之间的 CURL 请求因超时而失败
CURL request between two clients fails with a timeout
我有两个应用程序,一个 API 及其在 Windows 上的客户端,使用 Nginx,PHP 7.1 使用 Fastcgi。当我从我的 API 向我的客户或从我的客户向我的 API 发送 CURL 请求时,它工作正常。
另一方面,如果 API 向客户端发送请求,客户端也向 API 发送请求,则不再是这种情况。我的第一个请求将在 30 秒后超时,在此期间我无法向客户端并行发送请求。他们都会超时,直到第一个结束。
到目前为止我尝试了什么:
- 我将其添加到我的 Nginx 配置中
fastcgi_read_timeout 120s;
upstream php-cgi {
server 127.0.0.1:9000 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9001 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9002 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9003 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9004 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9005 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9006 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9007 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9008 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9009 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9012 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
}
以下是我使用的 CURL 选项:
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true,
CURLINFO_HEADER_OUT => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_URL=> MY_URL,
CURLOPT_POSTFIELDS=> MY_DATA,
CURLOPT_CUSTOMREQUEST=> MY METHOD,
CURLOPT_HTTPHEADER=> MY HEADERS
这就是我启动服务器的方式:
c:\nginx\RunHiddenConsole.exe c:\nginx\php-7.1\php-cgi.exe -b 127.0.0.1:9005 -c c:\nginx\php-7.1\php.ini
c:\nginx\RunHiddenConsole.exe c:\nginx\php-7.1\php-cgi.exe -b 127.0.0.1:9007 -c c:\nginx\php-7.1\php.ini
c:\nginx\RunHiddenConsole.exe c:\nginx\nginx.exe
还有我的 Nginx 配置:
worker_processes 5;
error_log logs/error.log notice;
#pid logs/nginx.pid;
events {
worker_connections 64;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
#access_log off;
# Optimisation sur l'envoie des fichier sans passer par des buffer
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 600;
server_name_in_redirect off;
server_names_hash_bucket_size 64;
# Compression
gzip on;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# Taille de headers HTTP en prereponse
proxy_connect_timeout 159s;
proxy_send_timeout 600;
proxy_read_timeout 600;
proxy_buffer_size 64k;
proxy_buffers 16 256k;
proxy_busy_buffers_size 256k;
fastcgi_buffer_size 256k;
fastcgi_buffers 8 256k;
fastcgi_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
client_max_body_size 200m;
######################################
######################################
# fastcgi_cache_path c:/nginx/cache/ levels=1:2 keys_zone=www_cache:10m inactive=1h max_size=1g;
server {
listen 443 ssl http2;
server_name my-api.com
root c:\www\my-api.com\web;
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate ../cert/server.crt;
ssl_certificate_key ../cert/server.key;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /app_dev.php$is_args$args;
}
# DEV
# This rule should only be placed on your development environment
# In production, don't include this and don't deploy app_dev.php or config.php
location ~ ^/(app_dev|config)\.php(/|$) {
fastcgi_pass 127.0.0.1:9005;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
}
server {
listen 443 ssl http2;
server_name my-client.com;
root c:\www\my-client.com\public;
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate ../cert/server.crt;
ssl_certificate_key ../cert/server.key;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php$is_args$args;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1h;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass 127.0.0.1:9007;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
}
}
感谢这个 link (https://www.nginx.com/resources/wiki/start/topics/examples/fastcgiexample/),我能够理解有必要在我的启动脚本中定义变量 PHP_FCGI_MAX_REQUESTS 所以 API可以响应同时收到的多个请求。
SET PHP_FCGI_CHILDREN=5
SET PHP_FCGI_MAX_REQUESTS=0
c:\nginx\RunHiddenConsole.exe c:\nginx\php-7.1\php-cgi.exe -b 127.0.0.1:9005 -c c:\nginx\php-7.1\php.ini
c:\nginx\RunHiddenConsole.exe c:\nginx\php-7.1\php-cgi.exe -b 127.0.0.1:9007 -c c:\nginx\php-7.1\php.ini
c:\nginx\RunHiddenConsole.exe c:\nginx\nginx.exe
我有两个应用程序,一个 API 及其在 Windows 上的客户端,使用 Nginx,PHP 7.1 使用 Fastcgi。当我从我的 API 向我的客户或从我的客户向我的 API 发送 CURL 请求时,它工作正常。
另一方面,如果 API 向客户端发送请求,客户端也向 API 发送请求,则不再是这种情况。我的第一个请求将在 30 秒后超时,在此期间我无法向客户端并行发送请求。他们都会超时,直到第一个结束。
到目前为止我尝试了什么:
- 我将其添加到我的 Nginx 配置中
fastcgi_read_timeout 120s;
upstream php-cgi {
server 127.0.0.1:9000 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9001 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9002 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9003 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9004 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9005 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9006 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9007 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9008 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9009 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
server 127.0.0.1:9012 max_conns=5 weight=1 max_fails=0 fail_timeout=30s;
}
以下是我使用的 CURL 选项:
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true,
CURLINFO_HEADER_OUT => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_URL=> MY_URL,
CURLOPT_POSTFIELDS=> MY_DATA,
CURLOPT_CUSTOMREQUEST=> MY METHOD,
CURLOPT_HTTPHEADER=> MY HEADERS
这就是我启动服务器的方式:
c:\nginx\RunHiddenConsole.exe c:\nginx\php-7.1\php-cgi.exe -b 127.0.0.1:9005 -c c:\nginx\php-7.1\php.ini
c:\nginx\RunHiddenConsole.exe c:\nginx\php-7.1\php-cgi.exe -b 127.0.0.1:9007 -c c:\nginx\php-7.1\php.ini
c:\nginx\RunHiddenConsole.exe c:\nginx\nginx.exe
还有我的 Nginx 配置:
worker_processes 5;
error_log logs/error.log notice;
#pid logs/nginx.pid;
events {
worker_connections 64;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
#access_log off;
# Optimisation sur l'envoie des fichier sans passer par des buffer
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 600;
server_name_in_redirect off;
server_names_hash_bucket_size 64;
# Compression
gzip on;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# Taille de headers HTTP en prereponse
proxy_connect_timeout 159s;
proxy_send_timeout 600;
proxy_read_timeout 600;
proxy_buffer_size 64k;
proxy_buffers 16 256k;
proxy_busy_buffers_size 256k;
fastcgi_buffer_size 256k;
fastcgi_buffers 8 256k;
fastcgi_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
client_max_body_size 200m;
######################################
######################################
# fastcgi_cache_path c:/nginx/cache/ levels=1:2 keys_zone=www_cache:10m inactive=1h max_size=1g;
server {
listen 443 ssl http2;
server_name my-api.com
root c:\www\my-api.com\web;
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate ../cert/server.crt;
ssl_certificate_key ../cert/server.key;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /app_dev.php$is_args$args;
}
# DEV
# This rule should only be placed on your development environment
# In production, don't include this and don't deploy app_dev.php or config.php
location ~ ^/(app_dev|config)\.php(/|$) {
fastcgi_pass 127.0.0.1:9005;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
}
server {
listen 443 ssl http2;
server_name my-client.com;
root c:\www\my-client.com\public;
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate ../cert/server.crt;
ssl_certificate_key ../cert/server.key;
location / {
# try to serve file directly, fallback to app.php
try_files $uri /index.php$is_args$args;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1h;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass 127.0.0.1:9007;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
}
}
感谢这个 link (https://www.nginx.com/resources/wiki/start/topics/examples/fastcgiexample/),我能够理解有必要在我的启动脚本中定义变量 PHP_FCGI_MAX_REQUESTS 所以 API可以响应同时收到的多个请求。
SET PHP_FCGI_CHILDREN=5
SET PHP_FCGI_MAX_REQUESTS=0
c:\nginx\RunHiddenConsole.exe c:\nginx\php-7.1\php-cgi.exe -b 127.0.0.1:9005 -c c:\nginx\php-7.1\php.ini
c:\nginx\RunHiddenConsole.exe c:\nginx\php-7.1\php-cgi.exe -b 127.0.0.1:9007 -c c:\nginx\php-7.1\php.ini
c:\nginx\RunHiddenConsole.exe c:\nginx\nginx.exe