一、Nginx 简介
1️⃣ Nginx 概述
Nginx(Engine X) 是一个高性能的HTTP和反向代理服务器,特点是占有内存少,并发能力强。同时也提供了IMAP/POP3/SMTP服务
nginx可以作为静态页面的web服务器,同时还支持CGI协议的动态语言,比如pex以、php等
但是不支持java。Java程序只能通过与tomcat配合完成
Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率,能经受高负载的考验,有报告表明能支持高达50,000个并发连接数
2️⃣ 正向代理
3️⃣ 反向代理
反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器P地址。
4️⃣ 负载均衡
单个服务器解决不了,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡
5️⃣ 动静分离
为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力
6️⃣ 如何区分正向代理和反向代理?
- 反向代理(Reverse Proxy) 和 正向代理(Forward Proxy 是代理服务器的两种类型,它们的主要区别在于代理的方向不同
(1)正向代理的作用是代理客户端进行访问,即客户端通过正向代理来访问其他的服务器资源
-
在这种情况下,代理服务器是向Internet提供服务的客户端。
-
举个例子,如果您的公司内有一个局域网,您希望在局域网内的电脑通过您的公司提供的互联网访问其他网站资源,您可以配置一个正向代理服务器。这个正向代理服务器会代替内网电脑向互联网请求资源,获得相关响应后再把结果返回给内网电脑。
(2)反向代理则是代理服务器代理服务器端的服务,即客户端使用正常的方式访问后,由代理服务器来把请求转发到真正的服务器端,把服务器端的响应返回给客户端
-
在这种情况下,代理服务器相当于服务器的门面,向客户端提供相应的服务,隐藏后面的真实服务器。
-
举个例子,如果您有一个在Internet上的网站,使用一个反向代理服务器可以帮助您解决负载均衡、高可用性和安全等问题。反向代理服务器可以接受来自Internet的客户端请求并将其转发到具有适当资源的服务器,甚至可以处理SSL终止、缓存和流量压缩等高级功能。
(3)总之,正向代理和反向代理的区别在于代理的方向不同。正向代理是代理客户端访问其他服务器资源,而反向代理是代理服务器端提供服务。
二、Nginx 安装
🅰️ 准备材料 【为了降低版本差异带来的影响,我选择使用和老师一样的版本】
- nginx-1.12.2.tar.gz
- pcre-8.37.tar.gz
🅱️ 环境搭建 【我用的是最小版本的CentOS7】
(1)因为新配置的虚拟机缺少相关工具,通过 yum -y install vim wget curl net-tools zip unzip
下载
(2)使用XShell连接到我们的虚拟机,并通过 yum -y install lrzsz
指令下载小文件拖拽快速传输工具
(3)将我们Windows本地下载的两个安装包拖拽到 /usr/src 目录下
(4)通过 tar -zxvf pcre-8.37.tar.gz
解压,然后 cd 解压出来的目录,然后执行 ./confgure
检查
在 Linux 系统中,执行 ./configure 命令通常是为了在将软件包编译安装到系统中之前对其进行配置。该命令会自动检测和识别系统上的相关软件和库,并根据其特定的配置选项生成适当的 Makefile 文件,方便后续执行 make 命令进行编译
如果最后一行出现:configure: error: You need a C++ compiler for C++ support
我们需要通过 yum install -y gcc gcc-c++
安装gcc、c++编译环境,然后重新执行 ./configure
(5)最后再执行 make && make install
完成安装
(6)通过 yum -y install make zlib zlib-devel gcc-c++libtool openssl openssl-devel
安装其他依赖
(7)通过 tar -zxvf nginx-1.12.2.tar.gz
解压,然后会出现一个 nginx 的相关目录,进入这个目录
(8)先执行 ./configure
,再执行 make && make install
完成 nginx 的安装
⭕️ 开启Nginx
(1)通过 cd /usr/local/nginx/sbin
我们来到nginx执行文件目录
(2)通过 ./nginx
启动
❌ 防火墙放行 nginx 端口
(1)通过 firewall-cmd --list-all
查看当前防火墙放行的端口
(2)通过 sudo firewall-cmd --add-port=80/tcp --permanent
添加要放行的端口
(3)通过 firewall-cmd --reload
重新加载防火墙
☀️ 浏览器测试
此时通过访问我们虚拟机的IP地址,可以显示出来 Nginx 的页面说明已经配置成功了
三、Nginx 常用命令
🌔 1、最基础的几个命令
(1)使用 nginx 操作命令的前提是进入到 nginx 的目录中: cd /usr/local/nginx/sbin
(2)通过 ./nginx -v
查看 nginx 的版本号
(3)通过 ./nginx
启动 nginx
(4)通过 ./nginx -s stop
关闭 nginx
(5)通过 ./nginx -s reload
重新加载 nginx
四、反向代理
-
此处我将通过两个案例来演示如何实现反向代理的配置
-
首先,我们要知道 nginx 的配置文件位置
-
其次,我们需要大致了解配置文件中分为几部分:
-
第一部分:全局块
- 从配置文件开始带 events 块之间的内容,主要会设置一些影响 nginx 服务器整体运行的配置指令
- 例如:worker_processes 1【 nginx服务器支持的并发的处理器】
-
第二部分:events 块
- events 块涉及的指令主要影响 nginx 服务器与用户的网络连接
- 例如:worker_connections: 1024 【支持的最大连接数】
-
第三部分:http 块
- nginx 服务器配置中最频繁的部分
- http 块也可以包括 http 全局块、server 块
-
-
通过这篇文章,在反向代理部分我们需要掌握两个内容
- 如何通过 nginx 转发到自己的服务器当中
- 如何根据路径转发到不同的端口服务中去
案例一
1️⃣ 准备工作
-
在 Linux 系统安装 tomcat,使用默认端口 8080 【此处使用的是 tomcat-7.0.70 】
-
将压缩包上传到
/user/src
目录下,解压 tomcat 压缩包
-
进入到 tomcat 目录的
bin
目录下,执行./startup.sh
启动 tomcat
-
通过日志查看启动效果
-
-
对外开放 tomcat 的端口 【在防火墙中进行设置】
-
在浏览器中进行测试:
-
PS:如果虚拟机中没有安装Java的JDK,可以参考这篇文章:亲测好用
2️⃣ 案例需求分析
我们想通过访问 www.123.com 的方式,直接访问到我们虚拟机中的 tomcat
tomcat 是我们虚拟机内部的web服务器,所以我们需要通过 nginx 服务器来完成反向代理
3️⃣ 完成案例需求
(1)我们需要到本地 host 中进行配置,完成域名到IP的映射
-
找到我们电脑的 host 文件
-
编辑文件添加域名和ip地址的映射规则 【在我们保存修改的时候,可能会出现权限不够的提示,可以参考这篇文章亲测好用】
-
到浏览器进行访问测试
-
我们希望通过访问 www.123.com 直接来到这个界面,而无需指定端口号
(2)在 nginx 的配置文件中进行反向代理的配置
-
将配置文件中的 server_name 改成虚拟机的 ip
-
在 location / 中添加转发规则,
proxy_pass http://127.0.0.1:8080;
(3)重启 nginx 到浏览器的地址栏进行访问测试 >> 测试成功
案例二
- 案例效果:
- 使用 nginx 反向代理,根据访问的路径跳转到不同端口的服务中,nginx 监听端口为 9001
- 访问 http://192.168.132.144:9001/edu/ 直接跳转到 127.0.0.1:8080
- 访问 http://192.168.132.144:9001/vod/ 直接跳转到 127.0.0.1:8081
1️⃣ 准备工作
- 准备两个 tomcat 服务器,一个使用 8080 端口,一个使用 8081 端口
(1)在 /usr/src
目录下创建两个文件夹 tomcat8080 tomcat8081
(2)在我们这两个文件夹下分别放一个tomcat 【我是通过拷贝的方式】【在拷贝之前我把 tomcat8081删了,所以后面会重新创建】
(3)关掉原来的 tomcat 【我是通过命令查看到进程号为 28600,这个不是固定的】
(4)启动我们8080端口的tomcat
(5)修改另一个tomcat的配置文件 【修改了三处】
(6)启动端口为8081的tomcat
- 创建文件夹和测试文件
(1)给我们的 tomcat8080 创建一个文件
(2)通过浏览器访问这个文件测试
(3)在tomcat8081中创建文件
(4)在浏览器中进行测试
知道怎么回事儿了,因为我这个防火墙没放行8081的端口
再次进行测试
PS:因为后续需要用到9001的端口,所以此处我直接将这个端口添加到防火墙中
至此,案例二的准备工作就做完了
2️⃣ 反向代理配置
(1)进入文件夹 cd /usr/local/nginx/conf
,编辑我们的 nginx 的配置文件,添加下面的代码块
(2)重新启动nginx
(3)测试
PS 对 location 的补充说明:
-
location 指令用于匹配 URL:
location [ = | ~ | ~* | ^·] uri {}
=
用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求~
用于表示 uri 包含正则表达式,并且区分大小写~*
用于表示 uri 包含正则表达式,并且不区分大小写^~
用于不包含正则表达式的 uri 前,要求 Nginx 服务器找到表示 uri 和请求字符串匹配度最高的 location 后,立即使用此location 处理请求,而不再使用 location 块中的正则 uri 和字符串做匹配
-
如果 uri 包含正则表达式,则必须要有
~
或者~*
标识
server {
listen 80;
server_name example.com;
location ^~ /api/ {
proxy_pass http://localhost:8080;
# 此处省略其它配置项
}
# 其它 location 配置
}
五、负载均衡
- 我们通过案例来演示 负载均衡 如何配置,以及实现效果
- 需求分析:
- 在浏览器地址栏输入地址 http://192.168.131.144/edu/a.html,平均分配到 8080 端口和 8081 端口中
- 换句话说,就是将请求平均分担到不同的服务器中
1️⃣ 准备工作
- 准备两台 tomcat 服务器,一台 8080 端口,另一台 8081 端口 【这在反向代理的部分已经完成了】
- 在两台 tomcat 服务器 里面 webapps 目录中,分别创建 edu 文件夹,该目录下再创建 a.html 用于测试
- 在反向代理部分,已经在 8080 的 tomcat 中完成了这部分的准备
- 所以,我们只需要在 8081 的 tomcat 中创建目录和文件即可
2️⃣ 修改nginx配置文件
-
找到nginx的配置文件并编辑
-
添加下面的代码块 【注意:这部分放到我们 http 块中,为了避免和之前的配置冲突,将这部分放到最上面】
3️⃣ 浏览器测试
4️⃣ 接下来介绍一下我们 Nginx 实现负载均衡的几种分配策略: 【配置到我们upstream中】
(1)轮循
- 默认的分配策略
- 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器宕机了,能自动删除
(2)weight
-
weight 代表权重,默认为1,权重越高被分配的客户端越多
-
指定轮循几率,weight 和访问比率成正比,用于后端服务器性能不均的情况
-
以下是配置案例
upstream myserver{ server 192.168.132.144:8080 weight=5; server 192.168.132.144:8081 weight=10; }
(3)ip_hash
-
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 问题
upstream myserver{ ip_hash; server 192.168.132.144:8080; server 192.168.132.144:8081; }
-
当访客发起同一个请求访问不同的服务器时,会有可能出现 Session 不一致的问题。这是因为在 Web 应用程序中,会话(Session)是一种跨请求的状态保持机制。当用户在 Web 应用程序中进行操作时,服务器会创建一个唯一的 Session ID,并将此 ID 与用户相关联。然后,服务器通过 Cookie 或 URL 重写机制将此 ID 发送给客户端,以便客户端的每个请求都包含此 ID。这样,服务器就能够识别用户并查找与其相关联的 Session 数据。
-
当用户访问不同的服务器时,如果这些服务器之间没有共享 Session 数据,那么每个服务器都会创建自己的 Session 数据,并使用自己的 Session ID。这样,当用户跳转到另一个服务器时,将不能识别其之前在另一个服务器上已创建的 Session 数据,从而导致 Session 不一致问题。
为了解决此类问题,通常有以下几种方法:- 使用 Nginx upstream 模块进行 Session 的 Sticky,使得同一个客户端请求会被分配到同一个应用服务器,从而保证 Session 不会出现不一致的问题。
- 将 Session 数据存储在共享存储中,例如 Redis、Memcached 等,以便多个应用服务器共享 Session 数据。
- 对于无法共享 Session 的应用场景,可以采用无状态的分布式架构,即将 Session 数据存储在客户端而非服务端。
-
总之,解决多个服务器之间的 Session 不一致问题通常需要对应用程序进行相应的配置和调整,以保证 Session 数据的正确性和一致性。
(4)fair (第三方)
-
按后端服务器的响应时间来分配请求,响应时间越短的优先分配
upstream myserver{ server 192.168.132.144:8080; server 192.168.132.144:8081; fair; }
六、动静分离
-
Nginx 动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离,可以理解成使用gs处理静态页面,Tomcat处理动态页面。
-
动静分离从目前实现角度来讲大致分为两种
- 一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案
- 另外一种方法就是动态跟静态文件混合在一起发布,通过gx来分开
-
通过location指定不同的后缀名实现不同的请求转发。
-
通过expires参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。
-
具体Expires定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量
- 此种方法非常适合不经常变动的资源。(如果经常更新的文件,不建议使用Expires来缓存)
- 我这里设置3d,表示在这3天之内访问这个URL,发送一个请求
- 比对服务器该文件最后更新时间没有变化,则不会从服务器抓取,返回状态码 304
- 如果有修改,则直接从服务器重新下载,返回状态码200
- 不配置前是访问不到静态资源的 【因为不在我们tomcat的webapps目录下】
1️⃣ 准备工作
(1)在根目录下创建 date 目录,再创建 www 、image 两个子目录
(2)www中存放a.html、image中存放nginx.jpg
2️⃣ 配置 nginx
(1)来到配置文件路径
(2)编辑
(3)整体操作流程
3️⃣ 浏览器测试
- autoindex on 的作用是列出文件目录
七、高可用
-
Nginx 高可用性(High Availability,HA)是指 通过配置多个 Nginx 服务器,以确保在其中一个或多个服务器无法工作时,其他服务器可以继续提供服务并保证服务的可靠性和可用性
-
通常情况下,Nginx HA 的实现方法有以下几种:
- 负载均衡(Load Balancing):在多个 Nginx 服务器之间分配负载,以均衡请求流量,避免单个服务器负载过高而崩溃。负载均衡可以通过 DNS 轮询、IPVS、Nginx 自身的负载均衡模块等方式实现
- 故障切换(Failover):在一台 Nginx 服务器无法正常工作时,将请求流量转移到其他可用的服务器上,以确保服务的连续性和稳定性。故障切换可以通过使用自动化的工具、手动干预等方式实现
- 集群化(Clustering):将多个 Nginx 服务器组成一个集群,以实现分布式架构,提高系统的可用性和伸缩性。集群化可以通过基于 keepalived、Pacemaker、Corosync 和 DRBD 等工具和技术实现
- 数据同步和数据备份:将关键数据存储在多个服务器上,并通过数据同步和数据备份等技术确保数据的所有权和一致性。数据同步和数据备份可以通过使用 Nginx 的高级模块、第三方插件和存储解决方案实现
-
总之,Nginx 的高可用性是通过配置多个 Nginx 服务器并使用负载均衡、故障切换、集群化、数据同步和数据备份等技术来实现的。通过合理的配置和应用,可以确保 Nginx 服务的正常运行,并提供可靠的服务
- 接下来通过案例来演示如何通过故障切换的方式来保证 nginx 的高可用
1️⃣ 准备工作
(1)需要两台服务器 192.168.132.144 和 192.168.132.145
(2)在两台服务器上安装 nginx
(3)在两台服务器安装 keepalived
我采取的办法是在我们现有的 centOS1 基础上安装 keepalived,然后再拷贝出来一个虚拟机,这样就达到了要求
- 通过
yum install keepalived -y
安装 keepalived,在/etc
目录下会生成 keepalived 目录,其中有它的配置文件 keepalived.conf
- 通过
rpm -q -a keepalived
可以查看版本号 - 然后拷贝一个虚拟机 centOS2 出来
2️⃣ 修改 keepalived 的配置
-
给我们主机设置名称
-
编写我们 keepalived.conf 配置文件 【直接移动到
/etc/keepalived
目录下覆盖原文件】global_defs { notification_email{ acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.132.144 smtp_connect_timeout 30 router_id LVS_DEVELBACK } vrrp_script chk_http_port { script "/usr/local/src/nginx_check.sh" interval 2 # 检测脚本执行的间隔 weight 2 } vrrp_instance VI_1 { state MASTER # 备份服务器上将 MASTER 改为 BACKUP interface ens32 //网卡 virtual_router_id 51 #主备机的这个id一定要相同 priority 100 # 主、备机取不同的优先级,主机值较大,备机值较小 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress{ 192.168.17.50 //VRRP H虚拟地址 } }
-
编写我们 nginx_check.sh 脚本 【放到
/usr/local/src
目录下】#!/bin/bash A=`ps -C nginx -no-header | wc -1` if[ $A -eq 0];then /usr/local/nginx/sbin/nginx sleep 2 if [ `ps -C nginx --no-header | wc -1` -eq 0];then killall keepalived fi fi
-
配置好这两个文件,重启我们的 nginx 和 keepalived
- 到浏览器中测试我们的虚拟IP
- 然后配置我们的第二台 centOS2,和上面的方法大同小异,在 keepalived 配置文件有所区别
state BACKUP
priority 90
smtp_server 192.168.132.145
八、Nginx 原理
1️⃣ master相当于管理者,worker可以有多个,当请求进来后,master告诉worker,worker进行处理
2️⃣ worker 是如何进行工作的呢?
3️⃣ master-workers 机制的好处
首先,对于每个worker进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。
其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快启动新的 worker进程。
当然,worker进程的异常退出,肯定是程序有bug了,异常退出,会导致当前worker上的所有请求失败,不过不会影响到所有请求,所以降低了风险。
4️⃣ 那么我们需要设置多少个 worker 呢?
Nginx同redis类似都采用了io多路复用机制,每个worker都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求,即使是千上万个请求也不在话下。
每任worker的线程可以把一个cpu的性能发挥到极致。所以worker数和服务器的cpu数相等是最为适宜的。
设少了会浪费cpu,设多了会造成cpu频繁切换上下文带来的损耗。
5️⃣ 连接数 worker connection
-
第一个:发送请求,占用了woker的几个连接数?
- 如果是静态请求,那么占用了2个连接数 【从客户端到nginx,从nginx到客户端】
- 如果是动态请求,那么占用了4个连接数 【在上面的基础上还有两条到tomcat的连接】
-
第二个:nginx有一个master,有四个woker,每个woker支持最大的连接数据1024,支持的最大并发数是多少?
- 普通的静态访问最大并发数是: worker connections * worker_processes / 2
- 而如果是HTTP作为反向代理来说,最大并发数量应该是 worker connections * worker_processes / 4