nginx安装、进程结构、热升级详解

nginx安装

rpm包安装

http://nginx.org/en/linux_packages.html#RHEL-CentOS 官方预制包 http://nginx.org/packages/centos/7/x86_64/

 1]$ vim /etc/yum.repos.d/nginx.repo
 2内容如下
 3[nginx-stable]
 4name=nginx stable repo
 5baseurl=http://nginx.org/packages/centos/7/x86_64/
 6gpgcheck=1
 7enabled=1
 8gpgkey=https://nginx.org/keys/nginx_signing.key
 9
10]$ yum repolist  //    已经有了nginx 的仓库
11]$ yum info nginx //最新稳定1.14版本
12]$ yum install nginx

编译安装

 1#创建nginx  系统用户、用户组
 2groupadd  -r -g 108  nginx     //组号 108
 3useradd -r  -g 108   nginx
 4#安装常用的
 5 yum -y install gcc gcc-c++ autoconf automake libtool make cmake
 6 #安装在这个目录下
 7 cd    /usr/local/src/
 8#安装  nginx  需要的 
 9yum -y install zlib zlib-devel openssl openssl-devel pcre-devel
10# 下载稳定版的nginx
11wget http://nginx.org/download/nginx-1.10.0.tar.gz
12
13tar -zxvf    nginx-1.10.0.tar.gz
14cd  nginx-1.10.0
15./configure  \
16--prefix=/usr/local/nginx \
17--sbin-path=/usr/sbin/nginx \
18--conf-path=/etc/nginx/nginx.conf \
19--error-log-path=/var/log/nginx/error.log \
20--http-log-path=/var/log/nginx/access.log \
21--pid-path=/var/run/nginx/nginx.pid \
22--lock-path=/var/lock/nginx.lock \
23--user=nginx \
24--group=nginx \
25--with-http_stub_status_module \
26--with-http_ssl_module \
27--with-http_flv_module \
28--with-http_gzip_static_module \
29--http-client-body-temp-path=/var/tmp/nginx/client/ \
30--http-proxy-temp-path=/var/tmp/nginx/proxy/ \
31--http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \
32--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \
33--http-scgi-temp-path=/var/tmp/nginx/scgi \
34--with-pcre
35make && make install
36/usr/sbin/nginx  #启动     我这里报错了说没这个目录
37mkdir    /var/tmp/nginx/client -p      # 再次启动
38/usr/sbin/nginx
39ps -aux | grep nginx   #查看是否启动
参数 含义
–prefix 安装目录
–user 运行worker子进程的属主
–group 运行worker子进程的属组
–with-pcre pcre模块, 正则表达式
1nginx -V #看编译参数
2./configure --help 

nginx 进程结构

nginx的基本架构

master进程、worker进行、cache loader进程、cache manager 进程

  1. Nginx启动后,会产生一个主进程,主进程执行一系列的工作后会产生一个或者多个工作进程
  2. 在客户端请求动态站点的过程中,Nginx服务器还涉及和后端服务器的通信。Nginx将接收到的Web请求通过代理转发到后端服务器,由后端服务器进行数据处理和组织;
  3. Nginx为了提高对请求的响应效率,降低网络压力,采用了缓存机制,将历史应答数据缓存到本地。保障对缓存文件的快速访问

master进程

master进程主要用来管理worker进程,具体包括以下主要功能:

(1)接收来自外界的信号。

(2)处理配置文件读取。

(3)创建,绑定和关闭套接字

(4)启动,终止和维护配置的工作(worker)进程数

(5)当woker进程退出后(异常情况下),会自动重新启动新的woker进程。

worker进程

worker进程的主要任务是完成具体的任务逻辑。其主要关注点是与客户端或后端真实服务器(此时nginx作为中间代理)之间的数据可读/可写等I/O交互事件。

(1)接收客户端请求;

(2)将请求一次送入各个功能模块进行过滤处理;

(3)与后端服务器通信,接收后端服务器处理结果;

(4)数据缓存

(5)响应客户端请求

缓存相关的进程

(1)cache loader:载入缓存对象

(2)cache manager:管理缓存对象

常用命令及控制信号

1、查看Nginx的版本号:nginx -V

2、停止 nginx -s stop

3、退出 nginx -s quit

4、重启加载配置 nginx -s reload

5、配置文件启动 nginx -c </path/to/config> 为 Nginx 指定一个配置文件

6、nginx -t 不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。

再次回过头看看nginx的原理图,我们还可以通过信号,去操作nginx,默认,nginx 将其主进程的 pid 写入到 /usr/local/nginx/nginx.pid 文件中

TERM, INT 快速关闭 nginx -s stop
QUIT 从容关闭 nginx -s quit
HUP 重载配置 用新的配置开始新的工作进程 从容关闭旧的工作进程 nginx -s reload
USR1 重新打开日志文件 nginx -s reopen
USR2 平滑升级可执行程序。
WINCH 从容关闭工作进程

nginx停止命令,等所有请求结束后关闭服务

	kill -QUIT  nginx主进程号

重新载入配置

	kill -HUP  nginx主进程号

worker进行宕掉,发送 sigchld 信号给 master进程

master进程管理work进程 接受信号

nginx -s reload 执行过程

  • 向master 进程 发送 HUP 信号 ,或reload 命令

  • master进程 检测配置文件语法是否正确

  • master进程打开监听端口

  • master 启动新的worker进程

  • master进程向老的work进程发送quit信号

  • 老的work进程 关闭监听句柄,处理完当前链接后 关闭进程

