Nginx知识系统梳理
一直以来配置Nginx的时候,都是直接百度谷歌,认识比较零碎。最近买书的时候顺了一本《精通Nginx》,在一个漫长的地铁旅途上扫了一遍,在快速地这里整理一下笔记。
买这本书就是因为页数少,而且新。但是再次印证,精通字样的书都不怎么地。。。尤其是译文本- -!~翻译者貌似搞不清楚信号和信号量的区别(见P106第二段末尾)
一、Nginx的来由
Nginx最初的设计是成为一个Http服务器,基于OS的事件处理机制来解决C10K(concurrent 10k connection)问题。
没想到社区反响很好,所以基于http模块后来又加了很多模块,比如mail,proxy, upstream等。
二、Nginx如何实现高并发
整本书都在讲配置,根本没有说明Nginx的原理,所以我在网上又花了些时间,搞明白这个问题。我们知道Nginx比Apche优秀的地方就是高并发。那么这个是如何实现的呢?
“Nginx包括一个单一的master进程和多个worker进程。所有这些进程都是单线程的,并且设计为同时处理成千上万个链接。”
好吧读完,这个我就懵了,既然这些进程都是单线程的,如何能够高并发?要知道Apache是多线程模式,每个线程处理一个连接,连接多了,线程数上去了,CPU资源就耗得差不多了。现在Nginx用单线程,那怎么实现高并发呢?
Nginx的设计是这样的,它的master进程负责读取配置文件、处理套接字、派生worker进程、打开日志文件和编译嵌入式Perl脚本。然后worker进程用来处理具体的请求。
父进程listen一个socket,然后派生的子进程继承这个socket,accept得到客户端连接请求的新的socket,进行后续工作。
奥妙就在worker进程,worker进程的主线程采用非阻塞IO的方式来循环处理多个事件,具体实现类似select,epoll机制。当某个事件I/0阻塞的时候,就继续执行其他事件,直到I/O条件具备,再继续运行。
好吧,就这么简单?Apache把阻塞I/O改一下不也可以吗?事实上Apache也做过这方面的尝试,但是历史包袱比较重,如果做成非阻塞I/O,很多之前的东西都不兼容了。
在Nginx的全局配置参数中,有两个与worker相关的,worker_process用来配置最大的worker进程数,worker_connections用来配置worker进程能接受的最大连接数。
如果一个worker中过多的事件都在等待,那么就多起几个worker,每个worker进程可以指定特定的CPU,这样可以充分地利用CPU多核特性。
三、配置指南
1.基本配置格式
<section>{<directive> <parameters> }
每条配置指令用“;”来结尾
2.Nginx全局配置
以下几个命令常用:user,worker_processes,error_log,pid,use,worker_connections
3.Http的server部分配置
很多,分类:
**客户端指令: client_开头的比如client_body_buffer_size, 还有keepalive开头的等
**文件I/O指令: aio, postpone_output等
**Hash指令
**Socket指令:lingering_timeout,send_timeout,tcp_nodelay等
4.虚拟serve部分
常用:
server{
listen 参数表见P23
server_name
}
5.Locations
用来做客户端URI地址匹配和内部重定向
location [modifier] uri {…}
location @name {...}
四、反向代理
reverse proxy是一个web服务器,它终结了客户端连接,并且生成一个新的连接。新的连接代表客户端向上游服务器(upstream)请求。以为upstream不能直接从client获得数据,因此reverse proxy要做一些从client到upstream传递数据的任务。
相关模块reverse proxy, upstream
配置命令:
proxy_pass
least_conn:激活负载均衡算法
Upstream的服务器可以包含多种类型:既然可以是远程服务器,又可以是本地的一个TCP端口监听者(如让Apache监听8080,Nginx把相关的路由到Apache上;再比如通过memcached模块路由memcached守护进程;或者fastcgi上游服务器)
upstream memcaches{
server 192.168.1.1:11211;
}
upstream fastcgi{
server 192.168.1.1:9000;
}
location / {
set $memcached_key “$uri?$args”;
memcached_pass memcaches;
fastcgi_pass fastcgis;
}
五、HTTP模块
1.server
指令server开始了一个新的context
2.log
log_format指明记录要记载的内容
3.文件查找
try_files $uri1 $uri2 $uri3;
4.limit指令
limit_conn指明共享内存的最大key-value连接数
5.约束访问
allow deny auth_basic auth_basic_user_file
6.预定义变量
系统定义了一些变量名,如
$https, $pid, $remote_addr, $remote_port, $remote_user
7.使用PHP-FPM
PHP-FPM使PHP内核接受连接,因此php可以通过它在FastCGI服务器下运行。
PHP-FPM自己也有master和worker进程。它使用FastCGI协议与其他服务进行通信。
Nginx有一个fastcgi模块,可以接受PHP-FPM,同样可以兼容任何FastCGI协议的服务。
就是这些了。