反向代理服务器 Nginx
1 什么是Nginx
-
Nginx 是一个高性能的 Web 和反向代理服务器, 它具有很多非常优越的特性,特点是反向代理
-
作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。能够支持高达 50,000 个并发连接数的响应。
-
作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP代理服务器 对外进行服务。Nginx 用 C 编写, 不论是系统资源开销还是 CPU 使用效率很优秀。
-
作为邮件代理服务器: Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器)。
-
Nginx(还能够支持perl语法),Bugs非常少的服务器: Nginx 启动特别容易,并且几乎可以安装非常的简单,配置文件 非常简洁做到7*24不间断运行,即使运行数个月也不需要重新启动,还能够在不间断服务的情况下进行软件版本的升级。
-
我们看不到淘宝、京东有服务暂停的情况,而且还在不断升级,就是因为它们用的就是Nginx(实现原理:设了AB组服务器,A组运行1.0,B组更新2.0后无缝切换,然后运行一段时间,确认无重大漏洞时,再把A组升级到2.0,然后切回A组)
-
反之,游戏服务器就不是这样,游戏服务器有时候需要停机维护,一般在人少的时候,比如早上6点
2 什么是CDN
CDN就是一个内容分发者,服务提供者在全国每一个CDN节点上储存相同的数据( 比如图片),用户就近访问,这就实现了加速。
当然,代价就是一张图片要存到200多个节点上,每次修改都要改动200多次,这就是典型的空间换时间,而CDN加速的中间件,或者说CDN用的服务器就是Nginx
抖音、淘宝等服务提供商,最大的成本支出就是CDN代理,太贵了
3 安装Nginx到Linux中
3.1 下载、解压
首先安装Nginx的依赖
yum -y install zlib zlib-devel openssl openssl-devel
yum -y install patch
如果yum很卡,那就手动切换到阿里云的源
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
然后去百度搜索NGINX,就能找到官网,在里面就能找到downloda 下载包,下载tar.gz格式
使用Xftp放到虚拟机的opt/soft下
在soft文件夹下直接解压nginx
tar zxvf nginx-1.21.3.tar.gz
解压后进入nginx解压出的文件夹,可以看到有许多东西,其中conf包下就有nginx的配置文件nginx.conf
3.2 配置nginx
按照官网的文档进行配置
当然,简单一点,在nginx文件夹下,直接运行下面的代码就行了,这会配置好Nginx,注意要放在一行里运行
./configure --prefix=/usr/local/nginx --pid-path=/usr/local/nginx/nginx.pid --error-log-path=/usr/local/nginx/logs/error.log --http-log-path=/usr/local/nginx/logs/access.log --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-stream --http-client-body-temp-path=/usr/local/nginx/tmp/client/ --http-proxy-temp-path=/usr/local/nginx/tmp/proxy/
配置nginx编译环境的各个属性说明,上面这一长串已经配置好了,如果有需要,自己改一下就行
./ configure : 配置nginx的编译环境
–pid-path : nginx的进程文件存放目录
--error-log-path : 错误日志存放目录
--http-log-path : 请求日志存放目录
module : Nginx中的功能,基本上都是以module的形式存在
with-http_stub_status_module : 性能统计
with-http_ssl_module : 支持https
with-http_gzip_static_module : 扩展压缩模块,支持.gz
with-http_realip_module : 获取用户实际ip
with-stream : tcp代理模块
*-temp-path : 临时数据存储目录
3.3 编译安装
执行完上面一长串代码后,如果没有报错就说明配置成功,此时执行 make编译Nginx
再执行 make install进行安装
都执行后,根据官方文档,我们可以前往usr/local/nginx查看是否有这个目录,有就说明安装成功
进入这个目录,可以看到确实存在文件
此时查看conf目录,可以看到有下面几个文件,其中nginx.conf就是nginx的配置文件
另一个nginx.conf.default是Nginx安装时自动创建的一个备份文件
接着还能查看sbin目录,可以看到只有一个绿色的脚本文件
进入sbin目录,然后运行这个脚本,可以显示Nginx配置
./nginx -V //在sbin目录下运行这个命令,可以显示Nginx配置,判断Nginx是否安装成功 注意要用./开头
或者直接使用
/usr/local/nginx/sbin/nginx -V //这样就不用./了
3.4 补全Nginx需要的配置
使用下面命令,可以查看Nginx的配置是否齐全
/usr/local/nginx/sbin/nginx -t
出现如图的提示,说明配置没有齐全,需要进一步补充
使用下面的命令创建上图提到的缺失的文件夹,这里mkdir后面加-p 就能避免需要创建的目录client的上级目录 tem不存在时报错的问题 它会自动递归把上级目录一块创建
mkdir -p /usr/local/nginx/tmp/client/
再次查看,可以发现提示OK,就证明没问题了
3.5 查看Nginx的配置文件
使用下面的代码,就能打开Nginx.conf,conf文件中的部分参数已经在3.2步骤配置好了,比如错误日志输出目录等
vim /usr/local/nginx/conf/nginx.conf
3.6 启动Nginx
使用下面的代码就能启动Nginx服务器,其中 -c 表示使用指定的Nginx配置文件,后接配置文件的地址
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
如果无法启动,那可能是端口没有被加入防火墙白名单,执行下面代码
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --reload
然后重启Nginx
/usr/local/nginx/sbin/nginx -s reload
按照步骤来,应该就没问题了
4 Nginx作为web服务器 配置静态web页面
使用Xftp把静态web页面放到home目录下
然后修改Nginx.conf中的设置,图中的代码意思是当访问Nginx服务器根目录时,自动访问/home/www文件夹下的index.html文件(如果没有就访问index.htm文件)
启动Nginx,可以看到静态页面可以正常被访问
5 手动映射ip地址到自定义域名
可以看到上面访问页面中,浏览器地址是ip,要是想做成域名的样子也行
如果希望别人通过我们指定的域名访问到我们指定的ip,我们就得去域名商那购买
如果希望只是自己本地上看一下就简单了,在win或mac系统下,自己修改一下host文件,映射一下域名和ip地址就行了,这样我们在地址栏输入自定义域名,电脑访问映射的ip地址
6 Nginx实现反向代理(中介)
Nginx服务器的主要功能就是反向代理,作为中介,当用户访问Nginx服务器时,被分配到后方的tomcat服务器上
要实现这个功能,首先要在Nginx.conf中配置一个新的标签——upstream
这个标签在http下,与server同级,在这个标签里配置要关联的服务器的ip和端口号,这里为了方便练习,不开虚拟机了,所以都连接了本地ip
接着设置请求转发,当用户访问Nginx根目录时,自动被转到Nginx关联的服务器群(这里设置的是上面关联好的erp)
6 Linux下查看日志
语法 | 说明 |
---|---|
vim ../logs/error.log | 查看日志 |
echo ''>../logs/error.log | 清空日志 |
echo '字符串'>> ../logs/error.log | 在日志最后一行追加字符串 |
tail | 在屏幕上显示指定文件的末尾若干行,默认在屏幕上显示指定文件的末尾10行 |
tail -t ../logs/error.log | 进入监控状态,持续显示指定日志文件最新追加的内容,使用ctrl+C退出这个状态 |
我们一般只用tail -t命令查看日志,不使用vim编辑器查看
7 java项目部署到Linux的Nginx服务器下
7.1 springboot项目打包和自测
将springboot项目打包
然后可以先测试一下,右键target,选择open in terminal 可以在IDEA的控制台使用命令直接运行打好的包,由于整个包由springboot项目封装形成,这就等于启动了springboot项目,连带着使用了tomcat服务器
7.2 修改运行jar包的端口号
在执行jar包后,会根据打包前springboot项目中yml配置的端口监听请求,如果需要换一个端口监听,一种方式是手动指定端口号
另一种方式是在yml修改端口号
7.3 在Linux下运行jar包 实现项目部署
确认无误后就可以把jar包放到Linux的opt下,具体文件夹可以自定义
这里有两个包,是因为要练习Nginx关联两个服务器的知识点,要区分用户访问到的是哪个服务器,所以需要两个有差异的包
接着在linux启动jar包即可,下面的代码会让jar包运行,并且在Xshell界面上显示
java -jar 包名.jar
但是这样界面就会被占用,没办法再去启动别的jar包,所以我们可以使用“后台启动”
java -jar 包名.jar &
但是这样我们就没办法看这个进程执行的怎么样了,所以要指定进程输出log,我们就能随时查看日志了解进程
java -jar 包名.jar >> log文件名.log &
分别运行两个jar包,此时就部署好了,在win或mac下访问ip+端口号,就等同于访问了springboot项目,可以看到结果
如果jar包运行时指定的端口,比如8081还没在Linux系统的防火墙上打开,要记得打开,否则会提示拒绝访问
firewall-cmd --permanent --zone=public --add-port=8081/tcp
firewall-cmd --reload
8 Nginx轮询以及DNS分流
在上面的实例中,当用户访问Nginx服务器时,会被Nginx以轮询的方式分配请求给8080端口和8081端口
Nginx不参与业务逻辑的运算,只是分配请求,让关联的tomcat服务器负责运算,Nginx只要带宽足够承载前端的请求就行。
如果前端流量很大,就用第二个Nginx,但是如何均分两个Nginx的流量?
这个流量均分的场景如果是游戏,那么就直接让游戏入口显示“爆满”,不允许用户进入就行,用户自己会去别的大区。
但是网页没办法,只能让运营商协助。
运营商通过DNS分流给不同的Nginx,对应的技术就是DNSpod,专门做分流
不过一般需要这种技术的都得是国民级别的网站,得上亿访问量,如果真需要这种分流需求,只能花钱,技术解决不了的
9 ip_hash策略
Cookie和Session的区别(面试必备)_chen13333336677的博客-CSDN博客_cookie和session区别面试
Nginx默认使用轮询机制,但是这会导致一个问题,如果使用随机或轮询,用户每次访问的服务器是不同的,就可能出现用户明明选择了记住账号密码,结果下次登录又得重新输入。
原因就是用户携带的cookie与服务器A的session对应,而session储存在服务器A上,那么用户去访问服务器B时,自然对应不上身份,就需要重新输入。
一种解决方式就是ip_hash策略
那么我们可以在集群服务器数量不变的情况下,比如一直保持4台服务器,让Nginx自动对访问的ip地址取余,比如余数为1,就分配到第一台服务器执行请求,这就能保证每个用户在后续访问时都是前往固定的服务器,这就能避免用户要反复登录的情况。
只需要在upstream中设置“ip_hash”
但这有个弊端,一但集群服务器数量变化,那么几乎所有ip都会被重新分配服务器
所以更常用的做法就是不使用tomcat的session,而是手动模拟session,详见下面链接
10 Nginx设置流量限制
为了防止用户恶意访问,可以在Nginx设置限流,放置雪崩效应
请求限制的功能来自于ngx_http_limit_req_module 模块
NGINX由众多模块组成,通过模块实现功能,下图是官方文档中显示的Nginx自带的模块
将下面的代码配置到Nginx.conf中http下
limit_req_zone $binary_remote_addr zone=javasmlimit:10m rate=1r/s; //配置到http下
语法 | 说明 |
---|---|
limit_req_zone | 只能配置在 http 范围内 |
$binary_remote_addr | 代表客户端ip |
javasmlimit | 是自定义变量名 |
rate | 请求频率,同一个ip每秒允许多少请求;rate=1r/s; 每秒只处理1次请求,超过的请求拒绝处理。 |
10m | 指定缓冲区大小,1M能存储16000 IP地址,10M可以存储16W IP地址访问信息 可以认为这是大小为10M的map |
将下面的代码配置到Nginx.conf中http的server的location中,表示当前请求会根据javasmlimit规则来限流
limit_req zone=javasmlimit burst=3 nodelay; //配置到location中
语法 | 说明 |
---|---|
nodelay | 不延迟处理 |
burst | 配置超额处理,可简单理解为队列机制,这里配置了缓存3个请求 |
配置如图
11 修改Nginx报错时的返回值
前后端交互时,浏览器接收到的是JSON,但Nginx默认配置中,如果出现500、502、503、504错误,就会返回50X.html页面
这就会导致前后端数据交互不一致,前端就会报错
此时只需要在Nginx.conf中,把发生错误时会回传的.html改为json即可,也可以改为图片等数据,只要能被前端解析都行
12 Nginx控制并发数 基于第三方Nginx组件
百度Nginx 3rd,就能找到许多的第三方Nginx组件
这个网站里有许多Nginx开发者发布的组件,比如把Nginx储存ip地址的功能交给redis,现在Nginx只有10M空间,有时候不太够,但是交给redis,那就等于无限制了
又比如自动根据访问的地址切换Nginx组件
又或者实现控制并发连接数
http模块添加
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
location模块添加
limit_conn perip 10;#单个客户端ip与服务器的连接数
limit_conn perserver 100; #限制与服务器的总连接数
# 限制传输速度(如果有N个并发连接,则是 N * limit_rate)
limit_rate 1024k;
总之组件非常丰富,按需取用