Nginx学习笔记
先看 2 个实际需求,引出 Nginx
需求 1: 访问不同微服务
- 示意图
需求 2: 轮询访问服务
-- 示意图
解决方案: Nginx
- 反向代理
- 负载均衡
- 动静分离
- 高可用集群
Nginx 在分布式 微服务 架构的位置
基本介绍
Nginx 是什么? 能干什么?
- 是什么:Nginx (“engine x”) 是一个高性能的 HTTP 和反向代理 WEB 服务器
- 能干什么:反向代理 负载均衡 动静分离
- 牛逼之处:高性能,高负载 有报告表明能支持高达 50,000 个并发连接数
- 详细说明:https://lnmp.org/nginx.html
官方资料
Nginx 核心功能
正向代理
- 一句话:如果我们要访问 www.google.com 但是直接访问不到,则需要通过代理服务器来访问,这种代理服务就称为正向代理
- 一图胜千言
老韩图解
- 我们知道www.google.com , 但是访问不到
- 所以使用代理服务器帮助我们(即客户端)来上网, 注意帮助的对象是客户端, 这种代理,我们称为正向代理.
- 正向代理同时也隐藏了客户端信息.
- 再次说明,正向代理帮助的是客户端, 因此可以把 客户端+正向代理服务 , 视为一个整体
反向代理
- 一句话:客户端将请求发送到代理服务器,由代理服务器去选择目标服务器获取数据后,返回给客户端,这种代理方式为反向代理
- 一图胜千言
老韩图解
- 项目设计者, 不希望客户端直接访问目标Web 服务器(比如目标 Web 服务器是集群, 如果直接访问就会提供多个公网 IP), 而是希望提供一个统一的访问 IP, 这个是理解反向代理的前提,即为什么要反向代理.
- 反向代理帮助的对象是目标 Web 服务器
- 当客户端请求达到反向代理服务后,由反向代理服务来决定如何访问目标 Web 服务器(或者是哪个 Web 服务器), 这个过程对客户端是透明的.
- 反向代理服务会暴露公共的IP, 只要能上网,就可以访问,但是对于反向代理服务器 管理的/代理的 Web 服务器通常是在局域网内,不能直接访问,只能通过反向代理来访问.
- 我们可以将 反向代理服务+反向代理服务代理的Web 服务器 视为一个整体
- 反向代理会屏蔽 内网服务器(也就是他代理的服务)信息, 并实现负载均衡访问
负载均衡
一句话:当客户端向反向代理服务器(比如 Nginx)发出请求,如果 Nginx 代理了多个
WEB 服务器(集群),Nginx 会将请求/负载分发到不同的服务器,也就是负载均衡
一图胜千言
-- 示意图
动静分离
- 一句话:为了加快网站的解析速度,可以把动态资源和静态资源由不同的服务器来解析,降低单个服务器的压力
- 传统的项目资源部署
-- 示意图
- 动静分离项目资源部署
-- 示意图
Nginx 下载&安装&启动
下载
- 下载地址:https://nginx.org/en/download.html
- 版本:nginx-1.20.2.tar.gz
安装
安装 Linux, 登录 Linux
1、我在讲解 Linux 的时候(用的 CentOS7.6, 请小伙伴和我保持一致), 已经讲过, 非常的全面细致
2、带学员看一下笔记位置
3、带学员看一下 Linux 视频课程在哪里
4、保证能登录 Linux
5、保证访问外网-在Linux 讲过怎么配置
具体安装步骤
- 搭建 gcc 环境
yum -y install gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel
老韩提示 1: 一定要保证当前的linux 系统, 可以连接外网, 因为yum 需要到外网,获取数据
老韩提示 2: 如何在 Linux 配置网络, 可以连接到外网, 带学员看一下文档和视频位置
(https://www.bilibili.com/video/BV1Sv411r7vd?p=63).
老韩提示 3: 执行上面指令的时候, 可能会报 Centos Another app is currently holding the yum lock..错误,是因为yum 不时会自动升级, 占用了端口或文件, 解决方案 (1)可以重启Linux, 立即执行该指令 (2)或者等一会再执行(3) 或者参考 https://www.cnblogs.com/lzxianren/p/4254059.html, 老韩用的是第 1 种解决方案, 可以搞定..
将nginx-1.20.2.tar.gz 上传到Linux /opt 目录
切换到/opt 目录, 解压 nginx-1.20.2.tar.gz
tar -zxvf nginx-1.20.2.tar.gz
将解压后的文件放到指定位置
mv nginx-1.20.2 /usr/local/nginx
- 进入文件目录
cd /usr/local/nginx
- 配置 nginx 路径
1 | ./configure --prefix=/usr/local/nginx --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-http_gzip_static_module --http-client-body-temp-path=/var/temp/nginx/client --http-proxy-temp-path=/var/temp/nginx/proxy --http-fastcgi-temp-path=/var/temp/nginx/fastcgi --http-uwsgi-temp-path=/var/temp/nginx/uwsgi --http-scgi-temp-path=/var/temp/nginx/scgi --conf-path=/usr/local/nginx/nginx.conf |
- 补全 nginx 配置目录
mkdir /var/temp/nginx -p
- 编译并安装
make && make install
- 测试配置与 nginx 是否正常,当出现 successful 即可
./sbin/nginx -t
- 启动 nginx
./sbin/nginx -c nginx.conf
- 查看进程/或端口(默认端口是 80) ps -ef | grep nginx
启动 Nginx 可能的错误 和解决方案
1. 解决 nginx 启动报错 nginx: [emerg] open() “/var/run/nginx/nginx.pid” failed (2: No such file or directory)
验证是否安装成功
- nginx 默认监听端口 80,出现 Welcome to nginx!该页面就是搞定了
- Linux 的浏览器:http://localhost
配置防火墙,让 Windows 访问 Nginx
- 说明:默认情况下 Windows 是不能访问 Nginx , 因为防火墙是关闭 80 端口的
- 具体配置
- 查看开放的端口号
firewall-cmd –list-all
设置开放的端口号
#firewall-cmd –add-service=http –permanent #增加了一个 http 服务,理解
firewall-cmd –add-port=80/tcp –permanent
重启防火墙
firewall-cmd –reload
**老 韩 提 示 : 防 火 墙 配 置 详 情 , << 韩 顺 平 一 周 学 会 Linux>> https://www.bilibili.com/video/BV1Sv411r7vd?p=77
测试: windows 浏览器: http://192.168.12.134/
Nginx 命令行参数
指令说明
地址:https://nginx.org/en/docs/switches.html
使用演示
- 启动 /usr/local/nginx/sbin/nginx -c nginx.conf
- 停止 /usr/local/nginx/sbin/nginx -s stop
- 重新加载(不需要重启) /usr/local/nginx/sbin/nginx -s reload
- 查看版本 /usr/local/nginx/sbin/nginx -v
- 查看版本、配置参数 /usr/local/nginx/sbin/nginx -V
nginx.conf 配置文件
基本说明
Nginx 的配置文件位置
1、文件位置
- 安装目录\conf\nginx.conf
- 安装目录\nginx.conf
2、两个文件是一样的
多说一句:使用 /usr/local/nginx/sbin/nginx 启动 Nginx ,默认用的是 安装目录 \nginx.conf 配置文件
作用:完成对 Nginx 的各种配置,包括端口,并发数,重写规则等
nginx.conf 组成
- 全局块
- events 块
- http 块
nginx.conf 详细文档
- 地址: 文档:https://blog.csdn.net/liuchang19950703/article/details/110792007
- 文档: Nginx 配置文件 nginx.conf 详解.docx
- 详细内容
1 | #Nginx 用户及组:用户组。window 下不指定 |
nginx.conf 讲解
- 一张图说明 nginx.conf 结构
- 看一下 /usr/local/nginx/conf/nginx.conf
1 | #user nobody; |
全局块
说明
- 从配置文件开始到 events 块之间的内容
- 主要会设置一些影响 nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx服务器的用户(组)、允许生成的 worker process 数,进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等
简单分析
1、#这是 Nginx 服务器并发处理服务的关键配置,worker_processes 值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约
2、配置举例:
worker_processes 1;
events 块
说明
- events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接
- 常用的设置包括是否开启对多 work process 下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 work process 可以同时支持的最大连接数等
简单分析
1、#上述例子就表示每个 work process 支持的最大连接数为 1024, 这部分的配置对
Nginx 的性能影响较大,在实际中应根据实际情况配置
2、配置举例 events {
worker_connections 1024;
}
http 块
说明
- 这是 Nginx 服务器配置中最复杂的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里
- http 块也可以包括 http 全局块、server 块
http 全局块
1、http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单连接请求数上限等
2、配置举例:
1 | http { |
server 块
- 这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。
- 每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。
- 每个 server 块也分为全局 server 块,以及可以同时包含多个 location 块。
- 全局 server 块
最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置。 - location 块
一个 server 块可以配置多个 location 块
- 全局 server 块
1 | server { |
- 小结: 这块的主要作用是基于 Nginx 服务器接收到的请求字符串( 例如 server_name/uri-string),对虚拟主机名称(也可以是 IP 别名) 之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理。比如地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。
- 实例 1:修改端口
- 实例 2:配置多个 server
反向代理-快速入门
需求说明/图解
需求说明/图解
在浏览器输入 www.hsp.com(windows), 可以访问到 tomcat
使用 Nginx 反向代理功能, 完成需求.
如图
反向代理配置-思路分析/图解
-- 思路分析示意图
实现步骤
安 装 JDK , 在 8 以 上 , 参 考 : << 韩 顺 平 一 周 学 会 Linux>> https://www.bilibili.com/video/BV1Sv411r7vd?p=86
安装步骤
- mkdir /opt/jdk
- 通过 xftp6 上传到 /opt/jdk 下
- cd /opt/jdk
- 解压 tar -zxvf jdk-8u261-linux-x64.tar.gz
- mkdir /usr/local/java
- mv /opt/jdk/jdk1.8.0_261 /usr/local/java
- 配置环境变量的配置文件 vim /etc/profile
- export JAVA_HOME=/usr/local/java/jdk1.8.0_261
- export PATH=$JAVA_HOME/bin:$PATH
- source /etc/profile [让新的环境变量生效]
测试是否安装成功
安 装 Tomcat , 参 考 : << 韩 顺 平 一 周 学 会 Linux>> https://www.bilibili.com/video/BV1Sv411r7vd?p=87
1、步骤
- 上传安装文件,并解压缩到/opt/tomcat
- 进入解压目录/bin , 启动 tomcat ./startup.sh
- 开放端口 8080 , 回顾 firewall-cmd
2、测试是否安装成功
在windows、Linux 下 访问 http://linuxip:8080
修改 C:\Windows\System32\drivers\etc\hosts 配置虚拟主机名
#127.0.0.1 www.mynews.com
127.0.0.1 localhost
#eureka 主机名和 ip 映射
127.0.0.1 eureka9001.com
127.0.0.1 eureka9002.com
192.168.12.134 www.hsp.com
修改 安装目录\nginx.conf
小技巧: 如何查看 nginx.conf 的配置错误
- nginx -t #检测默认配置文件
- nginx -t -c 配置文件 #指定检测配置文件
完成测试
- 重启 或者 重新加载 Nginx
- windows 浏览器输入: http://www.hsp.com
注意事项和细节
- Nginx 对外提供访问入口,充当反向代理服务器,Tomcat 的端口就无需对外暴露-测试一把
- 开启和关闭防火墙的端口
- 以 8080 端口为例,关闭 8080 端口
1 | firewall-cmd --remove-port=8080/tcp --permanent |
- 以 8080 端口为例,开放 8080 端口
1 | firewall-cmd --add-port=8080/tcp --permanent |
- 查看防火墙状态
1 | firewall-cmd --list-all |
反向代理配置-Location 实例
需求说明/图解
-- 效果示意图
反向代理配置-思路分析/图解
-- 示意图
Location 语法规则
解读 1-location 语法规则
Location规则
语法规则: location [=|~|~*|^~] /uri/ {… }
首先匹配 =,其次匹配^~,其次是按文件中顺序的正则匹配,最后是交给 /通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
| 符号 | 含义 |
|---|---|
| = | = 开头表示精确匹配 |
| ^~ | ^~开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格) |
| ~ | ~ 开头表示区分大小写的正则匹配 |
| ~* | ~* 开头表示不区分大小写的正则匹配 |
| !~和!~* | !~和!~*分别为区分大小写不匹配及不区分大小写不匹配的正则 |
| / | 用户所使用的代理(一般为浏览器) |
| $http_x_forwarded_for | 可以记录客户端IP,通过代理服务器来记录客户端的ip地址 |
| $http_referer | 可以记录用户是从哪个链接访问过来的 |
匹配规则示例:
location = / {
#规则A
}
location = /login {
#规则B
}
location ^~ /static/ {
#规则C
}
location ~ \.(gif|jpg|png|js|css)$ {
#规则D
}
location ~* \.(gif|jpg|png|js|css)$ {
#规则E
}
location !~ \.xhtml$ {
#规则F
}
location !~* \.xhtml$ {
#规则G
}
location / {
#规则H
}
那么产生的效果如下:
1. 访问根目录/,比如http://localhost/将匹配规则A
2. 访问 http://localhost/login 将匹配规则B,http://localhost/register则匹配规则H
3. 访问 http://localhost/static/a.html 将匹配规则C
4. 访问 http://localhost/a.gif,http://localhost/b.jpg 将匹配规则D和规则E,但是规则D顺序优先,规则E不起作用,而http://localhost/static/c.png则优先匹配到规则C
5. 访问 http://localhost/a.PNG 则匹配规则E,而不会匹配规则D,因为规则E不区分大小写。
6. 访问 http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应用中哪里会用到。
7. 访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如FastCGI(PHP),tomcat(jsp),nginx作为反向代理服务器存在。
实际常用规则
#直接匹配网站根目录,通过域名访问网站首页比较频繁,使用这个会加速处理。
#这里是直接转发给后端应用服务器了,也可以是一个静态首页
# 第一个必选规则
location = / {
proxy_pass http://tomcat:8080/index
}
# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
# 请求/static/a.txt 将被映射到实际目录文件:/webroot/res/static/a.txt
root /webroot/res/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|html|ico)${
root /webroot/res/;
}
第三个规则就是通用规则,用来转发动态请求到后端应用服务器
#非静态文件请求就默认是动态请求,自己根据实际把握
#毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了
location / {
proxy_pass http://tomcat:8080/
}
Location解析过程
老韩梳理[大概]:
1、 先判断精准命中,如果命中,立即返回结果并结束解析过程。
2、 判断普通命中,如果有多个命中,“记录”下来“最长”的命中结果(记录但不结束,最长的为准)[一会还要梳理]。
3、 继续判断正则表达式的解析结果,按配置里的正则表达式顺序为准,由上至下开始匹配,一旦匹配成功1个,立即返回结果,并结束解析过程。
4、 普通命中顺序无所谓,是因为按命中的长短来确定。正则命中,顺序有所谓,因为是从前往后命中的。
总结——精准匹配>^~匹配>正则匹配>普通匹配
解读 2-nginx 的 location 解析过程
- 参考 : https://blog.huati365.com/89af5ae5a56d1b96
实现步骤
- 修改 C:\Windows\System32\drivers\etc\hosts 配置虚拟主机名
#127.0.0.1 www.mynews.com
127.0.0.1 localhost
#eureka 主机名和 ip 映射
127.0.0.1 eureka9001.com
127.0.0.1 eureka9002.com
192.168.56.100 hspliving.com
192.168.12.134 www.hsp.com
192.168.12.134 www.hspmall.com
- 修改 安装目录\nginx.conf
- 在 Linux 的 Tomcat 创建 webapps\product\hi.html
hi.html
<h1>product service linux tomcat </h1>
在 windows 的 Tomcat 创建 webapps\member\hi.html
linux 防火墙打开 10000 端口
保证 linux 可以访问Windows Tomcat 【即:可以访问 Windows 的 8080 端口, 可暂时关闭 windows 防火墙,测完恢复】
完成测试
- 确保启动 Linux 下的 Tomcat
- 确保启动 Windows 下的 Tomcat
- 重启 或者 重新加载 Nginx
- windows 浏览器输入[注意带上端口]: http://www.hspmall.com:10000/product/hi.html http://www.hspmall.com:10000/member/hi.html
几个小实验-多测试
负载均衡-配置实例
需求说明/图解
-- 示意图
负载均衡配置-思路分析/图解
-- 示意图
负载均衡配置规则
- 负载均衡就是将负载分摊到不同的服务单元,既保证服务的可用性,又保证响应足够快
- linux 下有 Nginx、LVS、Haproxy 等等服务可以提供负载均衡服务, Nginx 提供了几种分配方式(策略):
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除
2、weight
weight 代表权,重默认为 1,权重越高被分配的客户端越多
指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况。 例如
1 | upstream hspservers{ |
3、ip_hash
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决
session 的问题。例如:
1 | upstream hspservers{ |
4、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配
1 | upstream hspservers{ |
实现步骤
修改 C:\Windows\System32\drivers\etc\hosts 配置虚拟主机名
#127.0.0.1 www.mynews.com
127.0.0.1 localhost
#eureka 主机名和 ip 映射
127.0.0.1 eureka9001.com
127.0.0.1 eureka9002.com
192.168.12.134 www.hsp.com
192.168.12.134 www.hspmall.com
192.168.12.134 www.hspcrm.com
修改 安装目录\nginx.conf
在 Linux 的 Tomcat8080 创建 webapps\search\look.html
look.html
<h1>tomcat 8080 search </h1>
在 Linux 下重新安装一份 Tomcat, 并将端口修改成 8081
- 修改 tomcat 的 conf\server.xml , 注意要修改如下位置,否则该 Tomcat 是不能正常工作.
- 细节说明:不同版本的 tomcat 修改的端口还不一样, 小伙伴们灵活处理即可,一定要认真,否则后面测试失败,你排除错误会花费很长时间,让你搞到怀疑人生
在 Linux 的 Tomcat8081 创建 webapps\search\look.html
look.html
<h1>tomcat 8081 search </h1>
linux 防火墙打开 80 端口, 保证外网可以访问
完成测试
启动 Linux 下两个 Tomcat
1、查看启动的端口, 确保有 8080 和 8081 端口在监听(老韩提示: 如果 tomcat 没有监听对应端口, 说明启动失败了, 可以尝试先执行 shutdown.sh 再执行 startup.sh 解决)
2、在 linux 下可以正常访问到两个页面
启动 或者 重新加载 Nginx
windows 浏 览 器 输 入 ( 保 证 浏 览 器 不 是 无 痕 上 网 ): http://www.hspcrm.com/search/look.html
注意事项和避免的坑
- nginx.conf 的 upstream 不能带下划线, 否则会失败, 但是语法检测不到
如果你的浏览器是无痕上网, 负载均衡可能失效, 因为 Nginx 无法采集到相关信息, 老师 就遇到这个情况. 改用其它浏览器即可(比如 chrome)
老韩提示: 如果某 tomcat 没有监听对应端口, 说明启动失败了, 可以尝试先执行
shutdown.sh 再执行 startup.sh 解决
几个小实现-多测试
文档: Nginx 的 upstream 配置技巧
1、基本介绍
Nginx 是一个反向代理软件,大部分的网站都采用Nginx 作为网站/平台的
服务器软件。Nginx 除了可以直接作为web 服务器使用外,更多的情况是
通过反向代理将请求转发给上游服务器
配置上游服务器可以使用upstream 进行设置,通过upstream 可以实现服
务的负载均衡规则,可以提高服务器的高可用性。
2、地址: https://zhuanlan.zhihu.com/p/409693332
如果停掉 1 个 Tomcat, 会怎样?
如果停掉 1 个 Tomcat, 然后又恢复,会怎样?
如何给不同的服务,分配权重 weight
动静分离-应用实例
什么是动静分离
- Nginx 动静分离简单来说就是把动态跟静态请求分开,可以理解成使用 Nginx 处理静态页面/资源,Tomcat 处理动态页面/资源。
- 动静分离可以减轻 Tomcat 压力,静态请求由 Nginx 处理,提供系统整体性能.
- 回顾前面-示意图
需求说明/图解
动静配置-思路分析/图解
– 示意图
先使用传统方式实现
- 创建tomcat\webapps\search\cal.jsp [老韩说明: 为了测试方便, 在tomcat2 也对应创建一份]
1 | <%-- Created by IntelliJ IDEA. User: 韩顺平 Version: 1.0 To change this template use File | Settings | File Templates. --%> |
拷贝 cal.jpg 到 tomcat\webapps\search\image 目录, [ 老韩说明: 为了测试方便, 在
tomcat2 也对应创建一份]
- 浏览器访问 http://www.hspcrm.com/search/cal.jsp 就可以看到正确页面
动静分离优化步骤
- 修改 安装目录\nginx.conf
- 创 建 /usr/local/nginx/html/search/image 目 录 , 因 为 图 片 路 径 其 实 是
ip/search/image
- 将 Linux 的 两 个 Tomcat\webapps\search\image 目 录 删 除 , 在
/usr/local/nginx/html/search/image 目录下放入图片
- linux 防火墙打开 80 端口, 保证外网可以访问
完成测试
- 启动 或者 重新加载 Nginx
- windows 浏览器输入 http://www.hspcrm.com/search/cal.jsp
老师解读
- 这时图片就是从 Nginx 直接返回的
- 而请求cal.jsp 才转发到对应 tomcat 完成
如果有css js 文件 需要动静分离,按照规则配置即可
Nginx 工作机制&参数设置
master-worker 机制
master-worker 工作原理图-先搂一眼
– 示意图
master-worker 机制
老韩图解
- 一个 master 管理多个 worker
一说master-worker 机制
- 争抢机制示意图
老韩图解
一个master Process 管理多个worker process, 也就是说Nginx 采用的是多进程结构, 而不是多线程结构.
当client 发出请求(任务)时,master Process 会通知管理的 worker process
worker process 开始争抢任务, 争抢到的worker process 会开启连接,完成任务
每个 worker 都是一个独立的进程,每个进程里只有一个主线程
Nginx 采用了 IO 多路复用机制(需要在 Linux 环境), 使用 IO 多路复用机制, 是 Nginx 在使用为数不多的 worker process 就可以实现高并发的关键
二说master-worker 机制
- 二说 Master-Worker 模式
老韩对上图说明
Master-Worker 模式
1、Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程。
2、Master 进程 接收来自外界的信号,向各 worker 进程发送信号,每个进程都有可能来
处理这个连接。
3、Master 进程能监控 Worker 进程的运行状态,当 worker 进程退出后(异常情况下),会自动启动新的 worker 进程。
- accept_mutex 解决 “惊群现象”/理论
1、所有子进程都继承了父进程的 sockfd,当连接进来时,所有子进程都将收到通知并“争着”与它建立连接,这就叫“惊群现象”。
2、大量的进程被激活又挂起,只有一个进程可以 accept() 到这个连接,会消耗系统资源。
3、Nginx 提供了一个 accept_mutex ,这是一个加在 accept 上的一把共享锁。即每个 worker 进程在执行 accept 之前都需要先获取锁,获取不到就放弃执行 accept()。有了这把锁之后,同一时刻,就只会有一个进程去 accpet(),就不会有惊群问题了。
4、当一个 worker 进程在 accept() 这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,完成一个完整的请求。
5、一个请求,完全由 worker 进程来处理,而且只能在一个 worker 进程中处理。
- 用多进程结构而不用多线程结构的好处/理论
1、节省锁带来的开销, 每个 worker 进程都是独立的进程,不共享资源,不需要加锁。在编程以及问题查上时,也会方便很多。
2、独立进程,减少风险。采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master 进程则很快重新启动新的 worker 进程
- 实现高并发的秘密-IO 多路复用
1、对于 Nginx 来讲,一个进程只有一个主线程,那么它是怎么实现高并发的呢?
2、采用了IO 多路复用的原理,通过异步非阻塞的事件处理机制,epoll 模型,实现了轻量级和高并发
3、nginx 是如何具体实现的呢,举例来说:每进来一个 request,会有一个 worker 进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发 request,并等待请求返回。那么,这个处理的 worker 不会这么傻等着,他会在发送完请求后,注册一个事件:”如果 upstream 返回了,告诉我一声,我再接着干”。于是他就休息去了。此时,如果再有 request 进来,他就可以很快再按这种方式处理。而一旦上游服务器返回了,就会触发这个事件,worker 才会来接手,这个 request 才会接着往下走。由于 web server 的工作性质决定了每个request 的大部份生命都是在网络传输中,实际上花费在server 机器上的时间片不多,这就是几个进程就能解决高并发的秘密所在
- 老韩小结:Nginx 的 master-worker 工作机制的优势
1、支持 nginx -s reload 热部署, 这个特征在前面我们使用过
2、对于每个 worker 进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多
3、每个 worker 都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式/IO 多路复用 来处理请求, 即使是高并发请求也能应对.
4、采用独立的进程,互相之间不会影响,一个 worker 进程退出后,其它 worker 进程还在工作,服务不会中断,master 进程则很快启动新的worker 进程
5. 一个 worker 分配一个 CPU , 那么 worker 的线程可以把一个 cpu 的性能发挥到极致
参数设置
worker_processes
- 需要设置多少个 worker
每个 worker 的线程可以把一个 cpu 的性能发挥到极致。所以 worker 数和服务器的 cpu数相等是最为适宜的。设少了会浪费 cpu,设多了会造成 cpu 频繁切换上下文带来的损耗。
- 设置 worker 数量, Nginx 默认没有开启利用多核cpu,可以通过增加 worker_cpu_affinity配置参数来充分利用多核 cpu 的性能
1 | #2 核cpu,开启2 个进程 |
- worker_cpu_affinity 理解
- 配置实例
- vi /usr/local/nginx/nginx.conf
- 重新加载 nginx
/usr/local/nginx/sbin/nginx -s reload
- 查看 nginx 的 worker process 情况
worker_connection
- worker_connection 表示每个 worker 进程所能建立连接的最大值,所以,一个 nginx 能建立的最大连接数,应该是 worker_connections * worker_processes
- 默认:worker_connections: 1024
- 调大:worker_connections: 60000,(调大到 6 万连接)
- 同时要根据系统的最大打开文件数来调整.
系统的最大打开文件数>= worker_connections*worker_process
根据系统的最大打开文件数来调整,worker_connections 进程连接数量要小
于等于系统的最大打开文件数,worker_connections 进程连接数量真实数量=worker_connections * worker_process
查看系统的最大打开文件数
ulimit -a|grep “open files”
open files (-n) 65535
- 根据最大连接数计算最大并发数:如果是支持 http1.1 的浏览器每次访问要占两个连接,所以普通的静态访问最大并发数是: worker_connections * worker_processes /2,而如果 是 HTTP 作 为 反 向 代 理 来 说 , 最 大 并 发 数 量 应 该 是 worker_connections * worker_processes/4。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接, 看一个示意图
配置 Linux 最大打开文件数
使用 ulimit -a 可以查看当前系统的所有限制值,使用 ulimit -n 可以查看当前的最大打开文件数。
新装的linux 默认只有 1024,当作负载较大的服务器时,很容易遇到 error: too many open files。因此,需要将其改大。
使用 ulimit -n 65535 可即时修改,但重启后就无效了。(注 ulimit -SHn 65535 等效 ulimit
-n 65535,-S 指soft,-H 指 hard)
有如下三种修改方式:
- 在/etc/rc.local 中增加一行 ulimit -SHn 65535
- 在/etc/profile 中增加一行 ulimit -SHn 65535
- 在/etc/security/limits.conf 最后增加如下两行记录
- soft nofile 65535
- hard nofile 65535
在 CentOS 中使用第 1 种方式无效果,使用第 3 种方式有效果,而在 Debian 中使用第 2 种有效果
搭建高可用集群
Keepalived+Nginx 高可用集群(主从模式)
集群架构图
- 老韩解读
1、准备两台 nginx 服务器, 一台做主服务器, 一台做备份服务器
2、两台 Nginx 服务器的 IP 地址, 可以自己配置, 不一定和老师一样(具体配置看 Linux 网络配置章节)
3、安装 keepalived , 保证主从之间的通讯
4、对外提供统一的访问 IP(虚拟 IP-VIP)
- 示意图
具体搭建步骤
搭建高可用集群基础环境
1、准备两台 Linux 服务器 192.168.198.130 和 192.168.198.131
- 可以克隆来完成
- 也可以直接拷贝一份
2、在两台 Linux 服务器, 安装并配置好 Nginx
- 安装配置Nginx 步骤前面讲过, 如果你克隆的Linux, 本身就有安装好了Nginx, 直接使用即可.
- 验证安装是否成功, 在 windows 可以通过 IP 访问到 Nginx, 具体的操作步骤和注意事项, 前面也都是说过了
- 因为我们是拷贝了一份 Linux , 而新的Linux 的 Ip 已经变化了, 所以需要克隆的 Linux的 nginx.conf 文件中的 IP 地址, 做相应的修改
- 如图
3、在两台 Linux 服务器, 安装 keepalived
- 下载 keepalived-2.0.20.tar.gz 源码安装包, https://keepalived.org/download.html
- 上传到两台 Linux /root 目录下
- mkdir /root/keepalived
- 解压文件到指定目录: tar -zxvf keepalived-2.0.20.tar.gz -C ./keepalived
- cd /root/keepalived/keepalived-2.0.20
- ./configure –sysconf=/etc –prefix=/usr/local
说明: 将配置文件放在 /etc 目录下, 安装路径在 /usr/local
- make && make install
说明: 编译并安装
如果成功, 就会安装好 keepalived 【可以检查一下】
说明: keepalived 的配置目录在 /etc/keepalived/keepalived.conf keepalived 的启动指令在 /usr/local/sbin/keepalived
提示: 两台 Linux 都要安装 keepalived
完成高可用集群配置
- 将 其 中 一 台 Linux( 比 如 192.168.198.130) 指 定 为 Master : vi
/etc/keepalived/keepalived.conf
将其中一台 Linux( 比如 192.168.198.131) 指定为 Backup( 备份服务器) : vi
/etc/keepalived/keepalived.conf
- 启动 两台 Linux 的keepalived 指令: /usr/local/sbin/keepalived
- 观察两台 linux 的 ens33 是否已经绑定 192.168.198.18
注意事项和细节
1、keepalived 启动后无法 ping 通 VIP,提示 ping: sendmsg: Operation not permitted https://blog.csdn.net/xjuniao/article/details/101793935
2、nginx+keepalived 配置说明和需要避开的坑
https://blog.csdn.net/qq_42921396/article/details/123074780
测试
1、首先保证 windows 可以连通 192.168.198.18 这个虚拟 IP
2、访问 nginx 如图
说明:大家可以看到, 因为 192.168.198.130 是 Master 他的优先级高, 所以访问的就是
192.168.198.130 的 Nginx, 同时仍然是支持负载均衡的.
3、停止 192.168.198.130 的 keepalived 服务, 否则直接关闭 192.168.198.130 主机
, 再次访问 http://192.168.198.18/search/cal.jsp , 这时虚拟 IP 绑定发生漂移, 绑定到
192.168.198.131 Backup 服务, 访问效果如图
这里老师直接关闭 192.168.198.130 Master 的 keepalived 来测试
自动检测Nginx 异常, 终止 keepalived
实现步骤
1、编写 shell 脚本: vi /etc/keepalived/ch_nginx.sh
简单说明: 下面的脚本就是去统计 ps -C nginx –no-header 的行数, 如果为 0 , 说明 nginx已经异常终止了, 就执行 killall keepalived
1 |
|
2、修改 ch_nginx.sh 权限
chmod 755 ch_nginx.sh
3、修改 192.168.198.130 主 Master 配置文件, 指令: vi /etc/keepalived/keepalived.conf
4、重新启动 192.168.198.130 Master 的 keepalived , 这时因为 Master 的优先级高,会争夺到 VIP 优先绑定.
5、手动关闭 192.168.198.130 Master 的 Nginx
注意观察 keepalived 也终止了
6、再次访问 nginx , 发现 192.168.198.18 这个虚拟IP 又和 192.168.198.131 备份服务器绑定了.
注意事项
1、keepalived vrrp_script 脚本不执行解决办法
-打开日志观察
tail -f /var/log/messages
-重启 keepalived
systemctl restart keepalived.service
–老师说明一下: 备课时,曾经出现过文件找不到 可以修改执行脚本文件名,不要有_就 OK
- 如果配置有定时检查 Nginx 异常的脚本, 需要先启动 nginx ,在启动 keepalived ,否则 keepalived 一起动就被 killall 了
- 老师提醒: 小伙伴们配置时,会遇到各种各样问题,有针对性解决即可
- 配置文件keepalived.conf 详解
1 | #这里只注释要修改的地方 |
nginx.conf 详解
1 |
|






































































