热升级

拿增加一个模块举例

给安装过的nginx 增加模块(半自动平滑升级)

半自动平滑升级

所谓半自动,其实就是在最后迁移的时候使用源码自带的升级命令:make upgrade 来自动完成

 1
 2# 新下载的nginx 目录 /usr/local/src/nginx-1.10.0
 3
 4#新增 --add-module=/usr/local/src/ngx_cache_purge-2.3  模块
 5
 6# 第一步:需要下载对应的需要加载的第三方的扩展,或者是需要附加设置的参数  (注意:之前的配置参数要保留)
 7sudo  ./configure --prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client/ --http-proxy-temp-path=/var/tmp/nginx/proxy/ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre --add-module=/usr/local/src/ngx_cache_purge-2.3
 8
 9# 第二步: 执行make不要执行make install 
10sudo make 
11
12# 第三步: 重命名 nginx 旧版本二进制文件,即 sbin 目录下的 nginx(期间 nginx 并不会停止服务)
13sudo mv  /usr/sbin/nginx /usr/sbin/nginx_bak
14
15# 第四步: 然后拷贝一份新编译的二进制文件到安装目录
16cd /usr/local/src/nginx-1.10.0
17sudo cp objs/nginx /usr/sbin/
18 
19# 第五部: 在源码目录执行 make upgrade 开始升级:
20sudo  make upgrade
21
22
23# 升级成功
24/usr/sbin/nginx -t
25#nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
26#nginx: configuration file /etc/nginx/nginx.conf test is successful
27
28
29kill -SIGUSR2 `cat /var/run/nginx/nginx.pid`
30
31# sleep 1
32# test -f /var/run/nginx/nginx.pid.oldbin 
33
34
35kill -SIGWINCH   `cat /var/run/nginx/nginx.pid.oldbin`  # 先关闭工作进程看看 是否 新的nginx 的 worker进程是否可行, 可行的 就执行 
36kill -SIGQUIT `cat /var/run/nginx/nginx.pid.oldbin`
37# 如果不可行   ,就让老的master进程再加载出  worker进程来 。
38kill -SIGHUP `cat /var/run/nginx/nginx.pid.oldbin`  

模块化管理机制

高度模块化,但其模块早期不支持DSO机制;近期版本支持动态装载和卸载; 模块分类:

  • 核心模块:core module
  • 标准模块:
    • HTTP modules:
      • Standard HTTP modules
      • Optional HTTP modules
    • Stream modules 传输层代理
    • Mail modules 邮件相关模块`
  • 3rd party modules:第三方模块

nginx的功用

  • 静态的web资源服务器;(图片服务器,或js/css/html/txt等静态资源服务器)
  • 结合FastCGI/uwSGI/SCGI等协议反代动态资源请求;
  • http/https协议的反向代理;
  • imap4/pop3协议的反向代理;
  • tcp/udp协议的请求转发;

IO复用/EventLoop

1、IO复用是什么

IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程,目前支持I/O多路复用的系统调用有 select,poll,epoll,I/O多路复用就是通过一种机制,一个进程可以监视多个描述符(socket),一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。

2、Select跟poll

Select介绍:

监视并等待多个文件描述符的属性变化(可读、可写或错误异常)。select函数监视的文件描述符分 3 类,分别是writefds、readfds、和 exceptfds。调用后 select会阻塞,直到有描述符就绪(有数据可读、可写、或者有错误异常),或者超时( timeout 指定等待时间),函数才返回。当 select()函数返回后,可以通过遍历 fdset,来找到就绪的描述符,并且描述符最大不能超过1024

poll 介绍:

poll的机制与select类似,与select在本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数量的限制。poll和select同样存在一个缺点就是,包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,它的开销随着文件描述符数量的增加而线性增大。

问题:

select/poll问题很明显,它们需要循环检测连接是否有事件。如果服务器有上百万个连接,在某一时间只有一个连接向服务器发送了数据,select/poll需要做循环100万次,其中只有1次是命中的,剩下的99万9999次都是无效的,白白浪费了CPU资源。

3. epoll

epoll是在2.6内核中提出的,是之前的select和poll的增强版本。相对于select和poll来说,epoll更加灵活,没有描述符限制,无需轮询。epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中。

简单点来说就是当连接有I/O流事件产生的时候,epoll就会去告诉进程哪个连接有I/O流事件产生,然后进程就去处理这个进程。

这里可以多加一个选择nginx的原因,因为Nginx是基于epoll的异步非阻塞的服务器程序。自然,Nginx能够轻松处理百万级的并发连接,也就无可厚非了。

那么我们也可以基于epoll,实现 IO复用异步非阻塞(eventloop或者叫Reactor),Event 是核心,Loop 是机制,Loop 可以用select/poll/epoll/中的任意方式,实现。

IO复用异步非阻塞程序使用经典的Reactor模型,Reactor顾名思义就是反应堆的意思,它本身不处理任何数据收发。只是可以监视一个socket(也可以是管道、eventfd、信号)句柄的事件变化。

注:什么是句柄?句柄英文为handler,可以形象的比喻为锅柄、勺柄。也就是资源的唯一标识符、资源的ID。通过这个ID可以操作资源。

Reactor只是一个事件发生器,实际对socket句柄的操作,如connect/accept、send/recv、close是在callback中完成的。