Linux 搭建 nginx+keepalived 高可用 | Nginx反向代理
注意:本文为 “Linux 搭建 nginx+keepalived (主备+双主模式) 高可用 | Nginx反向代理” 相关文章合辑。
Keepalived+Nginx实现高可用(HA)
xyang0917 于 2016-09-17 00:24:15 发布
keepalived 的 HA 分为抢占模式和非抢占模式,抢占模式即 MASTER 从故障中恢复后,会将 VIP 从 BACKUP 节点中抢占过来。非抢占模式即 MASTER 恢复后不抢占 BACKUP 升级为 MASTER 后的 VIP。下面分别介绍 CentOS7 下抢占模式和非抢占模式的配置方式:
1、方案规划
| VIP | IP | 主机名 | Nginx端口 |
|---|---|---|---|
| 192.168.1.210 | 192.168.1.201 | nginx-01 | 80 |
| 192.168.1.210 | 192.168.1.202 | nginx-02 | 80 |
两台服务器的 VIP 为:192.168.1.210
分别在两台 WEB 服务器安装 nginx 和 keepalived:
1、安装 Nginx,请参考《Nginx源码安装》
http://blog.csdn.net/xyang81/article/details/51476293)
2、安装 Keepalived,请参考《Keepalived安装与配置》
http://blog.csdn.net/xyang81/article/details/52554398
3、防火墙添加 arrp 组播规则,或关闭防火墙
1> iptables
shell> vi /etc/sysconfig/iptables
-A INPUT -p vrrp -d 224.0.0.18/32 -j ACCEPT
2> firewall
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface enp4s0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload
4、关闭selinux
shell> vi /etc/sysconfig/selinux
#修改:
SELINUX=disabled
#setenforce 0
2、抢占模式配置
编辑/etc/keepalived/keepalived.conf配置文件
1> MASTER(192.168.1.201):
global_defs {router_id nginx_01 #标识本节点的名称,通常为hostname
}## keepalived会定时执行脚本并对脚本执行的结果进行分析,动态调整vrrp_instance的优先级。
##如果脚本执行结果为0,并且weight配置的值大于0,则优先级相应的增加。如果脚本执行结果非0,
##并且weight配置的值小于 0,则优先级相应的减少。其他情况,维持原本配置的优先级,即配置文件中priority对应的值。
vrrp_script chk_nginx {script "/etc/keepalived/nginx_check.sh"interval 2 #每2秒检测一次nginx的运行状态weight -20 #失败一次,将自己的优先级-20
}
vrrp_instance VI_1 {state MASTER # 状态,主节点为MASTER,备份节点为BACKUPinterface enp0s3 # 绑定VIP的网络接口,通过ifconfig查看自己的网络接口virtual_router_id 51 # 虚拟路由的ID号,两个节点设置必须一样,可选IP最后一段使用,相同的VRID为一个组,他将决定多播的MAC地址mcast_src_ip 192.168.1.201 # 本机IP地址priority 100 # 节点优先级,值范围0~254,MASTER要比BACKUP高advert_int 1 # 组播信息发送时间间隔,两个节点必须设置一样,默认为1秒# 设置验证信息,两个节点必须一致authentication {auth_type PASSauth_pass 1111}# 虚拟IP,两个节点设置必须一样。可以设置多个,一行写一个virtual_ipaddress {192.168.1.210}track_script {chk_nginx # nginx存活状态检测脚本}
}
2> BACKUP(192.168.1.202)
global_defs {router_id nginx_02
}
vrrp_script chk_nginx {script "/etc/keepalived/nginx_check.sh"interval 2weight -20
}
vrrp_instance VI_1 {state BACKUPinterface enp0s3virtual_router_id 51mcast_src_ip 192.168.1.202priority 90advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.1.210}track_script {chk_nginx}
}
3> 创建nginx服务检测脚本
分别在主备服务器/etc/keepalived目录下创建nginx_check.sh脚本,并为其添加执行权限
chmod +x /etc/keepalived/nginx_check.sh
用于 keepalived 定时检测 nginx 的服务状态,如果 nginx 停止了,会尝试重新启动 nginx,如果启动失败,会将 keepalived 进程杀死,将 vip 漂移到备份机器上。
#!/bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then/opt/nginx/sbin/nginx #尝试重新启动nginxsleep 2 #睡眠2秒if [ `ps -C nginx --no-header | wc -l` -eq 0 ];thenkillall keepalived #启动失败,将keepalived服务杀死。将vip漂移到其它备份节点fi
fi
4> 启动 keepalived 服务
shell> service keepalived start
shell> ps -ef | grep keepalived
[root@localhost ~]# ps -ef | grep keepalived
root 865 1 0 23:36 ? 00:00:00 keepalived -D
root 869 865 0 23:36 ? 00:00:00 keepalived -D
root 870 865 0 23:36 ? 00:00:00 keepalived -D
如果看到如上进程信息,表示keepalived已经启动成功。下面用ip add命令查看vip绑定的情况,如下图所示:
从上图可以看出,vip地址192.168.1.210绑定在MASTER(192.168.1.201)的enp0s3网卡上。
5> 测试故障转移
将MASTER上的keepalived停止,查看vip是否会漂移到192.168.2.202上。
停止201的keepalived服务:
shell> service keepalived stop
shell> ip addr12
从上图可以看出,vip已经成功从201漂移到了202。此时再将201的keepalived服务启动后,由于201是MASTER,所以会将202的VIP抢占过来。
启动201的keepalived服务:
shell> service keepalived start1
结果VIP又回到了201,如下图所示:
3、非抢占模式
master从故障中恢复后,不会抢占备份节点的vip
1> MASTER(192.168.1.201):
global_defs {router_id nginx_01 #标识本节点的名称,通常为hostname
}vrrp_script chk_nginx {script "/etc/keepalived/nginx_check.sh"interval 2weight -20
}vrrp_instance VI_1 {state BACKUPinterface enp0s3virtual_router_id 51mcast_src_ip 192.168.1.201priority 100advert_int 1nopreemptauthentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.1.210}track_script {chk_nginx # nginx存活状态检测脚本}
}
2> BACKUP(192.168.1.202)
global_defs {router_id nginx_02
}vrrp_script chk_nginx {script "/etc/keepalived/nginx_check.sh"interval 2weight -20
}vrrp_instance VI_1 {state BACKUPinterface enp0s3virtual_router_id 51mcast_src_ip 192.168.1.202priority 90advert_int 1nopreemptauthentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.1.210}track_script {chk_nginx}
}
和非抢占模式的配置相比,只改了两个地方:
1> 在vrrp_instance块下两个节点各增加了nopreempt指令,表示不争抢vip
2> 节点的state都为BACKUP
两个keepalived节点都启动后,默认都是BACKUP状态,双方在发送组播信息后,会根据优先级来选举一个MASTER出来。由于两者都配置了nopreempt,所以MASTER从故障中恢复后,不会抢占vip。这样会避免VIP切换可能造成的服务延迟。
Linux搭建nginx+keepalived 高可用(主备+双主模式)
the丶only于 2021-06-30 21:46:15 发布
一:keepalived简介
反向代理及负载均衡参考:
- nginx反向代理与负载均衡
https://blog.csdn.net/weixin_52270081/article/details/118297655
当你了解会搭建 nginx 负载均衡后,需要考虑nginx这台服务器的安全性啦,如果只有一台,这台 nginx 一出问题,web 就会无法访问的情况,所以为了应对这种情况,就需要两台nginx做主备服务器。
nginx+keepalived如下图所示:
Keepalived:
是 Linux 下面实现 VRRP 备份路由的高可靠性运行件。基于 Keepalived 设计的服务模式能够真正做到主服务器和备份服务器故障时 IP 瞬间无缝交接。
VRRP 协议:全称 Virtual Router Redundancy Protocol
即虚拟路由冗余协议。可以认为它是实现路由器高可用的容错协议,即将 N 台提供相同功能的路由器组成一个路由器组 (RouterGroup),这个组里面有一个 master 和多个 backup,但在外界看来就像一台一样,构成虚拟路由器,拥有一个虚拟 IP(vip,也就是路由器所在局域网内其他机器的默认路由),占有这个 IP 的 master 实际负责 ARP 相应和转发 IP 数据包,组中的其它路由器作为备份的角色处于待命状态。master 会发组播消息,当 backup 在超时时间内收不到 vrrp 包时就认为 master 宕掉了,这时就需要根据 VRRP 的优先级来选举一个 backup 当 master,保证路由器的高可用。
总结:两台主备机器通过keepalived,虚拟一个IP,也就是VIP,不是贵宾的意思,是Virtual IP的意思。VIP开始为主机器所有,备份机为空闲状态,同时在两台keepalived之间通信相当于有一条心跳线,通过心跳线互相通信,只要主机器监控(通过脚本)到ngin服务停止,则主机器自己停止keepalived,将VIP交给备份机器处理web请求,直至主机器再次恢复正常,将VIP返还给主机器。
高可用有2种方式:
1、Nginx+keepalived 主从配置
这种方案,使用一个vip地址,前端使用2台机器,一台做主,一台做备,但同时只有一台机器工作,另一台备份机器在主机器不出现故障的时候,永远处于浪费状态,对于服务器不多的网站,该方案不经济实惠。
2、Nginx+keepalived 双主配置
这种方案,使用两个vip地址,前端使用2台机器,互为主备,同时有两台机器工作,当其中一台机器出现故障,两台机器的请求转移到一台机器负担,非常适合于当前架构环境。
如下图所示:
模拟搭建环境:4台主机:系统centos7,注:本人搭建的环境为双网卡模式,192.168.200.0/24外网,172.16.2.0/内网。所以本文配置的VIP均为外网IP。
- nginx1:
172.16.2.50(已安装nginx)外网ip:192.168.200.150 - nginx2:
172.16.2.51(已安装nginx)外网ip:192.168.200.151 - web1:
172.16.2.20(已安装nginx,php) - web1:
172.16.2.21(已安装nginx,php)
目的:配置nginx主备,模拟其中一台服务终止后,另外一台可正常访问到web服务器,当那台恢复正常时,两台恢复同时处理请求。
二:在nginx服务安装keepalived软件
keepalived官网:https://www.keepalived.org/
由于yum安装的版本实在太旧了,所以自己下载下来编译安装(不嫌弃旧版本的直接yum -y install keepalived一步到位即可)。
1:安装基础依赖包,有的话就没必要安装了:
主要是gcc ,openssl-devel, libnl, libnl-devel, libnfnetlink-devel, net-tools, vim这几个包。
yum install -y gcc openssl-devel libnl libnl-devel libnfnetlink-devel net-tools vim
2:在官网下载最新版:
目前最新版为2.2.2
wget https://www.keepalived.org/software/keepalived-2.2.2.tar.gz
3: 解压到指定目录,并重命名:
解压,移动到/usr/local目录,重命名keepalived文件夹
tar -zxvf keepalived-2.2.2.tar.gz
mv keepalived-2.2.2 /usr/local/keepalived
4:进入目录编译安装:
cd /usr/local/keepalived/
./configure
make && make install
5:复制相关文件到系统中:
(之所以不喜欢编译安装,就是这一步,由于版本不同,移少移错都可能导致启动失败)
确定好自己的文件路径,复制到系统相关文件夹即可。
mkdir /etc/keepalived
cp /usr/local/keepalived/keepalived/etc/init.d/keepalived /etc/init.d/
cp /usr/local/keepalived/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
cp /usr/local/keepalived/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/sbin/keepalived /usr/sbin/
6:启动测试:
/etc/init.d/keepalived start
提示正确或者OK,则表示安装成功:
但是这时用/etc/init.d/keepalived status 或者 systemctl status keepalived.service命令查看服务是关闭状态,并没有启动起来。
那是因为我们配置文件并没有配置好,无论怎么start都起不来的。
三:keepalived配置文件基础配置
此配置为主备模式,先理解主备后,在配置双主模式更简单。
配置文件位置:/etc/keepalived/keepalived.conf
打开也许会很懵,其实用不了太多模块,先备份原配置,然后删掉其他留下最基础的配置(配置全部参数说明参考本文最后)。
cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
vim /etc/keepalived/keepalived.conf
基础三个模块,global_defs全局模块,vrrp_instance配置vip模块,vrrp_script 脚本模块,用来检测nginx服务。
注:vrrp_script定义脚本后,在vrrp_instance模块必须加上track_script 参数。我就入了这个坑,导致脚本不生效。
global_defs模块参数
notification_email: keepalived在发生诸如切换操作时需要发送email通知地址,后面的 smtp_server 相比也都知道是邮件服务器地址。也可以通过其它方式报警,毕竟邮件不是实时通知的。router_id: 机器标识,通常可设为hostname。故障发生时,邮件通知会用到。
vrrp_instance模块参数
state: 指定instance(Initial)的初始状态, MASTER 或者BACKUP,不是唯一性的,跟后面的优先级priority参数有关。interface: 实例绑定的网卡,因为在配置虚拟IP的时候必须是在已有的网卡上添加的,(注意自己系统,我的默认是ens33,有的是eth0)mcast_src_ip: 发送多播数据包时的源IP地址,这里注意了,这里实际上就是在那个地址上发送VRRP通告,这个非常重要,一定要选择稳定的网卡端口来发送,这里相当于heartbeat的心跳端口,如果没有设置那么就用默认的绑定的网卡的IP,也就是interface指定的IP地址virtual_router_id: 这里设置VRID,这里非常重要,相同的VRID为一个组,他将决定多播的MAC地址priority: 设置本节点的优先级,优先级高的为master(1-255)advert_int: 检查间隔,默认为1秒。这就是VRRP的定时器,MASTER每隔这样一个时间间隔,就会发送一个advertisement报文以通知组内其他路由器自己工作正常authentication: 定义认证方式和密码,主从必须一样virtual_ipaddress: 这里设置的就是VIP,也就是虚拟IP地址,他随着state的变化而增加删除,当state为master的时候就添加,当state为backup的时候删除,这里主要是有优先级来决定的,和state设置的值没有多大关系,这里可以设置多个IP地址track_script: 引用VRRP脚本,即在 vrrp_script 部分指定的名字。定期运行它们来改变优先级,并最终引发主备切换。
vrrp_script模块参数
告诉 keepalived 在什么情况下切换,所以尤为重要。可以有多个 vrrp_script
script: 自己写的检测脚本。也可以是一行命令如killall -0 nginxinterval 2: 每2s检测一次weight -5: 检测失败(脚本返回非0)则优先级 -5fall 2: 检测连续 2 次失败才算确定是真失败。会用weight减少优先级(1-255之间)rise 1: 检测 1 次成功就算成功。但不修改优先级
在主nginx服务器172.16.2.50上, VIP设置为192.168.200.200,配置如下:
global_defs {router_id Nginx_01
}
vrrp_script check_nginx {script "/etc/keepalived/check_nginx.sh"interval 2weight -5fall 3rise 2
}
vrrp_instance VI_1 {state MASTERinterface ens33virtual_router_id 51priority 150advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.200.200}track_script {check_nginx}
}
在备用nginx服务器172.16.2.51上,配置一样,就三点不同,一点必须相同,1. router_id 不同, 2. state BACKUP不同 ,3. priority不同。 4.virtual_router_id 必相同。 配置如下:
global_defs {router_id Nginx_02
}
vrrp_script check_nginx {script "/etc/keepalived/check_nginx.sh"interval 2weight -5fall 3rise 2
}
vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.200.200}track_script {check_nginx}
}
四:nginx脚本与配置
由于待会测试,所以第一个简单脚本就可以了,只要判断nginx进程没有数值,则停止keepalived服务。测试脚本如下:
#! /bin/bash
pidof nginx
if [ $? -ne 0 ];then
/etc/init.d/keepalived stop
fi
如果测试完,可以加个尝试启动nginx,如果尝试失败两次就停止keepalived服务。脚本如下:
#!/bin/bash
counter=$(ps -C nginx --no-heading|wc -l)
if [ "${counter}" = "0" ]; then/usr/local/bin/nginxsleep 2counter=$(ps -C nginx --no-heading|wc -l)if [ "${counter}" = "0" ]; then/etc/init.d/keepalived stopfi
fi
nginx服务器中的nginx配置:只需要把server_name 改成VIP的IP即可,其他无需更改,负载均衡时也只要访问这个VIP地址即可。
upstream phpserver1 {server 172.16.2.20:9091;server 172.16.2.21:9092;
}server {listen 80;server_name 192.168.200.200;location / {proxy_pass http://phpserver1;index index.html index.htm;}}
五:keepalived启动与测试
1:启动nginx服务,在启动keepalived服务:
依次在两台nginx服务器启动,
systemctl restart nginx.service
syetemctl start keepalived
此时在用syetemctl status keepalived查看服务已经正常启动
分别在nginx主备两台用ip addr查看IP地址:主nginx1的网卡此时已经自动获取VIP,备nginx2则没有处于空闲状态
在浏览器访问VIP:192.168.200.200,也正常,可依次负载均衡至两台web服务器的测试页面,如图展示
2:模拟主nginx1的nginx服务停止
systemctl stop nginx.service
再次在两台nginx服务器上ip addr查看ip地址,主nginx1上此时已经没有VIP:192.168.200.200了,在备nginx2此时已经得到VIP了,浏览器访问VIP依然正常可得到web1和web2的测试网页
3:测试再次启动主nginx服务器nginx服务和keepalived服务
systemctl start nginx.service
syetemctl start keepalived
最后在主nginx1上启动nginx后,在启动keepalived后,nginx重新抢回VIP,一切恢复正常。备nginx2恢复空闲状态。可自行测试查看结果。
六:keepalived双主模式
1:keepalived配置
当了解主备模式后,双主模式就容易配置多了。只需要在每台keepalived配置文件,加上一个vrrp_instance命名vrrp_instance VI_2即可,更改几个参数,设置另一个VIP:192.168.200.210
nginx1:state BACKUP ,priority 100, virtual_router_id 52`
`nginx2:state MASTER ,priority 150, virtual_router_id 52
nginx1的配置如下:
global_defs {router_id Nginx_01
}
vrrp_script check_nginx {script "/etc/keepalived/check_nginx.sh"interval 2weight -5fall 3rise 2
}
vrrp_instance VI_1 {state MASTERinterface ens33virtual_router_id 51priority 150advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.200.200}track_script {check_nginx}
}
vrrp_instance VI_2 {state BACKUPinterface ens33virtual_router_id 52priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.200.210}track_script {check_nginx}
}
nginx2配置如下:
global_defs {router_id Nginx_02
}
vrrp_script check_nginx {script "/etc/keepalived/check_nginx.sh"interval 2weight -5fall 3rise 2
}
vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 51priority 150advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.200.200}track_script {check_nginx}}vrrp_instance VI_2 {state MASTERinterface ens33virtual_router_id 52priority 150advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.200.210}track_script {check_nginx}
}
同样,在nginx做负载均衡时,需要在nginx的配置文件中,server_name加上这个192.168.200.210这个VIP2的地址,配置如下:
upstream phpserver1 {server 172.16.2.20:9091;server 172.16.2.21:9092;
}server {listen 80;server_name 192.168.200.200;server_name 192.168.200.210;location / {proxy_pass http://phpserver1;index index.html index.htm;}}
2:启动测试,查看ip
依次重启两台的keepalived服务,查看IP,最后看到的为以下结果,
在浏览器分别访问192.168.200.200和192.168.200.210都可以负载均衡至web1和web2。
双主模式配置完成!!
七:keepalived配置文件详解(参考)
#全局配置
global_defs {# 邮件通知信息notification_email {# 定义收件人acassen@firewall.loc}# 定义发件人notification_email_from Alexandre.Cassen@firewall.loc# SMTP服务器地址smtp_server 192.168.200.1smtp_connect_timeout 30# 路由器标识,一般不用改,也可以写成每个主机自己的主机名router_id LVS_DEVEL# VRRP的ipv4和ipv6的广播地址,配置了VIP的网卡向这个地址广播来宣告自己的配置信息,下面是默认值vrrp_mcast_group4 224.0.0.18vrrp_mcast_group6 ff02::12
}# 定义用于实例执行的脚本内容,比如可以在线降低优先级,用于强制切换
vrrp_script SCRIPT_NAME {}# 一个vrrp_instance就是定义一个虚拟路由器的,实例名称
vrrp_instance VI_1 {# 定义初始状态,可以是MASTER或者BACKUPstate MASTER# 工作接口,通告选举使用哪个接口进行interface ens33# 虚拟路由ID,如果是一组虚拟路由就定义一个ID,如果是多组就要定义多个,而且这个虚拟# ID还是虚拟MAC最后一段地址的信息,取值范围0-255virtual_router_id 51# 使用哪个虚拟MAC地址use_vmac XX:XX:XX:XX:XX# 监控本机上的哪个网卡,网卡一旦故障则需要把VIP转移出去track_interface {eth0ens33}# 如果你上面定义了MASTER,这里的优先级就需要定义的比其他的高priority 100# 通告频率,单位为秒advert_int 1# 通信认证机制,这里是明文认证还有一种是加密认证authentication {auth_type PASSauth_pass 1111}# 设置虚拟VIP地址,一般就设置一个,在LVS中这个就是为LVS主机设置VIP的,这样你就不用自己手动设置了virtual_ipaddress {# IP/掩码 dev 配置在哪个网卡192.168.200.16/24 dev eth1# IP/掩码 dev 配置在哪个网卡的哪个别名上192.168.200.17/24 dev label eth1:1}# 虚拟路由,在需要的情况下可以设置lvs主机 数据包在哪个网卡进来从哪个网卡出去virtual_routes {192.168.110.0/24 dev eth2}# 工作模式,nopreempt表示工作在非抢占模式,默认是抢占模式 preemptnopreempt|preempt# 如果是抢占默认则可以设置等多久再抢占,默认5分钟preempt delay 300# 追踪脚本,通常用于去执行上面的vrrp_script定义的脚本内容track_script {}# 三个指令,如果主机状态变成Master|Backup|Fault之后会去执行的通知脚本,脚本要自己写notify_master ""notify_backup ""notify_fault ""
}# 定义LVS集群服务,可以是IP+PORT;也可以是fwmark 数字,也就是防火墙规则
# 所以通过这里就可以看出来keepalive天生就是为ipvs而设计的
virtual_server 10.10.10.2 1358 {delay_loop 6# 算法lb_algo rr|wrr|lc|wlc|lblc|sh|dh# LVS的模式lb_kind NAT|DR|TUN# 子网掩码,这个掩码是VIP的掩码nat_mask 255.255.255.0# 持久连接超时时间persistence_timeout 50# 定义协议protocol TCP# 如果后端应用服务器都不可用,就会定向到那个服务器上sorry_server 192.168.200.200 1358# 后端应用服务器 IP PORTreal_server 192.168.200.2 1358 {# 权重weight 1# MSIC_CHECK|SMTP_CHEKC|TCP_CHECK|SSL_GET|HTTP_GET这些都是# 针对应用服务器做健康检查的方法MISC_CHECK {}# 用于检查SMTP服务器的SMTP_CHEKC {}# 如果应用服务器不是WEB服务器,就用TCP_CHECK检查TCP_CHECK {# 向哪一个端口检查,如果不指定默认使用上面定义的端口connect_port <PORT># 向哪一个IP检测,如果不指定默认使用上面定义的IP地址bindto <IP># 连接超时时间connect_timeout 3}# 如果对方是HTTPS服务器就用SSL_GET方法去检查,里面配置的内容和HTTP_GET一样SSL_GET {}# 应用服务器UP或者DOWN,就执行那个脚本notify_up "这里写的是路径,如果脚本后有参数,整体路径+参数引起来"notify_down "/PATH/SCRIPTS.sh 参数"# 使用HTTP_GET方法去检查HTTP_GET {# 检测URLurl {# 具体检测哪一个URLpath /testurl/test.jsp# 检测内容的哈希值digest 640205b7b0fc66c1ea91c463fac6334d# 除了检测哈希值还可以检测状态码,比如HTTP的200 表示正常,两种方法二选一即可status_code 200}url {path /testurl2/test.jspdigest 640205b7b0fc66c1ea91c463fac6334d}url {path /testurl3/test.jspdigest 640205b7b0fc66c1ea91c463fac6334d}# 向哪一个端口检查,如果不指定默认使用上面定义的端口connect_port <PORT># 向哪一个IP检测,如果不指定默认使用上面定义的IP地址bindto <IP># 连接超时时间connect_timeout 3# 尝试次数nb_get_retry 3# 每次尝试之间间隔几秒delay_before_retry 3}}real_server 192.168.200.3 1358 {weight 1HTTP_GET {url {path /testurl/test.jspdigest 640205b7b0fc66c1ea91c463fac6334c}url {path /testurl2/test.jspdigest 640205b7b0fc66c1ea91c463fac6334c}connect_timeout 3nb_get_retry 3delay_before_retry 3}}
}
Nginx——Nginx反向代理
啊噢1231 已于 2022-09-15 16:55:51 修改
1、Nginx反向代理概述
正向代理代理的对象是客户端,反向代理代理的是服务端,这是两者最大的区别。
Nginx 既可以实现正向代理,也可以实现反向代理。
1.1、Nginx正向代理

1、服务端的设置
log_format main 'client send request=>clientIp=$remote_addr serverIp=$host';server {listen 80;server_name localhost;# 指定日志文件存放位置和格式access_log logs/access.log main;location / {root html;index index.html index.htm;}}
2、使用客户端访问服务端,打开日志查看结果
client send request=>clientIp=192.168.200.1 serverIp=192.168.200.133
3、代理服务器设置
server {listen 82;# 设置DNS的IP,用来解析proxy_pass中的域名resolver 8.8.8.8;location / {proxy_pass http://$host$request_uri;}}
4、查看代理服务器的 IP(192.168.200.146)和 Nginx 配置监听的端口(82)
5、在客户端配置代理服务器

6、设置完成后,再次通过浏览器访问服务端
浏览器输入url:192.168.200.133服务端日志:client send request=> clientIp=192.168.200.146 serverIp=192.168.200.133
通过对比,上下两次的日志记录,会发现虽然我们是客户端访问服务端,但是如果使用了代理,那么服务端能看到的只是代理发送过去的请求,这样的话,就是用Nginx实现了正向代理的设置。
但是Nginx正向代理,在实际的应用中不是特别多。
1.2、Nginx反向代理
1.2.1、Nginx反向代理的配置语法
Nginx反向代理模块的指令是由ngx_http_proxy_module模块进行解析,该模块在安装Nginx的时候已经自己加装到Nginx中了,接下来介绍反向代理中的常用指令:
- proxy_pass
- proxy_set_header
- proxy_redirect
1、proxy_pass
该指令用来设置被代理服务器地址,可以是主机名称、IP地址加端口号形式。
| 语法 | proxy_pass URL |
|---|---|
| 默认值 | —— |
| 位置 | location |
URL:为要设置的被代理服务器地址,包含传输协议(http,https://)、主机名称或IP地址加端口号、URI等要素。
举例:
proxy_pass http://www.baidu.com;
proxy_pass http://192.168.200.146/;
在编写proxy_pass的时候,后面的值要不要加 / ?
server {listen 80;server_name localhost;location / {# proxy_pass http://192.168.200.146;proxy_pass http://192.168.200.146/;}
}
当客户端访问 http://localhost/index.html,效果是一样的
server {listen 80;server_name localhost;location /server {# proxy_pass http://192.168.200.146;proxy_pass http://192.168.200.146/;}
}当客户端访问 http://localhost/server/index.html这个时候,第一个proxy_pass就变成了http://localhost/server/index.html第二个proxy_pass就变成了http://localhost/index.html,效果就不一样了。
2、proxy_set_header
该指令可以更改Nginx服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给代理的服务器。
| 语法 | proxy_set_header field value; |
|---|---|
| 默认值 | proxy_set_header Host $proxy_host;proxy_set_header Connection close; |
| 位置 | http、server、location |
需要注意的是,如果想要看到结果,必须在被代理的服务器上来获取添加的头信息。
被代理服务器(192.168.200.146):
server {listen 8080;server_name localhost;location / {default_type text/plain;return 200 $http_username;}
}
代理服务器(192.168.200.133)
server {listen 8080;server_name localhost;location /server {proxy_pass http://192.168.200.146:8080/;# 添加请求头信息:username:TOMproxy_set_header username TOM;}
}
3、proxy_redirect
该指令用来重置头信息中的“Location”和“Refresh”的值。
| 语法 | proxy_redirect redirect replacement;proxy_redirect default;proxy_redirect off; |
|---|---|
| 默认值 | proxy_redirect default; |
| 位置 | http、server、location |
为什么要用该指令?
# 服务端(192.168.200.146)
server {listen 8081;server_name localhost;if (!-f $request_filename) {return 302 http://192.168.200.146;}
}
# 代理服务端
server {listen 8080;server_name localhost;location / {proxy_pass http://192.168.200.146:8081/;proxy_redirect http://192.168.200.146 http://192.168.200.133;}
}
server {listen 80;server_name localhost;location / {proxy_pass http://192.168.200.146:8081/;}
}
该指令的几组选项:
proxy_redirect redirect replacement;redirect:目标,location的值replacement:要替换的值
proxy_redirect default;将location块的uri变量作为replacement将proxy_pass变量作为redirect进行替换
proxy_redirect off;关闭proxy_redirect的功能
1.2.2、Nginx反向代理实战

服务器1,2,3存在两种情况:
-
第一种情况:三台服务器的内容不一样;
如果服务器1,2,3的内容不一样,那我们可以根据用户请求来分发到不同的服务器。 # 代理服务器# 服务器1server {listen 9001;server_name localhost;default_type text/html;location / {return 200 '<h1>server:9001</h1>';}}# 服务器2server {listen 9002;server_name localhost;default_type text/html;location / {return 200 '<h1>server:9002</h1>';}}# 服务器3server {listen 9003;server_name localhost;default_type text/html;location / {return 200 '<h1>server:9003</h1>';}}# 代理服务器server {listen 8080;server_name localhost;location /server1 {proxy_pass http://localhost:9001/;}location /server2 {proxy_pass http://localhost:9002/;}location /server3 {proxy_pass http://localhost:9003/;}} -
第二种情况:三台服务器的内容一样。
2、Nginx的安全控制
关于web服务器的安全是比较打的一个话题,里面所涉及的内容很多,Nginx反向代理是如何来提升web服务器的安全呢?
安全隔离
什么是安全隔离?
通过代理分开了客户端到应用程序服务器端的连接,实现了安全措施。在反向代理之前设置防火墙,仅留一个入口供代理服务器访问。
2.1、如何使用SSL对流量进行加密
翻译成熟悉的说法就是将我们常用的http请求转变成https请求,那么这两个之间的区别简单来说两个都是http协议,只不过https是身披SSL外壳的http。
HTTPS是一种通过计算机网络进行安全通信的传输协议,它经由HTTP进行通信,利用SSL/TLS建立全通信,加密数据包,确保数据的安全性。
- SSL(Secure Sockets Layer,安全套接层)。
- TLS(Transport Layer Security,传输层安全)。
上述这两个是为网络通信安全及数据完整性的一种安全协议,TLS和SSL在传输层和应用层对网络连接进行加密。
总结来说为什么要使用https:http协议是明文传输数据,存在安全问题,而http是加密传输,相当于http + ssl ,并且可以防止流量劫持。
Nginx要想使用SSL,需要满足一个条件,即需要添加一个模块 --with–http_ssl_module,而该模块在编译的过程中又需要OpenSSL的支持。
2.1.1、nginx添加SSL的支持
1、完成 --with-http_ssl_module模块的增量添加
将原有 /usr/local/nginx/sbin/nginx 进行备份
拷贝 nginx 之前的配置信息
在 nginx 的安装源码进行配置指定对应模块 ./configure --with-http_ssl_module
通过 make 模板进行编译
将 objs下面的 nginx 移动到 /usr/local/nginx/sbin下
在源码目录下执行 make upgrade 进行升级,这个可以实现不停机添加新模块的功能
2.1.2、Nginx的SSL相关指令
因为刚才我们介绍过该模块的指令都是通过ngx_http_ssl_module模块来解析的。
1、ssl:该指令用来在指定的服务器开启HTTPS,可以使用 listen 443 ssl,后面这种方式更通用些。
| 语法 | ssl on | off; |
|---|---|
| 默认值 | ssl off; |
| 位置 | http、server |
server {listen 443 ssl;
}
2、ssl_certificate:为当前这个虚拟主机指定一个带有PEM格式证书的证书。
| 语法 | ssl_certificate file; |
|---|---|
| 默认值 | —— |
| 位置 | http、server |
3、ssl_certificate_key:该指令用来指定PEM secret key文件的路径。
| 语法 | ssl_certificate_key file; |
|---|---|
| 默认值 | —— |
| 位置 | http、server |
4、ssl_session_cache:该指令用来配置用于SSL会话的缓存。
| 语法 | sse_session_cache off | none | [builtin[:size]] [shared:name:size]; |
|---|---|
| 默认值 | ssl_session_cache none; |
| 位置 | http、server |
- off:禁用会话缓存,客户端不得重复使用会话。
- none:禁止使用会话缓存,客户端可以重复使用,但是并没有在缓存中存储会话参数。
- builtin:内置OpenSSL缓存,仅在一个工作进程中使用。
- shared:所有工作进程之间共享缓存,缓存的相关信息用name和size来指定。
5、ssl_session_timeout:开启SSL会话功能后,设置客户端能够反复使用储存在缓存中的会话参数时间。
| 语法 | ssl_session_timeout time; |
|---|---|
| 默认值 | ssl_session_timeout 5m; |
| 位置 | http、server |
6、ssl_ciphers:指出允许的密码,密码指定为OpenSSL支持的格式。
| 语法 | ssl_ciphers ciphers; |
|---|---|
| 默认值 | ssl_ciphers HIGH:!aNULL:!MD5; |
| 位置 | http、server |
可以使用openssl ciphers查看openssl支持的格式。
7、ssl_prefer_server_ciphers:该指令指定是否服务器密码优先客户端密码。
| 语法 | ssl_prefer_server_cipher on | off; |
|---|---|
| 默认值 | ssl_prefer_server_ciphers off; |
| 位置 | http、server |
2.1.3、生成证书
- 方式1:使用阿里云/腾讯云等第三方服务进行购买;
- 方式2:使用openssl生成证书。
先要确认当前系统是否有安装openssl:
openssl version
安装下面的命令进行生成:
makedir /root/cert
cd /root/cert
openssl genrsa -des3 -out -server.key 1024
openssl req -new -key server.key -out server.csr
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
2.1.4、开启SSL实例
3、Nginx反向代理系统调优
反向代理值Buffer和Cache。Buffer翻译过来是“缓冲”,Cache翻译过来是“缓存”。
总结如下:
相同点:
两种方式都是用来提供 IO 吞吐效率,都是用来提升 Nginx 代理的性能。
不同点:
1、缓冲主要是用来解决不同设备之间数据传递不一致导致的性能低的问题,缓冲中的数据一旦此次操作完成后,就可以删除。
2、缓存主要是备份,将被代理服务器的数据缓存一份到代理服务器,这样的话,客户端再次获取相同数据的时候,就只需要从代理服务器上获取,效率较高,缓存中的数据可以重复使用,只有满足特定条件才会删除。
3.1、Proxy Buffer
3.1.1、Proxy Buffer相关指令
1、proxy_buffering:该指令用来开启或者关闭代理服务器的缓冲区。
| 语法 | proxy_buffering on | off; |
|---|---|
| 默认值 | proxy_buffering on; |
| 位置 | http、server、location |
2、proxy_buffers:该指令用来指定单个连接从代理服务器读取响应的缓存区的个数和大小。
| 语法 | proxy_buffers number size; |
|---|---|
| 默认值 | proxy_buffers 8 4k | 8k; (与系统平台有关) |
| 位置 | http、server、location |
- number:缓冲区的个数。
- size:每个缓冲区的大小,缓冲区的总大小就是number * size 。
3、proxy_buffer_size:该指令用来设置从被代理服务器获取的第一部分响应数据的大小。保持与proxy_buffers中的size一致即可,当然也可以更小。
| 语法 | proxy_buffer_size size; |
|---|---|
| 默认值 | proxy_busy_buffers_size 8k | 16k; |
| 位置 | http、server、location |
4、proxy_busy_buffers_size:该指令用来限制同时处于BUSY状态的缓冲总大小。
| 语法 | proxy_busy_buffers_size size; |
|---|---|
| 默认值 | proxy_busy_buffers_size 8k | 16k; |
| 位置 | http、server、location |
5、proxy_temp_path:当缓冲区存满后,仍未被Nginx服务器完全接收,响应数据就会被临时存放在磁盘文件上,该指令设置文件路径。
| 语法 | proxy_temp_path path; |
|---|---|
| 默认值 | proxy_temp_path proxy_temp; |
| 位置 | http、server、location |
注意path最多设置三层。
6、proxy_temp_file_write_size:该指令用来设置磁盘上缓冲文件的大小。
| 语法 | proxy_temp_file_write_size size; |
|---|---|
| 默认值 | proxy_temp_file_write_size 8k | 16k; |
| 位置 | http、server、location |
通用网站的配置:
proxy_buffering on;
proxy_buffer_size 4 32k;
proxy_buffer_buffers_size 64k;
proxy_temp_file_write_size 64k;
根据项目的具体内容进行响应的调节。
via:
-
Keepalived+Nginx实现高可用(HA)_nginx+keepalived的ha 非抢占模式配置-CSDN博客 xyang0917 于 2016-09-17 00:24:15 发布
https://blog.csdn.net/xyang81/article/details/52556886 -
Linux搭建nginx+keepalived 高可用(主备+双主模式)_nginx+keepalived需要几台机器-CSDN博客 the丶only于 2021-06-30 21:46:15 发布
https://blog.csdn.net/weixin_52270081/article/details/118341576 -
Nginx——Nginx反向代理_nginx反向代理模块-CSDN博客 啊噢1231 已于 2022-09-15 16:55:51 修改
https://blog.csdn.net/weixin_44623055/article/details/124705154
相关文章:
Linux 搭建 nginx+keepalived 高可用 | Nginx反向代理
注意:本文为 “Linux 搭建 nginxkeepalived (主备双主模式) 高可用 | Nginx反向代理” 相关文章合辑。 KeepalivedNginx实现高可用(HA) xyang0917 于 2016-09-17 00:24:15 发布 keepalived 的 HA 分为抢占模式和非抢占模式,抢占…...
Spring Boot 项目中 Maven 剔除无用 Jar 引用的最佳实践
目录 引言Maven 依赖管理的基础概念 2.1 什么是 Maven 依赖2.2 Maven 的依赖传递机制 无用依赖的常见问题与影响剔除无用 Jar 引用的常见方法 4.1 识别无用依赖4.2 使用 Maven 的 dependency:analyze 插件4.3 配置 scope 以优化依赖范围4.4 使用 exclude 排除传递依赖4.5 分析…...
useWhyDidYouUpdate详解
目录 API Params demo演示 源码 useWhyDidYouUpdate是ahooks库中的一个hook函数,用于帮助开发者排查是哪个属性改变导致了组件的 rerender。 API type IProps Record<string, any>;useWhyDidYouUpdate(componentName: string, props: IProps): void; …...
c++入门——c++输入cin和输出cout的简单使用
c输入cin、输出cout 1 cin2 cout3 cin和cout说明 c在c语言的输入、输出函数的基础上进行了封装。 1 cin c可以理解为控制台,in可以理解为输入。 参考代码: void f(){int a;float b;double c;char d;cin>>a>>b>>c>>d;//这里和…...
Spring Cloud LoadBalancer (负载均衡)
目录 什么是负载均衡 服务端负载均衡 客户端负载均衡 Spring Cloud LoadBalancer快速上手 启动多个product-service实例 测试负载均衡 负载均衡策略 自定义负载均衡策略 什么是负载均衡 负载均衡(Load Balance,简称 LB) , 是高并发, 高可用系统必不可少的关…...
微服务-1 认识微服务
目录 1 认识微服务 1.1 单体架构 1.2 微服务 1.3 SpringCloud 2 服务拆分原则 2.1 什么时候拆 2.2 怎么拆 2.3 服务调用 3. 服务注册与发现 3.1 注册中心原理 3.2 Nacos注册中心 3.3 服务注册 3.3.1 添加依赖 3.3.2 配置Nacos 3.3.3 启动服务实例 …...
基于51单片机的交通灯带拐弯proteus仿真
地址: https://pan.baidu.com/s/1cgqRHMHp9VJet4vs5LiG5A 提取码:1234 仿真图: 芯片/模块的特点: AT89C52/AT89C51简介: AT89C52/AT89C51是一款经典的8位单片机,是意法半导体(STMicroelectro…...
1229java面经
1,Java中synchronized关键字是否是可重入的? 可重入的定义 可重入是指当一个线程已经获取了某个对象的锁,在该锁没有释放的情况下,如果这个线程再次请求获取这个对象的锁,是可以成功获取的,而不会出现自己把自己锁死的情况。简单…...
MySQL中查看表结构
1. 使用 DESCRIBE 或 DESC 命令 DESCRIBE(或其简写 DESC)是最简单和最直接的方法,可以显示表的列信息。 语法: DESCRIBE table_name; -- 或者 DESC table_name;示例: 假设有一个名为 employees 的表,可以…...
python利用selenium实现大麦网抢票
大麦网(damai.cn)是中国领先的现场娱乐票务平台,涵盖演唱会、音乐会、话剧、歌剧、体育赛事等多种门票销售。由于其平台上经常会有热门演出,抢票成为许多用户关注的焦点。然而,由于票务资源的有限性,以及大…...
FME教程:一键批量调换图斑X、Y坐标,解决因为坐标弄反了,导致GIS弹窗提示“范围不一致”警告问题
目录 一、实现效果 二、实现过程 1.读取数据 2.提取坐标 3.调换图斑的X、Y坐标 4.输出成果 5.模板的使用 三、总结 在工作中有时候会出现因为失误导致图斑的X、Y坐标弄反,在GIS中打开是会提示“范围不一致”警告的弹窗警告,如果重做工作量非常大…...
OpenCV-Python实战(4)——图像处理基础知识
一、坐标 在 OpenCV 中图像左上角坐标为(0,0),竖直向下为 Y(height) ;水平向右为 X(width)。 二、生成图像 2.1 灰度图像 img np.zeros((h,w), dtype np.uint8) i…...
音视频入门基础:MPEG2-PS专题(1)——MPEG2-PS官方文档下载
一、引言 MPEG2-PS(又称PS,Program Stream,程序流,节目流)是一种多路复用数字音频、视频等的封装容器。MPEG2-PS将一个或多个分组但有共同的时间基准的基本数据流 (PES)合并成一个整体流。它是…...
Qt自定义步骤引导按钮
1. 步骤引导按钮 实际在开发项目过程中,由一些流程比较繁琐,为了给客户更好的交互体验,往往需要使用step1->step2这种引导对话框或者引导按钮来引导用户一步步进行设置;话不多说,先上效果 2. 实现原理 实现起来…...
贝叶斯神经网络(Bayesian Neural Network)
最近在研究贝叶斯神经网络,一些概念一直搞不清楚,这里整理一下相关内容,方便以后查阅。 贝叶斯神经网络(Bayesian Neural Network) 贝叶斯神经网络(Bayesian Neural Network)1. BNN 的核心思想2. BNN 的优化目标3. BNN 的结构与特点4. BNN 的训练过程5. BNN 的优缺点6. …...
Direct Preference Optimization: Your Language Model is Secretly a Reward Model
DPO直接偏好优化:你的语言模型实际上是一个奖励模型 前言知识储备 什么是用户偏好数据目的:用于指导模型行为,使其输出更符合特定用户或者用户群体期望和喜好的信息。 用户偏好数据通常反映了用户对特定内容、风格、观点或者互动方式的倾向。 用户偏好数据的收集通常涉及直…...
如何通过 Kafka 将数据导入 Elasticsearch
作者:来自 Elastic Andre Luiz 将 Apache Kafka 与 Elasticsearch 集成的分步指南,以便使用 Python、Docker Compose 和 Kafka Connect 实现高效的数据提取、索引和可视化。 在本文中,我们将展示如何将 Apache Kafka 与 Elasticsearch 集成以…...
嵌入式系统 第十二讲 块设备和驱动程序设计
• 块设备是Linux三大设备之一(另外两种是字符设备,网络设备),块 设备也是通过/dev下的文件系统节点访问。 • 块设备的数据存储单位是块,块的大小通常为512B至32KB不等。 • 块设备每次能传输一个或多个块,…...
攻防世界web第六题upload
这是题目,可以看出是个上传文件的题目,考虑文件上传漏洞,先随便上传一个文件试试,要求上传的是图片。 可以看到上传成功。 考虑用一句话木马解决,构造文件并修改后缀为jpg,然后上传。 <?php eval($_POST[attack])…...
人工智能-Python网络编程-HTTP
用Python创建自己的HTTP服务器 方案一 HTTP-Python官方 python -m http.server 80 方案二 HTTP-概念版 import socketIPV4_ADDR 192.168.124.7 IPV4_PORT 8888# TCP 服务端程序必须绑定端口号,否则客户端找不到这个 TCP 服务端程序 class ServerSocket(obje…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
前端工具库lodash与lodash-es区别详解
lodash 和 lodash-es 是同一工具库的两个不同版本,核心功能完全一致,主要区别在于模块化格式和优化方式,适合不同的开发环境。以下是详细对比: 1. 模块化格式 lodash 使用 CommonJS 模块格式(require/module.exports&a…...
