高可用并发解决方案Nginx+keepalived
在这个互联网飞速发展的时代,人们已经离不开网络,其中网购最为常见。在家网购,上班路上网购,吃饭也购物,下班还网购,2019年双十一天猫支付峰值达到了54.4万笔/秒。 热点网站中频繁出现的大量并发如何去解决?
那么在此篇博文中,将介绍目前处理并发能力非常强悍的开源软件nginx快速入门及使用,介绍nginx+ tomcat集群处理并发解决方案,带大家认识虚拟路由,了解虛拟路由的工作流程并安装keepalived,实现nginx+ keepalived主备配置,达到nginx高可用的效果。
Nginx介绍
Nginx下载和安装
Nginx官网:http://nginx.org
Nginx目前已经更新到了1.17.10版本,我们可以直接到官网下载,由于外面服务器大多都使用linux环境作为服务器,所以我们也弄一台linux环境的虚拟机。
虚拟机我们前面已经装好了,IP: 192.168.254.129, 由于nginx是用C语言写的而且还支持地址栏重写等功能,所以我们需要安装一下相关的依赖包。
yum install gcc-c++ yum install -y pcre-devel yum install -y zlib zlib-devel yum install -y openssl-devel
安装流程如下:
1.我们把刚才从官网下载的Nginx,文件上传到centos的/us/local/server目录去。
2.紧接着我们在server目录下创建nginx目录把压缩文件解压,进入解压的文件夹。
3.首先配置nginx安装信息./configure --prefix=nginx安装路径
4.执行编译和安装make && make install
Nginx常用命令
nginx常用命令 nginx -c /usr/1oca1/server/nginx/conf/nginx.conf 启动nginx(windows下start nginx); nginx -s quit 停止ngix nginx -s reload 重新载入nginx(当配置信息发生修改时) nginx -v 查看版本 nginx -t 查看nginx的配置文件的目录 nginx -h 查看帮助信息
Nginx常用命令
主模块
基本指令
daemon
语法:daemon on | off
默认值: on
是否以守护进程的方式运行nginx,守护进程(daemon)是一类在后台运行的特殊进程,关闭守护进程执行的方式可以让我们方便调试nginx
master_process
语法: on | off
默认值: on
是否以master/worker方式进行工作,在实际的环境中nginx是以一个master进程管理多个worker进程的方式运行的,关闭后nginx就不会fork出worker子进程来处理请求,而是用master进程自身来处理请求worker_processes number;默认1,在master/worker运行方式 下worker进程的数目,一般情况下用户要配置与CPU内核数相等的worker进程。
error_log
语法: error_log file [ debug | info | notice | warn | error | crit ]
include
语法: include file |*
默认值: none
可以包含一些其他的配置文件来完成想要的功能。
0.4.4版本以后,include指令已经能够支持文件通配符:
include vhosts/*.conf;
pid
语法: pid file
默认值:编译时指定
pid /var/1og/nginx.pid;
指定pid文件,可以使用kill命令来发送相关信号,例如你如果想重新读取配置文件,则可以使用:
kill -HUP `cat /var/1og/nginx.pid`
user
语法: user user [group]
默认值: nobody nobody
如果主进程以root运行,Nginx将 会调用setuid()/setgid()来设置用户/组,如果没有指定组,那么将使用与用户名相同的组,默认情况下会使用nobody用户与nobody组(或者nogroup) , 或者在编译时指定的-user=USER和-group=GROUP的值。
worker_ processes
语法: worker. processes number
默认值: 1
由于以下几点原因,Nginx可能需要运行不止一个进程
.使用了SMP (对称多处理技术)。
.当服务器在磁盘I/O出现瓶颈时为了减少响应时间。
.当使用selec()/poll()限制了每个进程的最大连接数时。
在事件模块这一章中我们将使用worker_processes和worker_connections来计算理论最大连接数(max _lients) :
max_ clients = worker_processes * worker_connections
Nginx处理HTTP的核心功能模块
基本指令
alias
语法: alias file-path|directory-path;
默认值: no
使用字段: location
这个指令指定一个路径使用某个某个, 注意它可能类似于root,但是document root没有改变,请求只是使用了别名目录的文件。
location /i/ { alias /spoo1/w3/images/; }
上个例子中,请求/top.gif将返回这个文件: */spool/w3/images/top.gif.
Alias同样可以用于带正则表达式的location,如:
location ~ ^/download/(.*)$ { alias /home/website/files/$1; }
keepalive_timeout
语法: keepalive_timeout [ time ][ time ]
默认值: keepalive_timeout 75
使用字段: http, server, location
参数的第一个值指定了客户端与服务器长连接的超时时间,超过这个时间,服务器将关闭连接。
参数的第二个值(可选)指定了应答头中Keep-Alive: timeout= time的time值,这个值可以使一些浏览器知道什么时候关闭连接,以便服务器不用重复关闭,如果不指定这个参数, nginx不会在应答头中发送Keep-Alive信息。(但这并不是指怎样将一个连接“Keep-Alive")
参数的这两个值可以不相同
下面列出了一些服务 器如何处理包含Keep-Alive的应答头:
.MSIE和Opera将Keep-Alive: timeout=N头忽略。
.MSIE保持一个连接大约60-65秒, 然后发送一个TCP RST.
.Opera将一直保持一个连接处于活动状态。
.Mozilla将一个连接在N的基础 上增加大约1-10秒。
.Konqueror保持一个连接大约N秒。
listen
语法(0.7.x): listen address:port [ default [ backlog=num I rovbuf=size | sndbuf= size I accept fitr-fiter I deferred I bind I ssI]]
语法(0.8.x): listen address:port [ default server [ backlog=num I rcvbuf=size I sndbuf=size | accept. filter-filter I deferred | bind |ssl]]
默认值: listen 80
使用字段: server
listen指令指定了server{...}字段中可以被访问到的ip地址及端口号,可以只指定一个ip,一个端口,或者一个可解析的服务器名。
listen 127.0.0.1:8000; listen 127.0.0.1; listen 8000;
listen *:8000;
listen localhost:8000;
location
语法: location [=|~|~*|^~|@]/uri/{..}
默认值: no
使用字段: server
这个参数根据URI的不同需求来进行配置,可以使用字符串与正则表达式匹配,如果要使用正则表达式,你必须指定下
列前缀:
1、~*不区分大小写。
2、~区分大小写。
location =/ { #只匹配/的查询。 [ configuration A ] } location / { #匹配任何以/开始的查询,但是正则表达式与些较长的字符串将被首先匹配。 [ configuration B ] } location ^~ /images/ { #匹配任何以/images/开始的查询并且停止搜索,不检查正则表达式。 [ configuration C ] } location ~* \.(gif|jpg|jpeg)$ { #匹配任何以gif, jpg, or jpeg结尾的文件,但是所有/images/ 目录的请求将在Configuration c中处理。 [ configuration D ] }
resolver_timeout
语法: resolver. timeout time
默认值: 30s
使用字段: http, server, location
解析超时时间。如:
resolver_timeout 5s;
root
语法: root path
默认值: root html
使用字段: http, server, location ,location中的if字段
请求到达后的文件根目录。
下例中:
location /i/ { root /spool/w3; }
如果请求"/i/top.gif"文件,nginx将转到"/spool/w3/i/top.gif"文件。 你可以在参数中使用变量。
注意:在请求中root会添加这个location到它的值后面, 即/i/top.gif 并不会请求"/spool/w3/top.gif"文件,如果要实现
上述类似于apache alias的功能,可以使用alias指令。
server
语法: server {...}
默认值: no
使用字段: http
server字段包含虚拟主机的配置。
没有明确的机制来分开基于域名(请求中的主机头)和基于IP的虚拟主机。
可以通过listen指令来指定必须连接到这个server块的所有地址和端口,并且在server_name指令中可以指定所有的域名。
server_name
语法: server_name name [...]
server_name
语法: server _name name [...]
默认值: server_name hostname
使用字段: server
这个指令有两个作用:
.将HTTP请求的主机头与在nginx配置文件中的server{...}字段中指定的参数进行匹配,并且找出第一个匹配结果。 这就是如何定义虚拟主机的方法,域名遵循下述优先级规则:
1、完整匹配的名称。
2、名称开始于一个文件通配符: *.example.com。
3、名称结束于一个文件通配符: www.example.*。
4、使用正则表达式的名称。
如果没有匹配的结果,nginx配置文件将安装以 下优先级使用[#server server {... }]字段:
1、listen指令 被标记为default的server字段。
2、第一个出现listen (或者默认的listen 80)的server字段。
HTTP负载均衡模块
摘要
这个模块为后端的服务器提供简单的负载均衡(轮询(round-robin) 和连接IP (lient IP) )
如下例:
upstream backend { server 192.168.254.130:8080 weight=5 ; server 192.168.254.129:8080 ; } server { location / { proxy_pass http://backend;
} }
指令
ip_hash
语法: ip_hash
默认值: none
使用字段: upstream
这个指令将基于客户端连接的IP地址来分发请求。
哈希的关键字是客户端的C类网络地址,这个功能将保证这个客户端请求总是被转发到一台服务器上, 但是如果这台服务器不可用,那么请求将转发到另外的服务器上,这将保证某个客户端有很大概率总是连接到一台服务器。
无法将权重(weight) 与ip_hash联合使用来分发连接。如果有某台服务器不可用,你必须标记其为"down",如下例
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
server backend4.example.com;
}
server
语法: server name [parameters]
默认值: none
使用字段: upstream
指定后端服务器的名称和一些参数,可以使用域名,IP, 端口,或者unix socket.如果指定为域名,则首先将其解析为IP。
weight = NUMBER -设置服务器权重,默认为1.
max_ fails = NUMBER 在一定时间内 (这 个时间在fail timeout参数中设置)检查这个服务器是否可用时产生的最多失
败请求数,默认为1,将其设置为0可以关闭检查,这些错误在proxy_next_upstream或fastcgi_next_upstream (404错误
不会使max_ fails增加)中定义。
fail_timeout = TIME 在这个时间内产生了max_ fails所设置大小的失败尝试连接请求后这个服务器可能不可用,同样它
指定了服务器不可用的时间(在下一次尝试连接请求发起之前), 默认为10秒,fail _timeout与前端响应时间没有直接
关系,不过可以使用proxy_ connect _timeout和proxy_read_timeout来控制。
down -标记服务器处于离线状态,通常和ip_hash一起使用。
backup - (0.6.7或更高如果所有的非备份服务器都宕机或繁忙,则使用本服务器(无法和ip_hash指令搭配使用)。
示例配置
upstream backend { server backtynd1.example.com weight=5; server 127.8.0.1:8080 max_fails=3 fail_timeout=30s; server unix: /tmp/backend3 ; }
注意:如果你只使用一台上游服务器,nginx将设置一 个内置变量为1, 即max_fails和fail_timeout参数不会被处理。
结果:如果nginx不能连接到上游,请求将丢失。
解决:使用多台上游服务器。
upstream
语法: upstream name {.. }
默认值: none
使用字段: http
这个字段设置一群服务器, 可以将这个字段放在proxy, passofastcgi pass指令中作为一个单独的实体,它们可以是监听不同端口的服务器,并且也可以是同时监听TCP和Unix socket的服务器。
服务器可以指定不同的权重,默认为1。
示例配置
upstream backend { server backend1.example.com weight=5; server 127.0.0.1:8080 max_fails=3 fail_timeout=30s; server unix:/tmp/backend3; }
HTTP访问控制模块(HTTP Access)
摘要
这个模块提供简单的基于主机的访问控制。
ngx_http_access_module这个模块可以详细的检查客户端P,并且按顺序执行第一条匹配的规则。
如下例:
1 2 3 4 5 6 | location / { deny 192.168.254.128; allow 192.168.1.0 /24 ; allow 10.1.1.0 /16 ; denyall; } |
上面的例子中仅允许192.168.1.0/24和10.1.1.0/16网络段访问,但192.168.1.1是个例外。
如果要实施很多复杂的规则,那么最好使用GeolP module模块。
指令
allow
语法: alow [ address I CIDR I all]
使用字段: http, server, location, limit_except
指令指定了允许访问的IP或网络段。
deny
语法: deny [ address ICIDR I all]
默认值: no
使用字段: http, server, location, limit_except
指令指定了拒绝访问的IP或网络段。
提示和技巧
HttpAccess模块可以和error_page指令搭配使用来重定向一个未经验证的访问请求。
location / { deny 192.168.1.1; allow 192.168.1.0/24; allow 10.1.1.0/16; denyall; }
Nginx + Tomcat实现集群
当我们网站并发是高的时候,一台tomcat无法承受大量并发,可以考虑Nginx+ Tomcat集群来实现。咱们这就做一个集群演示。
配置说明
Nginx搭建图片服务器
针对任何站点,几乎都要访问图片,而一个网页里面几乎有好些张图片,这时候会占据大量tomcat连接,造成大量并发,我们可以通过Nginx配置直接访问硬盘里的图片,绕开tomcat。
我们在根路径/创建一个images目录,然后在images目录放入一些图片, 再在nginx的nginx.conf配置里配置一个虚拟机来访问。
server { listen 80; server_name localhost ; #所有带有images访问的路径直接/images目录下查找 location / { root /images; }
keepalived+ nginx集群解决单点故障
再牛逼的软件我们也不能保证它一定不挂,为了防止上Nginx挂了导致整个服务无法使用的灾难发生,我们这里可以考虑使用Keepalived+Nginx集群实现高可用。
keepalived介绍
Keepalived是一种高性能的服务 器高可用或热备解决方案,Keepalived 可以用来防止服务器单点故障的发生,通过配合Nginx可以实现web前端服务的高可用。
Keepalived以VRRP协议为实现基础,用VRRP协议来实现高可用性(HA)。VRRP(Virtual Router Redundancy Protocol)协议是用于实现路由器冗余的协议,VRRP 协议将两台或多台路由器设备虚拟成一个设备, 对外提供虚拟路由器IP(一个或多个,而在路由器组内部,如果实际拥有这个对外IP的路由器如果工作正常的话就是MASTER,或者是通过算法选举产生,MASTER实现针对虚拟路由器IP的各种网络功能,如ARP请求,ICMP, 以及数据的转发等;其他设备不拥有该虚拟IP,状态是BACKUP,除了接收MASTER的VRRP状态通告信息外,不执行对外的网络功能。当主机失效时,BACKUP 将接管原先MASTER的网络功能。
VRRP协议使用多播数据来传输VRRP数据,VRRP 数据使用特殊的虚拟源MAC地址发送数据而不是自身网卡的MAC地址,VRRP 运行时只有MASTER路由器定时发送VRRP通告信息,表示MASTER工作正常以及虚拟路由器IP(组),BACKUP 只接收VRRP数据,不发送数据,如果-定时间内没有接收到MASTER的通告信息,各BACKUP将宣告自己成为MASTER,发送通告信息,重新进行MASTER选举状态。
方案介绍
VIP | IP | 主机名 | 主从 |
192.168.254.135 | 192.168.254.130 | keep130 | master |
192.168.254.129 | keep129 | backup |
Keepalived安装
将文件上传到服务器,然后解压安装
# cd /usr/1ocal/ server # tar -zxvf keepalived-x.x.x.tar.gz # cd keepalived-1.2.18 #./configure --prefix-/usr/local/server/keepalived # make && make install
将keepalived安装成Linux系统服务
因为没有使用keepalived的默认路径安装(默认是/usr/local) ,安装完成之后,需要做一些工作复 制默认配置文件到默认路径
# mkdir /etc/keepalived # cp /usr/1ocal/server/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/ 复制keepalived服务脚本到默认的地址 # cp /usr/1ocal/server/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ # ln -s /usr/local/server/keepalived/sbin/keepalived /sbin/ 设置keepalived服务开机启动 # chkconfig keepalived on
配置主节点
找到130主机keepalived的配置文件keepalived.conf
global_defs { router id keep130 } vrrp_script chk_ nginx { script "/etc/keepalived/nginx_check.sh" interval 2 weight -20 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 130 mcast_src_ip 192.168.254.130 priority 100 nopreempt advert_int_1 authentication { auth_type PASS auth_pass 1111 } track_script { chk_nginx } virtual_ipaddress { 192.168.254.135 }
配置从节点
global_defs { router id keep129 } vrrp_script chk_nginx { script "/etc/keepalived/nginx_check.sh" interval 2 weight -20 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 130 mcast_src_ip 192.168.254.129 priority 90 advert_int_1 authentication { auth_type PASS auth_pass 1111 } track_script { chk_nginx } virtual_ ipaddress { 192.168.254.135 }
Nginx检查脚本
在/etc/keepalived目录下创建nginx_check.sh文件
#!/bin/bash A= `ps -C nginx --no-header| wc -l` if [ $A -eq 0];then /usr/1oca1/server/nginx/sbin/nginx sleep 2 if [ `ps -C nginx --no-header| wc -l` -eq 0 ]; then killall keepalived fi fi
配置说明
global_defs { ## keepalived 自带的邮件提醒需要开启sendmail 服务。建议用独立的监控或第三方SMTP router_ id keep130 ##标识本节点的字条串,通常为hostname } # keepalived 会定时执行脚本并对脚本执行的结果进行分析,动态调整vrrp. instance 的优先级。如果脚本执行结果为e, 并且weight 配置的值大于e,则优先级相应的增加。如果脚本执行结果非e, 并且weight配置的值小于日,则优先级相应的减少。其他情况,维持原本配置的优先级,即配置文件中priority 对应 的值。 vrrp_script chk_nginx { script "/etc/keepalived/nginx. check.sh" #检测nginx 状态的脚本路径 interval 2 #检测时间间隔 weight -20 #如果条件成立,权重-20
}
#定义虚拟路由,VI. 1为虚拟路由的标示符,自己定义名称 vrrp_instance VI_1 { state MASTER #主节点为MASTER, 对应的备份节点为BACKUP interface eth1 #绑定虚拟IP的网络接口,与本机IP地址所在的网络接口相同,我的是eth1 virtual_router_id 130 #虚拟路由的ID号,两个节点设置必须- 一样,可选IP最后一段使用, 相同的VRID为一个组,他将决定多播的MAC地址 mcast_ src_ ip 192.168.211.130 ##本机IP地址 priority 100 ##节点优先级,值范围0-254, MASTER 要比BACKUP 高 nopreempt #优先级高的设置nopreempt 解决异常恢复后再次抢占的问题 advert_int 1 ##特神组播信息发送间隔,两个节点设置必须-样,默认1s #设置验证信息,两个节点必须-致 authentication { auth_type PASS auth_pass 1111 ##真实生产,按需求对应该过来
}
##将track script块加入instance 配置块
track_script {
chk_nginx #执行Nginx 监控的服务
}
#虚拟IP池,两个节点设置必须一样
virtual_ipaddress {
192.168.199.135 #虚拟ip, 可以定义多个
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!