看看一次请求到Webserver发生了什么

  • 一个静态请求,webserver会找一下本地有没有存这个file,有就直接返回给client
  • 一个动态请求,不同于寻常的.js .css,需要一个可以读懂这个请求的解释器来帮助我们一下

CGI(Common Gateway InterFace)

既然webserver想把这个请求交给可以处理的人来做,是不是该告诉人家一些基本的,并且人家看得懂的信息信息?

Webserver会传那些基本信息给后端处理请求的解析器呢?url,get请求的query_string,POST数据,Http Header等,那么CGI就规定了要传哪些参数,以及以一个什么样的格式传过去,后端处理完这个请求,又该以什么样的格式传回。

概念:CGI(Common Gateway Interface)全称是“通用网关接口”,WEB 服务器与PHP应用进行“交谈”的一种工具,其程序须运行在网络服务器上。CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。也就是说,CGI用来在web服务器与后端实现了CGI协议的程序之间提供一个沟通的桥梁,降低两者之间的耦合性。

缺陷:采用了效率低下的"FE"模式,就是Fork-And-Execute,每个web请求进来之后,都会启动一个php程序,处理完请求后退出,浪费资源,高请求数下,服务器宕机。

FastCGI

有没有效率更高的解决办法呢,可以不可一完事先别走呢?

这就衍生出了FastCGI,也可以理解为一种协议,在CGI协议上进行强化,从原来的"FE"模式进化为"LL"模式,即Long-Live模式,运行完毕之后,常驻内存。同样,它也是语言无关性的,只要你具有标准输入输出和环境变量,那么就OK。

FastCGI会先启动一个Master进程,Master读取和处理基础的配置文件,初始化环境,之后依据配置生成多个worker进程来处理请求。并且可以动态调整worker的数量。

PHP-CGI

Fast-cgi听起来很不错,有没人用用它的呀?php-cgi是实现FastCGI协议的php解释器。

缺陷:

  1. 更改php.ini配置后需要重启php-cgi进程,且会杀死正在运行的进程。
  2. 单进程,不具备进程管理能力,效率很低。

PHP-FPM

概念:一个实现FastCGI多进程(进程池)管理的管理器。开启之后,会看到多个php-cgi进程,它们都由php-fpm管理。

一些进步:

  1. 修改配置后,平滑过渡,新的worker进程使用新的配置,正在运行的worker进程处理完当前请求后自动shutdown
  2. 多进程的效率比单进程更高

看一看一些相关的Nginx配置,能不能得到一些启发

比较重要的配置,去查看conf/nginx.conf

#nginx开启两个进程处理请求,设置为cpu数是一个好的开始
worker_processes  2;
#更改worker进程的最大打开文件数,超过会报"too many open files"
worker_rlimit_nofile 8192;

#记录错误日志位置以及级别
error_log   "/log"   notice;
pid         "nginx.pid";

events {
    #设置复用客户端轮询的方法
    use epoll;
    #一个worker进程同时打开文件的最大连接数
    worker_connections  8192; 
}

http {
    #MIME的类型
    include       mime.types; 
    #include       upstream.conf;
    default_type  application/octet-stream;

    log_format  main  '';

    #访问记录
    access_log  "xxx/access_log"  main;

    client_body_temp_path xxx/webserver/cache/client_body;
    fastcgi_temp_path xxxx/cache/fastcgi;
    proxy_temp_path xxxx/cache/proxy;
    uwsgi_temp_path xxxxx/cache/uwsgi;
    scgi_temp_path xxxxx/sscache/scgi;

    server_names_hash_bucket_size 128;
    client_header_buffer_size 4k;
    large_client_header_buffers 4 32k;
    #客户端上传文件最大体积(线上目前8M,所以当做视频上传分块,一块应该不会超过8M)
    client_max_body_size 4m;
    client_body_buffer_size 513k;

    #请求头和请求体超时时间
    client_body_buffer_size 8k;
    client_body_timeout 15;
    client_header_timeout 10;
    #客户端响应超时时间,两次客户端都操作如果超过240s,关闭连接
    send_timeout 240;

    sendfile        on;
    #告诉nginx在一个数据包里发送所有头文件,而不一个接一个的发送
    tcp_nopush      on;
    #告诉nginx不要缓存数据,而是一段一段的发送--当需要及时发送数据时,就应该给应用设置这个属性,这样发送一小块数据信息时就不能立即得到返回值。
    tcp_nodelay     on;

    #fastcgi相关设置 连接超时,发送数据,读取数据等
    fastcgi_connect_timeout 5;
    fastcgi_send_timeout 10;
    fastcgi_read_timeout 10;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;
    fastcgi_intercept_errors on;

    #给客户端分配keep-alive链接(长链接)超时时间。服务器将在这个超时时间过后关闭链接。我们将它设置低些可以让ngnix持续工作的时间更长。
    keepalive_timeout  0;
    #keepalive_timeout  65;

    #采用gzip压缩形式发送数据,减少发送数据量,有助于提速
    gzip on;
    # gzip_static on;查找是否有gzip预先处理过的文件
    #启用压缩最小字节数
    gzip_min_length 1k;
    #gzip_proxied any;压缩所有,包括请求和响应
    #存储压缩数据流的缓存大小 4 * 16k
    gzip_buffers 4 16k;
    #识别http协议的版本号
    gzip_http_version 1.0;
    #数据压缩等级,1-9,9最慢,压缩比最高
    gzip_comp_level 2;
    #需要压缩的数据格式
    gzip_types text/plain application/x-javascript text/css application/xml;
    #给代理服务器用
    gzip_vary on;

    #文件编码
    #charset UTF-8;

    #相关代理的配置
    proxy_connect_timeout 15s;
    proxy_read_timeout 24s;
    proxy_send_timeout 10s;
    proxy_buffer_size 64k;
    proxy_buffers 4 64k;
    proxy_busy_buffers_size 128k;
    proxy_temp_file_write_size 128k;
    proxy_set_header LOGID $logid;
    proxy_set_header Host $http_host;
    uninitialized_variable_warn off;

    set_real_ip_from xxxx;
    real_ip_header CLIENTIP;
    #这里php.conf文件内的内容也可以直接写在nginx.conf中
    include vhost/php.conf;
}

  

来看看nginx http-server部分的配置

server {
    listen              8202;#监听端口
    server_name         xxxx;#服务器域名
    more_set_headers    'Server: Dr.Jian Nginx';
    set $php_upstream 'unix:xxxxx/php-cgi.sock';转发请求到php-cgi的socket,这里使用的是本地unix socket,当然也可以用其他服务器的TCP/IP socket或者本机TCP/IP socket
    #set $php_upstream 'unix:xxxx/hhvm.sock';
#   统一配置全局的rewrite规则请打开如下配置项,并配置当前目录下的rewrite文件
    include             vhost/rewrite;

    underscores_in_headers on;
    logid_name x_bd_logid;

    location ~* /((.*)\.(.*)\/(.*)\.php){
        deny all;
    }

    location ~* /\.(sql|bak|inc|old)$ {
        deny all;
    }

    #static
    location ~* \.(swf|flv|js|css|gif|jpg|jpeg|png|bmp|ico|htc)$ {
        root  xxxx/webroot;
        expires 30d;
    }

    location ~ ^/(favicon.ico|static) {
        root            xxxx/webroot;
    }

    location ~ \.php$ {
        root            xxxxx/webroot;
        fastcgi_pass    $php_upstream;
        fastcgi_index   index.php;
        include         fastcgi.conf;
    }

    location / {
        root xxx/webroot;
        index index.php;
        fastcgi_pass    $php_upstream;
        include         fastcgi.conf;
    }
}