Nginx详解 第一部分:编译安装Nginx+Nginx模块

Part 1

  • 一 、HTTP 和 Nginx
    • 1.1 套接字Socket
    • 1.2 URL
      • 1.2.1 定义
      • 1.2.1 URL和URN的区别
      • 1.2.3 URL组成
    • 1.3 请求访问完整过程详解
  • 二、I/O模型 处理高并发的时候用
    • 2.1 I/O模型简介
    • 2.2 多路复用I/O型
    • 2.3 异步I/O模型
    • 2.4 事件模型 select poll epoll
  • 三、NGINX概述
    • 3.1 简介
    • 3.2 NGINX和APACHE的区别?
    • 3.3 什么是零拷贝?
  • 四、Nginx模块
    • 4.1 安装方式
      • 4.1.1 方式一 yum安装
      • 4.1.2 方式二 编译安装 (推荐使用)
        • 1)前置准备
        • 2)编译安装nginx
        • 3)nginx开机自启(可选)
    • 4.2 Nginx命令 常用选项
      • 4.2.1 常用选项
      • 4.2.2 信号
    • 4.3 日志分割(Nginx 优化 )
    • 4.4 升级nginx
      • 4.4.1 思路
      • 4.4.2 平滑升级nginx
    • 4.5 退回旧版本(回滚)

一 、HTTP 和 Nginx

1.1 套接字Socket

套接字Socket是进程间通信IPC的一种实现,允许位于不同主机(或同一主机)上不同进程之间进行通信和数据交换

进程间的传输要有两个标志:IP地址和端口号,合称为套接字地址 socket address

  • 客户机套接字地址定义了一个唯一的客户进程
  • 服务器套接字地址定义了一个唯一的服务器进程

1.2 URL

1.2.1 定义

统一资源定位符,用于描述某服务器某特定资源位置

1.2.1 URL和URN的区别

URN定义某事物的身份,仅用于命名,而不指定地址。

URL提供查找该事物的方法。

1.2.3 URL组成

在这里插入图片描述

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#
scheme:方案,访问服务器以获取资源时要使用哪种协议
user:用户,某些方案访问资源时需要的用户名
password:密码,用户对应的密码,中间用:分隔
Host:主机,资源宿主服务器的主机名或IP地址
port:端口,资源宿主服务器正在监听的端口号,很多方案有默认端口号
path:路径,服务器资源的本地名,由一个/将其与前面的URL组件分隔
params:参数,指定输入的参数,参数为名/值对,多个参数,用;分隔
query:查询,传递参数给程序,如数据库,用?分隔,多个查询用&分隔
frag:片段,一小片或一部分资源的名字,此组件在客户端使用,用#分隔

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第1张图片

协议(Protocol):该URL的协议部分是 "https://",表示使用HTTPS协议进行数据传输。

用户名和密码(Username and Password):URL中的 "john.doe" 是用户名,表示用于身份验证的用户名。这是可选的,并且很少在实践中使用。密码可以通过 ":" 字符的存在被提供,但在该URL中没有明确提供密码。

主机名(Hostname):主机名部分是 "www.example.com",表示资源所在的主机或服务器的地址。

端口号(Port):该URL中明确指定了端口号 "123",表示用于与服务器建立连接的端口。如果未指定端口号,默认使用协议的默认端口(例如,HTTPS的默认端口是443)。

路径(Path):路径部分是 "/forum/questions/",表示所请求资源的路径。在这个示例中,资源位于主机的 "/forum/questions/" 目录下。

查询参数(Query Parameters):查询参数以 "?" 开始,后跟参数的键值对,用 "&" 分隔。在该URL中,查询参数是 "tag=networking&order=newest",表示请求中附带了两个参数:'tag' 的值是 'networking''order' 的值是 'newest'。这些参数可以被服务器用来进行进一步的处理或筛选。

锚点(Anchor):锚点部分以 "#" 开始,用于在文档内定位到特定的片段。在该URL中,锚点是 "topscheme",它指示浏览器在加载文档后将滚动到名为 "topscheme" 的片段。

1.3 请求访问完整过程详解

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第2张图片

当用户发起http请求 需要请求index.html网页文件;

客户端请求和服务器端建立连接,建立连接后,客户端发送请求报文;

