Nginx 架构和安装

Nginx官网:http://nginx.org
功能介绍:1、静态的web资源服务器html,图片,js,css,txt等 2、动态资源 http/https协议的反向代理
基础特性:
模块化设计,较好的扩展性 
高可靠性 支持热部署:不停机更新配置文件,升级版本,更换日志文件 
低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存 
event-driven,aio,mmap,sendfile
Web 服务相关的功能
虚拟主机(服务器)
支持 keep-alive和管道连接(利用一个连接做多次请求) 
访问日志(支持基于日志缓冲提高其性能) 
url rewirte 
路径别名 
基于IP及用户的访问控制 
支持速率限制及并发数限制 
重新配置和在线升级而无须中断客户的工作进程
Nginx 架构和进程
架构:分成master主进程和若干个worker子进程两层架构(cpu有几个核,就有几个子进程)
master主进程负责接收用户的请求,把收到的请求交给其中的某一个worker子进程对外进行服务
worker子进程完成工作的时候,可以实现web服务器功能、反向代理功能、和缓存进行数据交换。
(支持多路复用、epoll、select)
进程:分成master主进程和若干个worker子进程(cpu有几个核,就有几个子进程)

主进程(master process)的功能:
对外接口:接收外部的操作(信号) 
对内转发:根据外部的操作的不同,通过信号管理 Worker 
监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程 读
取Nginx 配置文件并验证其有效性和正确性 建
立,绑定和关闭socket连接 按照配置生成,管理和结束工作进程 
接受外界指令,比如重启,升级及退出服务器等指令 
不中断服务,实现平滑升级,重启服务并应用新的配置 
开启日志文件,获取文件描述符 
不中断服务,实现平滑升级,升级失败进行回滚处理 
编译和处理perl脚本

工作进程(worker process)的功能:
所有 Worker 进程都是平等的 
实际处理:网络请求,由 Worker 进程处理 
Worker进程数量:一般设置为核心数,充分利用CPU资源,同时避免进程数量过多,导致进程竞争CPU资源
增加上下文切换的损耗 
接受处理客户的请求 
将请求依次送入各个功能模块进行处理 
I/O调用,获取响应数据 
与后端服务器通信,接收后端服务器的处理结果 
缓存数据,访问缓存索引,查询和调用缓存数据 
发送请求结果,响应客户的请求 
接收主程序指令,比如重启,升级和退出等
Nginx 模块介绍
核心模块:是Nginx 服务器正常运行必不可少的模块,提供错误日志记录,配置文件解析,事件驱动机制,进程管理等核心功能 
标准HTTP模块:提供HTTP协议解析相关的功能,比如:端口配置,网页编码设置,HTTP响应头设置等
可选HTTP模块:主要用于扩展标准的HTTP功能,让Nginx能处理一些特殊的服务,比如:Flash 多媒体传输 ,解析 GeoIP请求,网络传输压缩,安全协议SSL支持
邮件服务模块:主要用于支持 Nginx的邮件服务,包括对POP3协议,IMAP协议和SMTP协议的支持 
Stream服务模块: 实现反向代理功能,包括TCP协议代理 
第三方模块:是为了扩展Nginx服务器应用,完成开发者自定义功能,比如:Json支持,Lua支持等
Nginx安装
基于yum安装Nginx
查看Nginx版本:apt | yum info nginx
包安装最新版:把仓库配置成Nginx官方最新源
第一步:
打开Nginx官方网站http://nginx.org    右侧找到download下载,装偶数版本
第二步:
找到Pre-Built Packages,点击stable and mainline  复制下列
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
写入vim /etc/yum.repos.d/nginx.repo
第三步:
列出所有版本:yum list nginx --showduplicates
查看版本信息:dnf info nginx
安装指定版本:yum -y install nginx-1.18.0
编译安装
官方源码包下载地址:https://nginx.org/en/download.html
第一步:
centos安装依赖包:yum -y install gcc pcre-devel openssl-devel zlib-devel
rocky安装依赖包:yum -y install gcc make gcc-c++ libtool pcre pcre-devel zlib zlib-devel openssl openssl-devel perl-ExtUtils-Embed
ubuntu安装依赖包:apt -y install gcc make libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev
第二步:
useradd -s /sbin/nologin nginx
cd /usr/local/src/
wget https://nginx.org/download/nginx-1.22.0.tar.gz
tar xf nginx-1.22.0.tar.gz
cd nginx-1.22.0/
第三步:
./configure --prefix=/apps/nginx \
--user=nginx \     #指定运行用户
--group=nginx \ 
--with-http_ssl_module \    #启用加密 
--with-http_v2_module \      #启用HTTP2.0版本
--with-http_realip_module \  #启用IP地址
--with-http_stub_status_module \     #启用状态模块
--with-http_gzip_static_module \      #启用压缩
--with-pcre \                         #启用pcre正则表达式
--with-stream \                        #启用四层负载
--with-stream_ssl_module \ 
--with-stream_realip_module
第四步:
make && make install
修改权限:chown -R nginx.nginx /apps/nginx

