GVKun编程网logo

如何在 Nginx 上使用 FastCGI 防止网关超时(nginx504网关超时)

8

对于想了解如何在Nginx上使用FastCGI防止网关超时的读者,本文将提供新的信息,我们将详细介绍nginx504网关超时,并且为您提供关于c-Nginxfastcgi多线程、centos+ngin

对于想了解如何在 Nginx 上使用 FastCGI 防止网关超时的读者,本文将提供新的信息,我们将详细介绍nginx504网关超时,并且为您提供关于c-Nginx fastcgi多线程、centos+nginx+php-fpm+php include fastcgi_params php页面能访问但空白,被fastcgi_params与fastcgi.conf害惨了、cgi fastcgi wsgi isapi fastcgi fastcgi for iis nginx fastcgi pass、django – nginx和uWSGI给出“504网关超时”的有价值信息。

本文目录一览:

如何在 Nginx 上使用 FastCGI 防止网关超时(nginx504网关超时)

如何在 Nginx 上使用 FastCGI 防止网关超时(nginx504网关超时)

我正在运行 Django、FastCGI 和 Nginx。我正在创建一个 API,有人可以通过 XML
发送一些数据,我将处理这些数据,然后为每个发送过来的节点返回一些状态代码。

问题是,如果我处理 XML 的时间太长,Nginx 会抛出 504 Gateway Time-out ——我认为超过 60 秒。

所以我想设置 Nginx,这样如果任何与位置 /api 匹配的请求都不会超时 120 秒。什么设置将实现这一点。

到目前为止,我所拥有的是:

    # Handles all api calls    location ^~ /api/ {        proxy_read_timeout 120;        proxy_connect_timeout 120;        fastcgi_pass 127.0.0.1:8080;    }

编辑:我没有工作:)

答案1

小编典典

代理超时很好,对于代理,而不是 FastCGI…

client_header_timeout影响 FastCGI 超时的指令是client_body_timeoutsend_timeout

编辑 :考虑到 nginx wiki 上的内容,send_timeout
指令负责设置响应的一般超时(这有点误导)。对于
FastCGI,有fastcgi_read_timeout哪些影响FastCGI
进程响应超时。

c-Nginx fastcgi多线程

c-Nginx fastcgi多线程

您好,我一直在尝试制作fastcgi应用程序,我希望它是多线程的,以便它可以一次处理很多请求.我找到了代码,并对其进行了一些修改

FCGX_InitRequest(&request,FCGI_FAIL_ACCEPT_ON_INTR);

for (;;)
{
    static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER;
    static pthread_mutex_t counts_mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_lock(&accept_mutex);
    rc = FCGX_Accept_r(&request);
    pthread_mutex_unlock(&accept_mutex);

    ... ... ...


    FCGX_FPrintF(request.out,"%s",test_stream.str().c_str());

    FCGX_Finish_r(&request);
}

代码始终停留在接受状态,因此实际上它一直等待,直到请求完全完成为止.

我试过像这样产卵fastcgi

spawn-fcgi -p 8001 -U www-data -n handler.cgi -F 32
spawn-fcgi -p 8001 -U www-data -n handler.cgi -- /usr/bin/multiwatch -F 32
最佳答案
问题已经解决了.使用FCGX_OpenSocket和umask(0)来让套接字接受.这将为您提供真正的多线程应用程序.

#include <pthread.h> 
#include <sys/types.h> 
#include <stdio.h> 

#include "fcgi_config.h" 
#include "fcgiapp.h" 


#define THREAD_COUNT 8 
#define SOCKET_PATH "/var/run/myfcgiserver.sock" // your unix socket file

static int socketId; 

