nginx
Nginx 基本理论
截至2021年,nginx 的市场占有率已经达到世界第一
代理及反向代理
代理
由局域网内向公网请求资源时,由于各种原因,为了请求的正常抵达,需要将请求交由代理服务器进行转发
正向代理需要配置代理,一般在浏览器中进行配置
反向代理
由外部客户端向服务器发起请求时,请求在到达服务器前,可以配置反向代理。请求先到达反向代理服务器,再由反向代理来决定向哪台服务器请求数据,并将请求回来的数据返回给客户端。对外暴露代理服务器的地址
反向代理客户端不需要配置任何东西,对客户端来说是无感的。反向代理服务器与目标服务器,在客户端的严重是一个服务器
负载均衡
简单来说,负载均衡就是反向代理服务器将客户端请求,按照一定规则均衡的分配到各个服务器上去
动静分离
将动态资源与静态资源分开存储于不同的服务器中,根据客户端的请求,由反向代理服务器进行进一步的请求
基本命令
注意:使用命令前,需要进入 “/usr/local/nginx/sbin” 中
查看 nginx 当前版本号
./nginx -V
查看 nginx 是否启动
ps -ef | grep nginx
能搜索到则标识nginx已经启动
启动 nginx
./nginx
强行关闭 nginx
忽略当前已有连接,直接关闭ngxin
./nginx -s stop
安全关闭 nginx
./nginx -s quit
重载 nginx
./nginx -s reload
配置文件
文件位于:
/usr/local/nginx/conf/nginx.conf
nginx的配置格式
三种基本的块:
全局块 —> event块 —> http块
全局块
参数含义:
- worker_processes —— 并发处理的值,此值越大可处理的并发数越大
- error_log —— 不同错误等级的日志写入情况
event块(对 nginx 的性能影响较大)主要控制 nginx 服务器与用户的网络连接,常用设置包括:
- 是否开启对多 work process 下的网络连接序列化
- 是否允许同时接收多个网络连接
- 选取哪种事件驱动模型来处理连接请求
- 每个work process支持的最大同时连接数等
http块(nginx中配置最频繁的地方),代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里。h’t’t’p
http块又分为 http 全局块 和 server 块
- http块 —— 包含文件引入、MIME-TYPE定义、日志自定义、连接超时、单链接请求数上限等
- server块 —— 与虚拟主机有密切关系。server块又可分为全局 server 块和 location 块
nginx开启目录浏览
autoindex on; # 开启目录文件列表
autoindex_exact_size on; # 显示出文件的确切大小,单位是bytes
autoindex_localtime on; # 显示的文件时间为文件的服务器时间
charset utf-8,gbk,gb2312; # 避免中文乱码
add_header Content-Disposition attachment; # 文件下载(可以不开启该功能)
原理解析
nginx中存在两类进程 —— master 和 worker
master 和 worker 的关系
基本原理
master-worker机制的好处
1、对于每个 worker 进程来说,独立的进程不需要加锁,可以省略掉锁的开销
2、每个 worker 是独立的,其中几个 worker 的异常不会影响其他 worker,
worker 设置的依据
当通过异步非阻塞的方式处理请求时,即使进程中只有一个主线程,也可以把一个 cpu 的性能发挥到极致。所以worker数和服务器的cpu数相等最为适宜,过多的设置会导致频繁切换上下文而造成损耗
worker_connection 设置的依据
该值表示每个worker的最大连接数,nginx能建立的最大连接数为:
- http请求本地资源 —— worker_connections * worker_processes
- http 1.1请求本地资源(每次访问占2个连接数) —— worker_connections * worker_processes / 2
- http 做反向代理,每个并发会和客户端与后端保持连接,会占用两个连接
Windows
参考
https://www.cnblogs.com/mollie-x/p/10463140.html
下载 nginx
https://nginx.org/en/download.html
配置 nginx
将下载好的 nginx 解压出来
修改 nginx.conf
添加如下内容
location /apis {
rewrite ^.+apis/?(.*)$ /$1 break;
include uwsgi_params;
proxy_pass http://localhost:8001;
}
- 第一行的 /apis 可以替换为其他任意,这里是用 /apis 来代替 http://localhost:8001 这个。在前端访问 http://localhost:8001/map 这个地址时就用 /apis 即可
- proxy_pass 中为要请求的域名和ip
修改 nginx 的监听端口,将端口修改为需要的即可
启动 nginx
在nginx的根目录下,启动cmd
运行 start nginx 来启动 nginx
或者双击 nginx.exe 亦可
浏览器中输入 127.0.0.1:8888 查看是否启动成功,注意端口使用修改后的
查看跨域问题是否解决
将 html 代码放入 nginx 目录的 html 下
修改代码中关于跨域的请求
原始
修改后
原始代码,疯狂报错跨域问题
修改后代码可正常调用
关闭 nginx
命令:
安全的退出 nginx,在退出前完成现有连接
cmd —> nginx -s quit
直接退出 nginx,不考虑现有连接
cmd —> nginx -s stop
Linux
安装 nginx
下载 nginx
略
安装依赖
依赖包:
- pcre
- openssl
- zlib
安装命令:
sudo yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel
安装 nginx
此处我解压到 /usr/src
进入解压目录,执行
sudo ./configure
进行编译安装
sudo make && make install
配置 nginx
配置 nginx,一定要将 nginx 的安装包放到非 /usr/local目录下!!
当 nginx 安装完毕后,会自动部署到 /usr/local/nginx 中
修改监听端口,进入 /usr/local/nginx/conf 中
vim nginx.conf
此处我将端口修改为 8531
开放端口
查看端口是否开放
firewall-cmd --list-all
开启端口
firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-port=端口号/tcp --permanent
firewall-cmd --reload
启动 nginx
进入 /usr/local/sbin 执行
sudo ./nginx
查看是否启动成功
ps -ef | grep nginx
nginx 配置反向代理 —— 实例一 代理根节点
实现效果:
在浏览器中输入输入地址 www.123.com 跳转到 tomcat 中已有的一个页面
安装 tomcat
下载 tomcat
https://tomcat.apache.org/download-90.cgi
解压 tomcat
tar -zxvf apache-tomcat-9.0.41.tar.gz
启动 tomcat,进入解压目录 —> bin
运行 startup.sh
./startup.sh
回到上级目录,并进入logs,查看日志,确保 tomcat 已启动
tail -f catalina.out
开放端口 8080
firewall-cmd --add-service=http --permanent
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload
浏览器登录 虚拟机的 tomecat 主页
配置 nginx反向代理
最终目的
1、 Windwos 配置 hosts,添加 www.123.com
浏览器测试,此时是通过 8080 端口进行连接。即现在是直接连接的 tomcat 的主页,而非通过 nginx 进行代理的页面
2、添加反向代理,以做到从80端口进行连接
需要进行的修改如下:
1)、修改 http —> server块的 server_name,修改为虚拟机的ip地址,以达到通过 ip 访问的功能
2)、修改 location / {} 添加代理
原始如下
修改如下:
此时则可以通过 www.123.com:8531 的方式跳转到 tomcat 的主页了。即此时已经完成了 nginx 对 tomcat 主页的反向代理
最终效果如下:
修改前
nginx 配置反向代理 —— 实例二 代理不同子节点跳转不同页面
最终目的:通过代理 url 下的不同子节点,来跳转到不同的页面。如:
www.123.com:8531/edu/ —— 跳转至 127.0.0.1:8080
www.123.com:8531/cod/ —— 跳转至 127.0.0.1:8081
注意 127.0.0.1:8080 和 127.0.0.1:8081 是两个不同的 tomcat 服务器
实现效果
修改配置
停止正在运行的 tomcat
# 查看正在运行的 tomcat
ps -ef | grep tomcat
# 关掉进程
kill -9 9018
创建两个 tomcat 服务器
在 /usr/src 下分别创建 tomcat8080 和 tomcat8081 两个目录
tar zxvf apache-tomcat-9.0.41.tar.gz -C tomcat8080
tar zxvf apache-tomcat-9.0.41.tar.gz -C tomcat8081
分别进入两个目录的 bin 下,运行 ./startup.sh
./startup.sh
修改 tomcat8081 目录下的 tomcat 的端口号。进入 conf 修改 server.xml
1、修改 shutdown 的端口,改为8015
2、修改 8080 端口为 8081
3、修改 redirecPort 端口为 8019
4、开放端口 8080、8081
firewall-cmd --add-port=8081/tcp --permanent
firewall-cmd --reload
5、修改环境变量,区分两个 tomcat
# tomcat in port 8080
CATALINA_BASE=/usr/src/tomcat8080
CATALINA_HOME=/usr/src/tomcat8080
TOMCAT_HOME=/usr/src/tomcat8080
export CATALINA_BASE CATALINA_HOME TOMCAT_HOME# tomcat in port 8081
CATALINA02_BASE=/usr/src/tomcat8081
CATALINA02_HOME=/usr/src/tomcat8081
TOMCAT02_HOME=/usr/src/tomcat8081
export CATALINA02_BASE CATALINA02_HOME TOMCAT02_HOME
6、修改 tomcat8081 的 catalina.sh
修改其中所有的 CATALINA_HOME 为 CATALINA02_HOME,替换 CATALINA_BASE 为 CATALINA_BASE02
# 可以使用命令进行批量替换
:%s/CATALINA_HOME/CATALINA_HOME02/g
:%s/CATALINA_BASE/CATALINA_BASE02/g
7、通过浏览器查看两个端口是否可以正常访问
在 tomcat 服务器中分别部署不同的页面
如下 tomcat8080 中部署( tomcat 的 webapps 中新建目录 edu)了一个三维柱状图
在 8081 中部署了一个三维地图
通过 url 连接后,两个页面可通过 tomcat 正常访问
配置 nginx 反向代理
1、打开 nginx.conf,复制一份 server 块 并解除注释
修改为如下形式,其中 location 后的 ~ 表示后面为正则表达式
server {
listen 9001;
server_name 192.168.31.134;
location ~ /edu/ {
proxy_pass http://127.0.0.1:8080;
}
location ~ /vod/ {
proxy_pass http://127.0.0.1:8081;
}
}
2、开放 9001 端口
3、通过 nginx 的 url 和 端口进行访问
http://192.168.31.134:9001/edu/bar3d.html
http://192.168.31.134:9001/vod/map3d.html
补:
localtion 中 ~ 类似的关键字还有:
- ~ —— 区分大小写的正则表达式
- ~* —— 不区分大小写的正则表达式
- = —— 非正则的严格字符串匹配
- ^~ —— 找到和 url 匹配度最高的代理地址进行跳转
nginx 配置负载均衡
实现效果:前端访问页面时,根据服务器的负载情况,自动将请求分配给较为空间的服务器
准备工作:准备两个tomcat,并分别部署相同的页面(我这里就把 8081的 /vod/map3d.html,复制为8081自己的 /edu/bar3d.html)
配置nginx
注意事项
1、进行负载均衡的配置时, server 块中不可存在与负载均衡要配置的相同服务器,否则server块中内容会覆盖 upstream xxx{}中的配置
1、在 http 块中(非server块,在server块外部,一般放在server块的上方),添加如下内容:
upstream myserver{
ip_hash;
server 192.168.31.134:8080 weight=1;
server 192.168.31.134:8081 weight=1;
}
2、确保server{}块中的 “server_name” 是本机的ip地址
3、location / {} 中添加 proxy_pass http://myserver, 其中 myserver要和 upstream 后的服务名(此处就是 myserver)对应
配置后的效果
预先配置的内容:
1、tomcat 8080中, /edu/bar3d.html 的内容为
2、tomcat 8081中 /edu/bar3d.html 中的内容为
负载均衡对 8080 和 8081进行配置后
访问的url为:http://192.168.31.134:9001/edu/bar3d.html
刷新页面(对相同的页面再次请求)
存在的问题
1、本次配置是直接对两个tomcat 的 ip:端口 的形式进行了配置。若某个页面仅存在于其中一台 tomcat 上,则当通过 nginx 访问该页面时,会出现请求时而成功 时而404的情况
上述情况就是 /vod/map3d.html 该页面仅存在于8081的tomcat中导致的
nginx负载均衡的策略
策略如下:
1、轮询(默认策略)
含义:每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除
实现方式,就是 server 后面只跟代理的服务器地址,不加weight
2、weight
含义:权重策略,默认为1,权重越高被分配到的客户端越多
实现方式:server 后跟 weight
3、ip_hash
含义:每个请求按ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。例如:
实现方式:server上添加 ip_hash
4、fair(第三方)
含义:按后端的响应时间来分配,响应时间越短的优先分配
实现方式:
nginx 动静分离
动静分离
含义:不仅仅指将动态资源和静态资源分开,更重要的是把动态请求和静态请求分开。可以理解成用Nginx处理静态页面,Tomcat处理动态页面。
动态请求:数据或者内容是动态生成的,而非提前写好的不变的
静态请求:预先写好的静态的内容,如 html、css、image、json文件等
实现方案:
1、主流。将纯粹的静态文件独立成单独的域名,放在独立服务器上,也是目前主流推崇的方案
2、将动态、静态文件混合一起发布,通过nginx来分开
细节:
1、通过 location 指定不同的后缀名实现不同的请求转发
2、通过 expires 参数设置浏览器缓存的过期时间,以减少访问请求
修改配置
前提:
存在以下两个静态文件
1、 /data/img
2、/data/www
修改 nginx.conf
添加两个静态的跳转地址
上述参数中, autoindex on 代表可以在此目录下查看存在的文件
修改后效果如下:
1、使用了参数 autoindex on 的页面可以预览该目录下存在的资源
没有开启 autoindex 的则无法预览
2、对静态资源的访问
nginx 高可用集群配置
用途:当 nginx 宕机时,保证请求依旧可以正常到达服务器
原理:配置两台 nginx,一台主服务器,一台从服务器
基础软件:keepalived(用于检测 nginx 是否正常,若出问题则切换至备机),keepalived要提供一个对外的虚拟ip,外部请求均请求到虚拟ip
实践
此处我有两台虚拟机 —— centos8(主)、centos7(备)
centos8 —— 192.168.31.134
centos7 —— 192.168.31.133
需要配置(两台都要)
nginx
keepalived
备机配置nginx
安装 nginx 的依赖
yum install -y make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
配置 nginx,一定要将 nginx 的安装包放到非 /usr/local目录下!!
./configure
make && make install
开放端口
firewall-cmd --add-service=http --permanent
firewall-cmd --add-port=8531/tcp --permanent
firewall-cmd --reload
安装 keepalived
使用yum安装
yum install -y keepalived
通过以下命令查看是否安装成功
rpm -q -a keepalived
会默认安装到 /etc 目录下
配置 keepalived
主要步骤:
- 修改keepalived.conf
- 在 /usr/local/src 中添加检测脚本
- 启动nginx和keepalived
- 启动 keepalived —— systemctl start keepalived.service
- 通过虚拟ip进行测试,是否可以正常访问
- 停止主nginx,查看是否可以正常访问
keepalived安装后默认位于 /etc 目录下,其配置文件位于 /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.31.134
smtp_connect_timeout 30
router_id 192.168.31.134 # 此处用唯一值即可,也可以使用ip地址
}
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 ens33 # 网卡,要通过 ipconfig 来确定具体的网卡是什么
virtual_router_id 51 # 主、备机的 virtual_router_id 必须相同
priority 100 # 主、备机取不同的优先级,主机值较大,备机值较小
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress{
192.168.31.150 ## VRRP H虚拟地址
}
}
修改后备站点配置文件
global_defs{
notification_email{
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.31.133
smtp_connect_timeout 30
router_id 192.168.31.133 # 此处用唯一值即可,也可以使用ip地址
}
vrrp_script chk_http_port{
script "/usr/local/src/nginx_check.sh"
interval 2 # 检测脚本的执行时间
weight 2
}
vrrp_instance VI_1{
state BACKUP # 备份服务器上将 MASTER 改为 BACKUP
interface ens33 # 网卡,要通过 ipconfig 来确定具体的网卡是什么
virtual_router_id 51 # 主、备机的 virtual_router_id 必须相同
priority 90 # 主、备机取不同的优先级,主机值较大,备机值较小
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress{
192.168.31.150 ## VRRP H虚拟地址
}
}
检测nginx的bash脚本
#!/bin/bash
A=`ps -C nginx –no-header |wc -l`
if [ $A -eq 0 ];then
/usr/local/nginx/sbin/nginx
sleep 2
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi
将上述内容中的 主、备 keepalived.conf 替换到 /etc/keepalived 中,并且将检测 nginx 的脚本放到 /usr/local/src 中
分别启动 nginx 和 keepalived —— 先启动 nginx
systemctl start keepalived.service
通过虚拟 ip 访问页面,可以正常显示(这里我已将 nginx 的主页配置到 tomcat 中)
在主服务器中输入
ip a 来查看虚拟ip地址
关闭主服务器,再次使用虚拟 ip 进行访问测试
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.31.134
smtp_connect_timeout 30
router_id 192.168.31.134 # 主机的名字,此处用唯一值即可,也可以使用ip地址。若使用主机名的形式则需要在 /etc/hosts中添加 127.0.0.1 此处设置的主机名
}
vrrp_script chk_http_port{ # 脚本配置
script "/usr/local/src/nginx_check.sh"
interval 2 # 检测脚本的执行时间
weight 2
}
vrrp_instance VI_1{ # 虚拟ip配置
state MASTER # 备份服务器上将 MASTER 改为 BACKUP
interface ens33 # 网卡,要通过 ipconfig 来确定具体的网卡是什么
virtual_router_id 51 # 主、备机的 virtual_router_id 必须相同
priority 100 # 主、备机取不同的优先级,主机值较大,备机值较小
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress{
192.168.31.150 ## VRRP H虚拟地址
}
}
- 全局配置
- router_id —— 路由,通过此值来寻找主机。用唯一值即可,也可以使用ip地址。若使用主机名的形式则需要在 /etc/hosts中添加 127.0.0.1 此处设置的主机名