服务端网卡收到请求报文,将该报文复制到内核空间(操作系统),内核空间分析报文后交给对应的程序;

nginx分析该报文,对比报文和自己的配置文件,按照配置文件完成请求,分析完成后,发现客户需要index.html文件;

由于程序的权限问题,没有资格直接调用磁盘上的文件,程序会再将这个请求,再次转发给内核;

内核得到请求后,去磁盘中寻找目标文件,找到文件后,复制给程序;
程序构建响应报文,构建好后交给内核空间;

内核空间得到响应报文后,再交给网卡,发给客户。

二、I/O模型 处理高并发的时候用

2.1 I/O模型简介

同步/异步(消息反馈机制):关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。

  • 同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成
  • 异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第3张图片

阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态

  • 阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。
  • 非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。
    Nginx详解 第一部分:编译安装Nginx+Nginx模块_第4张图片

2.2 多路复用I/O型

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第5张图片
多路复用I/O(I/O multiplexing)模型是一种基于事件驱动的 I/O 处理模式。它利用操作系统提供的多路复用机制(如select、poll、epoll等)来同时监听多个 I/O 事件,当某个事件就绪时,通知应用程序进行处理。

通过多路复用I/O模型,可以在一个线程中同时处理多个客户端连接的 I/O 操作,而不需要为每个连接创建一个线程或进程,避免了资源开销和上下文切换的成本。

常见的多路复用I/O模型有:

  • select:适用于连接数不太多的情况,轮询监听多个文件描述符上的 I/O 事件。
  • poll:与select类似,但没有连接数的限制,并且不会修改传入的描述符集合。
  • epoll:适用于连接数非常多的情况,通过事件驱动机制来处理 I/O 事件,可以在大并发情况下具有较高的性能优势。

2.3 异步I/O模型

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第6张图片
异步 I/O 模型是一种非阻塞的 I/O 处理模式,通过回调函数或事件通知的方式来处理已完成的 I/O 操作,能够提高系统的并发性和处理效率。

2.4 事件模型 select poll epoll

①Nginx服务使用异步非阻塞模式:请求不需要排队,会反馈任务的完成结果。

②Apache服务使用同步阻塞模式:请求需要排队,且不会主动返回结果。

优缺点

模型 描述 优点 缺点
select 最古老的模型 可以同时监视多个文件描述符 效率较低,不适用于大规模并发连接
poll 类似于select 效率相对更高,可以处理大量并发连接 随着文件描述符数量的增加,性能下降较明显
epoll Linux特有模型 在高并发场景下性能表现更好,使用边缘触发方式,只在状态变化时通知 在非Linux系统上不可用,涉及到一些操作系统特定的细节和配置

区别

select poll epoll
操作方式 遍历 遍历 回调
底层实现 数组 链表 哈希表
IO效率 每次调用都进行线性遍历,时间复杂度为0(n) 同左 事件通知方式,每当fd就绪,系统注册的回调函数就会被调用,将就绪的fd放到rdlllist里,时间复杂度O(1)
最大连接数 1024(x86)2048(x64) 无上限 无上限
fd拷贝 每次调用select都需要把fd集合从用户拷贝到内核态 每次调用poll,都需要把fd集合从用户态拷贝到内核态 调用epoll ctl时拷贝进内核并保存,之后每次epoll wait不拷贝

三、NGINX概述

3.1 简介

①作用:支持七层(应用层)和四层(传输层)反向代理、可做web服务器。

②特性:高可靠性、支持热部署、可扩展性好、高并发高性能、单机部署。

⑤进程:一个主进程master生成多个worker子进程,worker子进程负责处理工作。

3.2 NGINX和APACHE的区别?

特点 Nginx Apache
并发处理 高并发处理能力,轻量级且低内存消耗 对静态文件处理高效,但在高并发情况下内存消耗较大
资源占用 占用更少的系统资源和内存 占用较多的系统资源和内存
事件驱动 使用事件驱动模型,可在较少的线程上同时处理多个连接 使用多线程模型,会为每个连接创建一个线程
配置灵活性 配置简单明了,易于阅读和维护 配置相对复杂,需要更多的配置项指定
扩展性 支持动态模块和第三方扩展,可自定义功能 支持动态模块和第三方扩展,但相对Nginx更少
虚拟主机 支持无限个虚拟主机配置,每个虚拟主机独立配置 支持无限个虚拟主机配置,但每个虚拟主机使用同一套配置
模块支持 支持反向代理、负载均衡、HTTP缓存等 支持反向代理、负载均衡、SSL等
用户群体 更适合高并发、网络应用场景,如反向代理、负载均衡 更适合传统Web服务器应用,如静态内容和PHP