static void *doit(void *a) 
{ 
    int rc,i; 
    FCGX_Request request; 
    char *server_name; 

    if(FCGX_InitRequest(&request,socketId,0) != 0) 
    { 
        printf("Can not init request\n"); 
        return NULL; 
    } 
    printf("Request is inited\n"); 

    for(;;) 
    { 
        static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER; 

        printf("Try to accept new request\n"); 
        pthread_mutex_lock(&accept_mutex); 
        rc = FCGX_Accept_r(&request); 
        pthread_mutex_unlock(&accept_mutex); 

        if(rc < 0) 
        { 
            printf("Can not accept new request\n"); 
            break; 
        } 
        printf("request is accepted\n"); 

        server_name = FCGX_GetParam("SERVER_NAME",request.envp); 

        FCGX_PutS("Content-type: text/html\r\n",request.out); 
        FCGX_PutS("\r\n",request.out); 
        FCGX_PutS("<html>\r\n",request.out); 
        FCGX_PutS("<head>\r\n",request.out); 
        FCGX_PutS("<title>FastCGI Hello! (multi-threaded C,fcgiapp library)</title>\r\n",request.out); 
        FCGX_PutS("</head>\r\n",request.out); 
        FCGX_PutS("<body>\r\n",request.out); 
        FCGX_PutS("<h1>FastCGI Hello! (multi-threaded C,fcgiapp library)</h1>\r\n",request.out); 
        FCGX_PutS("<p>Request accepted from host <i>",request.out); 
        FCGX_PutS(server_name ? server_name : "?",request.out); 
        FCGX_PutS("</i></p>\r\n",request.out); 
        FCGX_PutS("</body>\r\n",request.out); 
        FCGX_PutS("</html>\r\n",request.out); 

        FCGX_Finish_r(&request); 

    } 

    return NULL; 
} 

int main(void) 
{ 
    int i; 
    pthread_t id[THREAD_COUNT]; 

    FCGX_Init(); 
    printf("Lib is inited\n"); 
    umask(0);   
    socketId = FCGX_OpenSocket(SOCKET_PATH,2000); 
    if(socketId < 0) 
    { 
           return 1; 
    } 
    printf("Socket is opened\n"); 


    for(i = 0; i < THREAD_COUNT; i++) 
    { 
        pthread_create(&id[i],NULL,doit,NULL); 
    } 

    for(i = 0; i < THREAD_COUNT; i++) 
    { 
        pthread_join(id[i],NULL); 
    } 

    return 0; 
}

centos+nginx+php-fpm+php include fastcgi_params php页面能访问但空白,被fastcgi_params与fastcgi.conf害惨了

centos+nginx+php-fpm+php include fastcgi_params php页面能访问但空白,被fastcgi_params与fastcgi.conf害惨了

今天在centos上折腾这块是发现老是访问页面时,浏览器中提示是200 ok.且访问html后缀却是正常出现内容.

但是访问php后缀却返回空白页面,同时查看所有的log没有发现任何出错信息;

再在nginx.conf中的server中写如果 路径不存在就return 405这样的断句来调试,发现我的配置还是正常能走到那个405.

就是没有内容返回....

找了几个小时.头都快晕了.

立即学习“PHP免费学习笔记(深入)”;

还是没有搞明白怎么回事.

最后想想和比较了下fastcgi_params与fastcgi.conf,头已经晕了,看了几眼,没看出差别来了.

我包含的是params这个文件,不是conf这个.我就郁闷死了...怎么回事?

然后想想.是不是试试饮食一下conf这个试试看?

一改变.刷新页面,竟然出来内容了...

再回头仔细看眼二个文件.竟然还是没发现有什么区别....已经全部晕了.

使用二个文件名在网上查找一下,才发现,这二个文件真有区别;

而且还有一个历史.

