现在我们主要介绍下nginx的静态配置,并在最后搭建基于nginx的php网页访问服务以及文件访问服务。接上文安装指南中,默认的配置文件为/usr/local/nginx/conf/nginx.conf,其部分代码如下:
user root;
worker_processes 2;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
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"'
分一下几个模块:
1.进程配置
进程配置指令不属于任何配置模块,只能在全局域里配置,主要的参数有:
worker_processes:
表示worker进程数,默认为1,通常情况下设定数目与CPU核心数相等,此时每个worker都工作在一个独立的CPU核心上,完全消除调度成本,当然这里需要参数worker_cpu_affinity的配合,例如如下设置
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
这里表示有4个进程,分别运行在CPU核0/1/2/3上,每一个CPU核用一位掩码表示,如果是两个进程分别运行在两个CPU核上就表示为:
worker_processes 2;
worker_cpu_affinity 0101 1010;
即进程1运行在核0/2上,进程2运行在核1/3上。8进程分别在8个CPU核上表示为:
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
master_process on | off:
表示Nginx是否启动进程池,默认是ON否则就不会建立master进程,并发性大大下降。以我们实验的物理机为例我们设置worker_processes 为2,输入 ps aux|grep nginx结果如下:
root 3648 0.0 0.0 24916 464 ? Ss 11:43 0:00 nginx: master process /usr/local/nginx/sbin/nginx
root 3649 0.0 0.0 25296 2564 ? S 11:43 0:00 nginx: worker process
root 3650 0.0 0.0 25296 2564 ? S 11:43 0:00 nginx: worker process
root 4001 0.0 0.0 21312 1020 pts/18 S+ 11:47 0:00 grep --color=auto nginx
可以看到会启动一个master进程和两个worker进程。
daemon on | off:
是否以守护进程的方式运行nginx,默认是on,注意在docker中要设为off,其原理和意义后续会详细介绍。
working_directory path;
配置Nginx的工作目录,这里存放的是coredump文件,在发生意外崩溃时可以用gdb调试查找原因。
worker_shutdown_timeout time;
表示停止运行时,Nginx将最多等待多久时间后强制关闭进程。
2.动态模块配置
load_module file;
该模块主要是用来运行时动态加载模块,而不必重新./configure && make && make install,动态加载模块的个数限制则为128个,如果已经加载的动态模块有修改,那么必须重起Tengine才会生效,并且只支持http模块。file为模块名,可以是绝对路径也可以是相对路径,默认查找路径为:/usr/local/nginx目录。load_module同样需要全局配置。
3.运行日志配置
error_log file|stderr level;
access_log file|stderr level;
日志主要分为两种:TCP/HTTP访问请求的access_log和记录服务器错误信息的error_log,默认为安装目录下的文件/usr/local/nginx/logs/access.log和/usr/local/nginx/logs/error.log。参数二level是日志的允许输出级别。
4.events配置
Nginx采用事件驱动,利用内核提供的epoll、kqueue来高效处理网络连接,events用来配置Nginx的事件驱动机制。
use_method;
处理事件的方式,linux下可选择select、poll和epoll,其中epoll在大请求量下是最高效的,这是Nginx的默认设置,故一般无需修改。windows下可使用select和iocp,iocp通常最高效,且为默认。
accept_mutex on | off;
是否开启负载均衡,可以使多个worker进程的工作量更均匀,但锁的成本较高,很影响效率。默认为off,不启用负载均衡。不过现在的Nginx还可以使用内核级别的负载均衡技术,如EPOLLEXCLUSIVE或reuseport。
worker_connections number;
work进程可以处理的最大连接数。
5.http配置
这部分比较复杂,这里我们通过介绍搭建php网页服务和文件访问服务来介绍其基础功能,Nginx通过使用http块配置http相关所有的功能,包括cache、fastcgi、gzip、sever、location、proxy、upstream等。直接给出一个配置了http的php服务和文件访问服务的例子:
http {
include mime.types;
default_type application/octet-stream;
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
root /home/data/ngnix/php_study/www;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
#root php;
index index.php index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/data/ngnix/php_study/www$fastcgi_script_name;
include fastcgi_params;
}
}
autoindex on;
autoindex_exact_size on;
autoindex_localtime on;
server {
listen 8080 default_server;
listen [::]:8080 default_server;
server_name _;
root /home/data/filedown/;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
server配置:server指令定义一个虚拟主机,它必须是一个配置模块,使用server指令定义一个虚拟主机,其必须是一个配置模块,在块内部使用其他指令来确定主机的端口号、域名等参数,这样Nginx就可以对外提供Web服务了。
listen port设置虚拟主机监听的端口,默认是80,同样IP地址、SSL、recvbuf/sndbuf、HTTP2.0都可以通过listen设置来支持,server_name设置虚拟主机对外提供服务的主机名称。
location通过指定模式来与客户端请求的URI相匹配,基本语法如下:location [=|~|~*|^~|@] pattern{……},规则如下:
~ #波浪线表示执行一个正则匹配,区分大小写;
~* #表示执行一个正则匹配,不区分大小写;
^~ #^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录;
= #进行普通字符精确匹配;
@ #"@" 定义一个命名的 location,使用在内部定向时,例如 error_page, try_files。
下面我们通过一个php网页服务,结合上面的配置文件,来具体解释下server模块的功能,要实现php网页服务必须要安装一些必要的软件:
#安装程序包
sudo apt-get install php7.2
sudo apt-get install php7.2-fpm
sudo apt-get install nginx
#安装必要依赖
sudo apt-get install php-json
sudo apt-get install php-curl
sudo apt-get install php7.2-mysql
sudo apt-get install php7.2-cgi
配置php-frm
sudo gedit /etc/php/7.2/fpm/php.ini
#修改参数如下:
# 778行 ;cgi.fix_fathinfo=1 更改为 cgi.fix_fathinfo=0
nginx 是一个高性能的http服务器和反向代理服务器。即nginx可以作为一个HTTP服务器进行网站的发布处理,也可以作为一个反向代理服务器进行负载均衡。但需要注意的是:nginx本身并不会对php文件进行解析。对PHP页面的请求将会被nginx交给FastCGI进程监听的IP地址及端口,由php-fpm(第三方的fastcgi进程管理器)作为动态解析服务器处理,最后将处理结果再返回给nginx。即nginx通过反向代理功能将动态请求转向后端php-fpm,从而实现对PHP的解析支持,这就是Nginx实现PHP动态解析的基本原理。 一些基本的概念(nginx + php-fpm +fastcgi):
1)Nginx 是非阻塞IO & IO复用
模型,通过操作系统提供的类似 epoll 的功能,可以在一个线程里处理多个客户端的请求。Nginx 的进程就是线程,即每个进程里只有一个线程,但这一个线程可以异步地同时服务多个客户端,即不管上一个请求有没有处理完,可以不断接收新的请求。
2)PHP-FPM 是阻塞的单线程模型,pm.max_children
指定的是最大的进程数量,pm.max_requests
指定的是每个进程处理多少个请求后重启(因为 PHP 偶尔会有内存泄漏,所以需要重启)。PHP-FPM 的每个进程也只有一个线程,但是一个进程同时只能服务一个客户端,即必须处理完一个完整的请求之后,才能处理下一次请求。
3)fastCGI :为了解决不同的语言解释器(如php、python解释器)与webserver的通信,于是出现了cgi协议。只要你按照cgi协议去编写程序,就能实现语言解释器与webwerver的通信。如php-cgi程序。但是webserver每收到一个请求,都会去fork一个cgi进程,请求结束再kill掉这个进程。这样有10000个请求,就需要fork、kill php-cgi进程10000次。 fastcgi是cgi的改良版本。fast-cgi每次处理完请求后,不会kill掉这个进程,而是保留这个进程,使这个进程可以一次处理多个请求。大大提高了效率。
我们看第一个server中location的配置:
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/data/ngnix/php_study/www$fastcgi_script_name;
include fastcgi_params;
}
location ~ \.php表示大小写敏感处理php请求。
fastcgi_pass 表示fastcgi绑定的地址和端口。
fastcgi_param SCRIPT_FILENAME表示脚本文件请求的路径,也就是说当访问127.0.0.1/*.php的时候,需要读取网站根目录下面的名字为*.php的文件,没有则返回错误,显然这里会在目录/home/data/ngnix/php_study/www中读取。
以127.0.0.1:80/A/B?c=1&d=4为例,当该http请求到来时,解析过程如下:
1.nginx收到http请求,根据监听的端口号匹配到相应server;
2.对收到的URI进行匹配,匹配到location / ,在这个匹配规则中,通过try_files 先在root目录(/home/data/ngnix/php_study/www)找是否有对因文件;若没有,再查找root目录下是否有$uri/目录;同样没有匹配到,则匹配最后一项/index.php?$args,即发出一个"内部子请求",也就相当于nginx发起了一个http请求到127.0.0.1:80/index.php?c=1&d=4
3.这个子请求会被location ~ \.php${ ... }
catch住,也就是进入 FastCGI 的处理程序,nginx需要通过FastCGI模块配置,将相关php参数传递给php-fpm处理。在该项中设置了fastcgi_pass相关参数,将用户请求的资源发给php-fpm进行解析。
将php文件,例如php_info.php放在目录/home/data/ngnix/php_study/www下,即可通过http://127.0.0.1/php_info.php访问。
接下来看下静态文件访问配置,即file配置,对应的是另一个server模块:
server {
listen 8080 default_server;
listen [::]:8080 default_server;
server_name _;
root /home/data/filedown/;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
文件访问的配置很简单,主要涉及如下几个参数:
root path;
请求文档的根目录,以path作为其实路径查找文件。完成该配置后,我们可以通过http://127.0.0.1:8080/以静态网页方式访问目录/home/data/filedown/。