核心区别
1)apache 是同步多进程模型,一个连接对应一个进程,而 nginx 是异步的,多个
连接(万级别)可以对应一个进程;
2)需要稳定用apache,需要高性能用nginx。

3.3 什么是零拷贝?

在Nginx中,使用零拷贝技术可以将数据从文件系统直接发送到网络套接字中,而不需要中间的内存拷贝。

这可以减少CPU的使用量,减少内存带宽的消耗,并且可以更快地将数据发送到客户端

四、Nginx模块

4.1 安装方式

4.1.1 方式一 yum安装

#安装依赖包
yum install -y epel-releas
#yum方式安装
yum install -y nginx

4.1.2 方式二 编译安装 (推荐使用)

1)前置准备

#安装依赖包
yum -y install gcc pcre-devel openssl-devel zlib-devel openssl  openssl-devel
#新建nginx用户便于管理
useradd -M -s /sbin/nologin nginx
#官网下载包
wget http://nginx.org/download/nginx-1.18.0.tar.gz

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第7张图片

2)编译安装nginx

tar xf nginx-1.18.0.tar.gz 
mkdir /apps/nginx -p
cd nginx-1.18.0/

./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

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第8张图片

make -j2 && make install

chown -R nginx.nginx /apps/nginx#加权限

ln -s /apps/nginx/sbin/nginx /usr/sbin/ #直接启动 不需要绝对路径

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第9张图片
Nginx详解 第一部分:编译安装Nginx+Nginx模块_第10张图片

3)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/logs/nginx.pid
#注意文件位置,如果不对 启动不了
ExecStart=/apps/nginx/sbin/nginx
#注意启动文件位置
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
systemctl daemon-reload 
#重新加载配置
systemctl enable --now nginx
#开机自启并立即启动    如果卡主是应为logs下有 nginx.pid  文件  删除即可

chown -R nginx.nginx /apps/nginx
#修改权限

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第11张图片

###如果需要修改pid文件可以执行以下操作#################
mkdir /apps/nginx/run/
#创建目录
vim /apps/nginx/conf/nginx.conf
#修改配置文件
pid   /apps/nginx/run/nginx.pid;
#找到 pid的位置修改  

4.2 Nginx命令 常用选项

#基本格式
nginx [选项] [参数]

4.2.1 常用选项

选项 功能
-c <配置文件> 指定一个自定义的配置文件路径
-g <全局配置> 在命令行中指定全局配置选项
-p <工作目录> 设置工作目录,用于存放日志文件和临时文件
-s <信号> 向nginx发送信号,常用的有stop(停止nginx进程)和reload(重新加载配置文件)
-t 测试配置文件语法是否正确
-q 在测试配置文件时,以静默模式运行,只输出关键信息
-V 显示nginx的版本、编译信息和配置参数
-h 显示帮助信息,包括所有可用的命令行选项
-s <文件> 启动nginx并将master进程的PID写入指定的文件
-e <错误日志文件> 设置错误日志文件的路径
-g <配置指令> 设置全局配置指令。可以在命令行中设置多个全局配置指令,用分号分隔
-T 测试配置文件,并打印出解析后的配置内容
-q <文件> 检查配置文件,并打印出解析后的配置内容,但不启动nginx

4.2.2 信号

#基本格式
nginx  -s 信号
信号 描述
stop 快速停止nginx进程,可能会中断现有连接。
quit 优雅地停止nginx进程,等待现有连接完成后再停止。
reload 重新加载配置文件,优雅地应用新配置,不中断现有连接。
reopen 重新打开日志文件,用于日志切割或日志重定向。
term 快速停止nginx进程,可能会中断现有连接,与stop信号类似。
usr1 重新打开日志文件,用于日志切割或日志重定向,与reopen信号类似。
usr2 平滑地升级nginx可执行文件。
hup 重新加载配置文件,优雅地应用新配置,与reload信号类似。
winch 当nginx以master/worker工作模式运行时,重新生成worker进程以适应新的配置。
usr3 向worker进程发送自定义信号。