FASTCGI_PARAMS VERSUS FASTCGI.CONF ? NGINX CONFIG HISTORYTweetThe nginx source install (and by extension package managers) includes two FastCGI configuration files, fastcgi_params and fastcgi.conf that differ only a tiny bit. To this day they still cause confusion amongst new users due to package managers.The difference between the two files in the source install is the simple line of:fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;The difference between the two files in most distributions package repositories is nothing, they essentially modified fastcgi_params to match fastcgi.conf.What this line does is tell PHP which file it should execute, without this nginx and PHP cannot work together. This sounds like a good line to include in the shipped FastCGI configuration file and indeed Igor Sysoev thought so as well. However, due to the configurations of the time this wasn’t as easy as simply adding it in.Back in the days of 0.6.x when I started using nginx and a few years before this change happened a typical configuration example would look like this.location ~ \.php$ {    include fastcgi_params;    fastcgi_param SCRIPT_FILENAME /var/www/foo$fastcgi_script_name;    fastcgi_pass backend;}Due to community documentation efforts on the wiki people slowly started using the $document_root variable instead of hard coding the root path, however, many people were still using the above configuration many years later.Because of how array directives inherit and interact the people using the old configuration style made it impossible to include the line in fastcgi_params. Doing this would have meant that SCRIPT_FILENAME would be defined twice and both would be sent to the backend, potentially causing confusing behaviour.In 0.8.30 (released: 15th of December 2009) Igor then included fastcgi.conf which was the same as fastcgi_params except including the improved SCRIPT_FILENAME fastcgi_param. This meant that the community could now start recommending people include fastcgi.conf instead of recommending moving SCRIPT_FILENAME into fastcgi_params. New articles on the wiki mostly used this, the popular articles were slowly changed to use it and we were promoting it in the IRC support channel.Of course, an issue back then was that package managers gave nginx very little love and were many versions behind, usually something like 0.6.x versus 0.8.x. The fastcgi.conf file was not included for these people. When they eventually did update they shipped with a fastcgi.conf and a modified fastcgi_params leaving us with a situation where the source install actually differed from the repository install in a non-significant way. While not often, this does still cause the occasional confusing in the IRC channel.As an aside, I actually preferfastcgi_param SCRIPT_FILENAME $request_filename;as it takes the alias directive into account, fastcgi_new.conf anyone?Last updated:Sunday, July 7, 2013
登录后复制


关于上面的说法我理解是:

很久很久以前,大家都是include fastcgi_params,而且在后面加上一句

fastcgi_param SCRIPT_FILENAME /var/www/foo$fastcgi_script_name;
登录后复制
因为这个指令它是数组形态的,并不会说,同名的指令,后面会替换掉前面的.

而nginx的开发者慢慢发现大家写死这个root有问题.或是不方便?

于是给了一个方案,或是说,前面的时候,那块还不能写变量?里面是硬编码写死的?

后面可以了.但是估计很多人还是旧写法,如果直接把这句加入params这个文件的前面话,就会可能跟nginx.conf中同时出现,了二次.就会导致很多莫名的问题,

有可能某些地方会用前面一个指令的路径,而另一个地方会可能用到后面一个指令.

所以,作者保留params,新加一个文件叫fastcgi.conf.

而我却刚好理解成这二个文件是相同的...但是因为没有提供这个指令,所以,导致没有文件发送到php gate中.那么.就返回了空白内容;;;;;;;



我晕死了....几个小时........一段历史......如果在fastcgi.conf上加几下注释说明,让粗心,没有仔细看的我就不会这么惨了....

cgi fastcgi wsgi isapi fastcgi fastcgi for iis nginx fastcgi pass

cgi fastcgi wsgi isapi fastcgi fastcgi for iis nginx fastcgi pass

诸如nginx apache这些web服务器致力于静态文件的的传输,一些数据需要计算才能获知,计算的程序都在web服务器背后,所以这时web服务器也扮演了反向代理服务器的角色。
既然web服务器和后台计算程序分作两个进程,进程之间的通信必然要遵从一个协议,这个协议就是通用网关协议
cgi = common gateway interface
cgi方式在对于每个http请求,web宿主服务程序都建立新的进程以调用服务器脚本,相应该请求,处理完后结束这个子进程。这就是fork-and-execute模式。所以用cgi方式的服务器有多少连接请求就会有多少cgi子进程,子进程反复加载是cgi性能低下的主要原因。当用户请求数量非常多时,会大量挤占系统的资源如内存,cpu时间等,造成效能低下。

FCGI = Fast CGI

它其实是CGI在具体实现中的的一个变种。FCGI在规范上跟CGI并没有不同,通过减少CGI代理程序和Web宿主服务程序的通信开销。FCGI建立一个独立的FCGI服务程序进程,和Web宿主服务程序进程通信,FCGI服务进程被一旦启动后,自己分配资源、创建线程响应HTTP请求、并决定自身生命周期,从而大大降低了系统为了创建进程而做出的资源开销。现代流行的Web服务器程序,如PHP、ASP.Net,基本都是FCGI的实现。他还是支持分布式的运算,即FastCGI程序可以在网站服务器以外的主机上执行并且接受来自其他网站服务器来的请求。

FastCGI比GI的特点就是后面的计算程序从web服务进程中独立出来,可以常驻内存,可以分布式部署。

SCGI = Simple CGI