nginx安装以后,有四个主要的目录
ll /apps/nginx
total 0 
drwxr-xr-x 2 root root 333 Sep 22 12:49 conf 
drwxr-xr-x 2 root root  40 Sep 22 12:49 html 
drwxr-xr-x 2 root root   6 Sep 22 12:49 logs 
drwxr-xr-x 2 root root  19 Sep 22 12:49 sbin



验证版本及编译参数,将nginx二进制文件写入变量中
ls /apps/nginx/sbin/
ln -s /apps/nginx/sbin/nginx /usr/sbin/
查看版本 nginx -v
查看编译参数 nginx -V
conf:保存nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他的.conf则是用来配置nginx相关的功能的.
例如fastcgi功能使用的是fastcgi.conf和 fastcgi_params两个文件,配置文件一般都有一个样板配置文件,是以.default为后缀,使用时可将其复 制并将default后缀去掉即可.
html目录中保存了nginx服务器的web文件,但是可以更改为其他目录保存web文件,另外还有一个50x的 web文件是默认的错误页面提示页面. 
logs:用来保存nginx服务器的访问日志错误日志等日志,logs目录可以放在其他路径,比 如/var/logs/nginx里面. 
sbin:保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能.

第五步:
启动nginx  直接输入nginx
ss -ntl 查看端口号 80
停止nginx  nginx -s stop

第六步:创建Nginx自启动文件
vim /usr/lib/systemd/system/nginx.service 
[Unit] 
Description=nginx-high performance web server 
Documentation=http://nginx.org/en/docs/ 
After=network-online.target remote-fs.target nss-lookup. target 
Wants=network-online.target 
[Service] 
Type=forking 
PIDFile=/apps/nginx/run/nginx.pid 
ExecStart=/apps/nginx/sbin/nginx -C /apps/nginx/conf/nginx.conf 
ExecReload=/bin/kill -s HUP $MAINPID 
ExecStop=/bin/kill -s TERM $MAINPID 
LimitNOFILE=100000 
[Install] WantedBy=multi-user.target

第六步:
创建pid文件存放的目录
mkdir /apps/nginx/run/
修改配置文件
vim /apps/nginx/conf/nginx.conf 
pid   /apps/nginx/run/nginx.pid;

第七步:
验证 Nginx 自启动文件
systemctl daemon-reload
systemctl enable --now nginx 
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service →

ll /apps/nginx/run/
total 4
-rw-r--r-- 1 root root 5 Sep 22 13:01 nginx.pid
ss -ntl
systemctl stop nginx
systemctl status nginx
ss -ntl
nginx启动方式
各自配套各自的启动和关闭方式
一:nginx 直接启动,
关闭:nginx -s quit
二:systemctl start nginx启动
   systemctl start nginx关闭
nginx的平滑升级和回滚
平滑升级
平滑升级四个阶段 
第一阶段:只有旧版nginx的master和worker进程 
第二阶段:旧版和新版nginx的master和worker进程并存,由旧版nginx接收处理用户的新请求(注意:做快照方便测试回滚) 
第三阶段:旧版和新版nginx的master和worker进程并存,由新版nginx接收处理用户的新请求 
第四阶段:只有新版nginx的master和worker进程

将旧Nginx二进制文件换成新Nginx程序文件(注意先备份) 
向master进程发送USR2信号启动新nginx进程 
master进程修改pid文件名加上后缀.oldbin,成为nginx.pid.oldbin 
master进程用新Nginx文件启动新master进程及worker子进程成为旧master的子进程 
系统中将有新旧两个Nginx主进程和对应的worker子进程并存 
当前新的请求仍然由旧Nginx的worker进程进行处理 
将新生成的master进程的PID存放至新生成的pid文件nginx.pid 
向旧的Nginx服务进程发送WINCH信号,使旧的Nginx worker进程平滑停止 
当前新的请求由新Nginx的worker进程进行处理 
向旧master进程发送QUIT信号,关闭旧master,并删除Nginx.pid.oldbin文件
如果发现升级有问题,可以回滚∶向旧master发送HUP,向新master发送QUIT

平滑升级操作如下:
第一步:
查看当前版本nginx -v
下载比当前版本高的版本拖入系统
并建一个100M的文件
cd /apps/nginx/html/
dd if=/dev/zero of=test.img bs=1M count=100
第二步:
模拟另外一台主机从nginx主机下载数据
wget --limit-rate=1024 http://10.0.0.200/test.img
第三步:
下载新版本nginx:wget http://nginx.org/download/nginx-1.23.1.tar.gz
解开下载的安装包  tar xf nginx-1.23.1.tar.gz
进入:cd nginx-1.23.1
第四步:
查看当前使用的版本及编译选项
nginx -V
nginx version: nginx/1.22.0
built by gcc 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) 
built with OpenSSL 1.1.1f  31 Mar 2020
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module

configure arguments后面是以前编译时的参数.现在编译使用一样的参数

第五步:开始编译新版本
./configure  --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
只要make无需要make install
make
ll objs/nginx /aaps/nginxsbin/nginx 查看新老版本
-rwxr-xr-x 1 nginx nginx 8073792 Sep 15 08:12 /apps/nginx/sbin/nginx*
-rwxr-xr-x 1 root  root  8100480 Sep 15 11:27 objs/nginx*
第六步:备份老版本并进行升级
cp /apps/nginx/sbin/nginx /opt/nginx.old
第七步:把新版本的nginx命令复制过去覆盖旧版本程序文件,注意:需要加 -f 选项强制覆盖,否则会提示Text file busy
cp -f objs/nginx /apps/nginx/sbin/nginx  强行覆盖
查看版本:nginx -v
nginx version: nginx/1.23.1
第八步:检查语法 nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful

第九步:发送信号USR2平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的nginx 此时两个master的进程都在运行,只是旧的master不在监听,由新的master监听80
此时Nginx开启一个新的master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx进 程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理
发送USR2:kill -USR2 `cat/apps/nginx/logs/nginx.pid`
ls /apps/nginx/logs
access.log     error.log     nginx.pid(新版本进程编号)      nginx.pid.oldbin(旧版本进程编号)
可以看到两个master,新的master是旧版master的子进程,并生成新版的worker进程

ps auxf|grep nginx 查看两个版本进程信息
root       40832  0.0  0.0   6300   720 pts/0    S+   11:47   0:00          \_ grep --color=autonginx
root        9564  0.0  0.0   8600   828 ?        Ss   08:12   0:00 nginx: master process /apps/nginx/sbin/nginx
nginx       9565  0.0  0.1   9292  3528 ?        S    08:12   0:00  \_ nginx: worker process
root       40775  0.0  0.2   8596  6160 ?        S    11:45   0:00  \_ nginx: master process /apps/nginx/sbin/nginx
nginx      40776  0.0  0.1   9284  3384 ?        S    11:45   0:00      \_ nginx: worker process

第十步:
lsof -i :80
先关闭旧nginx的worker进程,而不关闭nginx主进程方便回滚 
向原Nginx主进程发送WINCH信号,它会逐步关闭旗下的工作进程(主进程不退出),这时所有请求都会由新版Nginx处理
kill -WINCH `cat /apps/nginx/logs/nginx.pid.oldbin`
如果旧版worker进程有用户请求,会一直等待处理完后才会关闭,但是现在重新发起请求,看到的是新版本
curl -I 10.0.0.200/
HTTP/1.1 200 OK
Server: nginx/1.23.1
Date: Thu, 15 Sep 2022 12:22:05 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Thu, 15 Sep 2022 08:12:47 GMT
Connection: keep-alive
ETag: "6322de7f-267"
Accept-Ranges: bytes

旧版本的访问结束后,查看旧版本的worker进程被关闭
ps auxf|grep nginx
第十一步:
经过一段时间测试,新版本服务没问题,最后发送QUIT信号,退出老的master。
kill -QUIT `cat /apps/nginx/logs/nginx.pid.oldbin`
查看版本是不是已经是新版了
nginx -v
nginx version: nginx/1.23.1
回滚
如果升级的版本发现问题需要回滚,可以发送HUP信号,重新拉起旧版本的worker
kill -HUP `cat /apps/nginx/logs/nginx.pid.oldbin`
最后关闭新版的master
kill -QUIT `cat /apps/nginx/logs/nginx.pid`
恢复旧的文件 
cp /opt/nginx /apps/nginx/sbin/nginx 没有使用不用加 -f