4.3 日志分割(Nginx 优化 )

cd /apps/nginx/logs #移动到日志所在目录下,此目录为指定安装目录,默认目录为/var/log/nginx

mv access.log access.log.bak #备份日志文件
touch access.log #建空的日志文件

pid=`cat /apps/nginx/logs/nginx.pid` #查看nginx的pid

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第12张图片

kill -s USR1 $pid 
或者
nginx -s reopen  #重新打开Nginx进程以重新加载配置文件

会发送信号给Nginx主进程,告诉它重新加载配置文件而不停止正在处理的连接(不停止Nginx服务)

在这里插入图片描述

4.4 升级nginx

4.4.1 思路

  1. 将旧Nginx文件换成新Nginx文件(注意备份)
  2. 向master进程发送USR2信号
  3. master进程修改pid文件名,加后缀.oldbin
  4. master进程用新Nginx文件启动新master进程,系统中将有新旧两个Nginx主进程共同提供Web服务
  5. 向旧的Nginx服务进程发送WINCH信号,使旧的Nginx worker进程平滑停止,并删除Nginx.pid.oldbin文件
  6. 向旧master进程发送QUIT信号,关闭老master
  7. 如果发现升级有问题,可以回滚向老master发送HUP,向新master发送QUIT

4.4.2 平滑升级nginx

nginx1.18---->nginx1.20
#关闭防火墙
systemctl stop firewalld 
setenforce 0
#启动服务
systemctl start nginx
#下载安装包到src目录
wget https://nginx.org/download/nginx-1.20.2.tar.gz -P \
/usr/local/src/

cd /usr/local/src/;ls

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第13张图片

tar xf nginx-1.20.2.tar.gz 
cd nginx-1.20.2/;ls

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第14张图片

重新编译安装

#检测编译环境 加模块
./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 -j2 && make install 

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第15张图片

nginx -V#查看版本

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第16张图片

mv /apps/nginx/sbin/nginx   /apps/nginx/sbin/nginx.bak
#将低版本的nginx主程序改名
cp /usr/local/src/nginx-1.20.2/objs/nginx /apps/nginx/sbin
#将新版本 拷入进去
/apps/nginx/sbin/nginx -t
#语法检查

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第17张图片

kill -USR2 `cat /apps/nginx/logs/nginx.pid`

ps auxf|grep nginx
#会生成新的master进程,需要结束旧的

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第18张图片

#创建一个无用的填充文件,用于让测试客户端下载
dd if=/dev/zero of=/apps/nginx/html/m.img bs=1G count=10

cd /apps/nginx/html;ls

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第19张图片

切换到客户端下载测试包

#192.168.2.100为服务端IP地址
#从服务端下载m.img,观察进程
wget --limit-rate=1M http://192.168.2.100/m.img 

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第20张图片

返回服务端

#查看master process pid文件路径 
ls /apps/nginx/logs/

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第21张图片

cat /apps/nginx/los/nginx.pid #1.20.2版本的

cat /apps/nginx/los/nginx.pid.oldbin  #1.18版本的

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第22张图片

kill -WINCH `cat /apps/nginx/logs/nginx.pid.oldbin`
#优雅关闭 旧版本的master process
开启新的客户机,从服务端获取测试包
wget --limit-rate=1M http://192.168.2.100/m.img 
然后返回服务端查看是否使用新进程
ss -natp | grep 80

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第23张图片

pstree -p |grep nginx 

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第24张图片

4.5 退回旧版本(回滚)

#唤起旧版本的主进程
kill -HUP `cat /apps/nginx/logs/nginx.pid.oldbin`
#观察进程
ps aux|grep nginx

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第25张图片

#结束新版本的master进程
kill -QUIT `cat /apps/nginx/logs/nginx.pid`

ps aux | grep nginx 

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第26张图片

curl -I 127.1 
#通过 curl 发送一个 HEAD 请求到本地服务器并返回响应头信息

Nginx详解 第一部分:编译安装Nginx+Nginx模块_第27张图片

你可能感兴趣的:(Nginx,nginx,运维,linux,笔记)