它是FCGI在精简数据协议和响应过程后的产物。其设计目的是为了适应越来越多基于AJAX或REST的HTTP请求,而做出更快更简洁的应答。并且SCGI约定,当服务器返回对一个HTTP协议请求响应后,立刻关闭该HTTP连接。所以不难看出,SCGI更加适合于普遍意义上SOA所提倡的“请求-忘记”这种通信模式。

WSGI = Web Server Gateway Interface

当Web Server收到一个请求后,可以通过Socket把环境变量和一个Callback回调函数传给后端Web应用,Web应用在完成页面组装后通过Callback把内容返回给Web Server。这样做的优点有很多:

  • 异步化,通过Callback将Web请求的工作拆解开,可以很方便的在一个线程空间里同时处理多个Web请求。
  • 方便进行各种负载均衡和请求转发,不会造成后端Web应用阻塞。

此协议是Python语言的专利,它定义了一组在Web服务宿主程序和HTTP响应代理程序之间通信的普遍适用的接口。它的产生是因为Python程序员注意到,对于Web框架和Web宿主服务器程序间,有严重的耦合性,比如说,某些框架是针对Apache的mod_python设计的。于是,WSGI就定义了一套非常低级别的接口。常见的Python Web框架都实现了这个协议:如 CherryPy, Django, web.py, web2py, TurboGears, Tornado, Pylons, BlueBream, Google App Engine[dubious – discuss], Trac, Flask, Pyramid,等等.

以上就介绍了cgi fastcgi wsgi,包括了fastcgi方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

django – nginx和uWSGI给出“504网关超时”

django – nginx和uWSGI给出“504网关超时”

我正在遵循教程Setting up Django and your web server with uWSGI and nginx.

uWsgi正在运行

我设置了uwsgi来为我的Django项目提供以下一行.

mydjangoproj $uwsgi --http 0.0.0.0:8002 --module wsgi --harakiri 5

当我在浏览器中去那里的时候,这个工作是42.42.42.42:8002.

我的Nginx设置

Nginx作为守护进程运行,访问它的默认站点,80端口,工作.

我使用以下mydjangoproj_Nginx.conf文件将其添加到Nginx的一个站点:

server {
    listen      8000;
    server_name 42.42.42.42;
    charset     utf-8;
    client_max_body_size 75M;

    location /static {
        alias /home/myuser/mydjangoproj/static; 
    }

    location / {
        uwsgi_pass 127.0.0.1:8002;
        include     /home/myuser/mydjangoproj/uwsgi_params;
    }
}

我使用uwsgi_params的未修改版本,从教程:

uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;

它完美地为静态文件提供服务.

错误

如果我访问42.42.42.42:8000它挂了很长时间,直到Nginx超时我猜,我得到504网关超时.

uWsgi在shell中不写.如果直接访问浏览器,它会写入关于接收请求.

Nginx错误日志只写入超时后:

2014/12/11 05:31:12 [error] 28895#0: *1 upstream timed out (110: Connection timed out) while reading response header from upstream,client: 66.66.66.66,server: 42.42.42.42,request: "GET / HTTP/1.1",upstream: "uwsgi://42.42.42.42:8002",host: "42.42.42.42:8000"

如果我关闭刚刚从shell运行的uWsgi,我马上就会得到一个502 Bad Gateway.

在线搜索时,人们只是建议将uWsgi超时设置为低于Nginx超时,这就是为什么我用–harakiri 5运行uWsgi.

那么这里有什么问题呢?

最佳答案
我认为你在http模式下运行uwsgi –http 0.0.0.0:8002但是您已经配置了Nginx,因为wsgi代理将您的uwsgi脚本更改为:

 uwsgi --socket :8002 --module wsgi --harakiri 5

注意,如果你在同一台机器上运行Nginx和uwsgi,最好使用unix sockets

关于如何在 Nginx 上使用 FastCGI 防止网关超时nginx504网关超时的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于c-Nginx fastcgi多线程、centos+nginx+php-fpm+php include fastcgi_params php页面能访问但空白,被fastcgi_params与fastcgi.conf害惨了、cgi fastcgi wsgi isapi fastcgi fastcgi for iis nginx fastcgi pass、django – nginx和uWSGI给出“504网关超时”的相关知识,请在本站寻找。

本文标签: