看看一次请求到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解释器。
缺陷:
- 更改php.ini配置后需要重启php-cgi进程,且会杀死正在运行的进程。
- 单进程,不具备进程管理能力,效率很低。
PHP-FPM
概念:一个实现FastCGI多进程(进程池)管理的管理器。开启之后,会看到多个php-cgi进程,它们都由php-fpm管理。
一些进步:
- 修改配置后,平滑过渡,新的worker进程使用新的配置,正在运行的worker进程处理完当前请求后自动shutdown
- 多进程的效率比单进程更高
看一看一些相关的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; } }