Nginx开发指南2:配置文件实现php和file配置实例

现在我们主要介绍下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/。

 

 

 

你可能感兴趣的:(微服务代码分析)