了解Nginx
nginx会以daemon的方式在后台运行。后台进程包含一个master进程和多个worker进程。
master进程:
主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程
worker进程:
处理基本的网络事件,各进程互相之间是独立的。worker进程的个数,一般与机器cpu核数一致.
Nginx 的进程模型
从进程模型图可以看出,我们想要操作nginx,只需要与master通信即可。
master进程在接受信号是怎么做的呢?
输入如下命令行
1 | kill -HUP pid |
这个命令是优雅地重启nginx。当master进程收到信号后,因为是优雅地重启,所以服务器不会中断。而是重新加载配置文件,然后新开worker进程,再向旧的worker进程发送关闭指令。这种直接发送信号给master进程的操作方式已经显得有些老了,在0.8版本后,引入了一系列命令行参数。
如
1 | nginx -s reload |
这是一个重新加载配置的命令。在执行命令时,它会向master进程发送信号,同样也是启动一个新的worker进程,再关闭掉旧的worker进程。
worker 进程又是怎么做的??
首先,在master进程里,比方说一个80端口的http服务,会建立好需要listen的sokcet(listenfd),然后再fork出多个worker进程。在新的请求到来时,所有worker进程的listenfd变为可读,然后开始抢锁,抢到互斥锁的那个进程注册listenfd读事件,在读事件里调用accept接受该连接,开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端。一个请求,完全由worker进程来处理,而且只在一个worker进程中处理。
好处:独立进程,不需要加锁,所以省掉了锁带来的开销。其次,worker进程间互相之间不会影响。
nginx事件模型
对于一个基本的web服务器来说,事件通常有三种类型,网络事件、信号、定时器。
网络事件
nginx采用了异步非阻塞的方式来处理请求,可以同时处理成千上万个请求。
请求的完整过程:请求过来,建立连接,然后再接收数据,接收数据后,再发送数据。具体到系统底层,就是读写事件,而当读写事件没有准备好时,必然不可操作。
| 网络事件模型 | 说明 |
|---|---|
| 阻塞式 | 事件没准备好,等。在等待中,cpu会让出去。 那么,会造成,网络事件一多,大家都在等,cpu都让出去了但是没人用,cpu使用率都不高,还谈高并发??? 尤其是单线程的worker了,更不合适。 |
| 非阻塞式 | 事件没准备好,马上返回EAGAIN,然后间断性再次访问,直到事件准备完成。 好处是确实可以做更多其他的事情,但开销也增加了。 |
| 异步非阻塞 | 对于事件,它是阻塞的。但是,它不是盲目的等待,而是设定了一段超时时间。 在超时时间内事件准备好了,就返回 |
以epoll(一个异步非阻塞机制的函数)为例:
1 当事件没准备好时,放到epoll里面;
2 事件准备好了,就去读写;
3 当读写返回EAGAIN时,将它再次加入到epoll里面;
4 线程只有一个,所以只能处理一个请求。但可以在请求里切换,再多的并发数,zhi会占用更多的内存而已;
所以说,worker数等于cpu数的原因。就是因为如此,反而事更多的worker数,只会导致cpu资源的竞争,从而带来不必要的上下文切换。
信号
信号会中断掉程序当前的运行,在改变状态后,继续执行。如果是系统调用,则可能会导致系统调用的失败,需要重入。关于信号的处理,大家可以学习一些专业书籍,这里不多说。对于nginx来说,如果nginx正在等待事件(epoll_wait时),如果程序收到信号,在信号处理函数处理完后,epoll_wait会返回错误,然后程序可再次进入epoll_wait调用。
Nginx定时器
由于epoll_wait等函数在调用的时候是可以设置一个超时时间的,所以nginx借助这个超时时间来实现定时器。nginx里面的定时器事件是放在一颗维护定时器的红黑树里面,每次在进入epoll_wait前,先从该红黑树里面拿到所有定时器事件的最小时间,在计算出epoll_wait的超时时间后进入epoll_wait。所以,当没有事件产生,也没有中断信号时,epoll_wait会超时,也就是说,定时器事件到了。这时,nginx会检查所有的超时事件,将他们的状态设置为超时,然后再去处理网络事件。由此可以看出,当我们写nginx代码时,在处理网络事件的回调函数时,通常做的第一个事情就是判断超时,然后再去处理网络事件。
Nginx事件处理伪代码
1 | while (true) { |
Connection
在nginx中connection就是对tcp连接的封装,其中包括连接的socket,读事件,写事件
安装
一、安装编译工具及库文件
1 | yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel |
二、首先要安装 PCRE
PCRE 作用是让 Nginx 支持 Rewrite 功能。
1、下载 PCRE 安装包,下载地址: http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
1 | [root@bogon src] |
2、解压安装包:
1 | [root@bogon src]# tar zxvf pcre-8.35.tar.gz |
3、进入安装包目录
1 | [root@bogon src] |
4、编译安装
1 | [root@bogon pcre-8.35] |
5、查看pcre版本
1 | [root@bogon pcre-8.35] |
三、安装 Nginx
1、下载 Nginx,下载地址:http://nginx.org/download/nginx-1.6.2.tar.gz
1 | [root@bogon src] |
2、解压安装包
1 | [root@bogon src]# tar zxvf nginx-1.6.2.tar.gz |
3、进入安装包目录
1 | [root@bogon src]# cd nginx-1.6.2 |
4、编译安装
1 | [root nginx-1.6.2]# ./configure --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/usr/local/src/pcre-8.35 |
5、查看nginx版本
1 | [root@bogon nginx-1.6.2]# /usr/local/webserver/nginx/sbin/nginx -v |
到此,nginx安装完成。
Nginx 配置
创建 Nginx 运行使用的用户 www:
1 | [root@bogon conf] |
配置nginx.conf ,将/usr/local/webserver/nginx/conf/nginx.conf替换为以下内容
1 | [root@bogon conf]# cat /usr/local/webserver/nginx/conf/nginx.conf |
配置文件详解
1 | ########### 每个指令必须有分号结束。################# |
检查配置文件nginx.conf的正确性命令:
1 | [root@bogon conf]# /usr/local/webserver/nginx/sbin/nginx -t |
修改完conf文件,则应重启nginx软件(不推荐)
systemctl restart nginx
一般重新加载nginx软件
systemctl reload nginx
然后关闭防火墙
systemctl stop firewalld
开机启动nginx
systemctl enable nginx
关闭开机启动nginx
systemctl disable nginx
防火墙同理