前言
当我们访问一个web服务的时候,肯定期望的是这项服务可以持续稳定的为我们提供服务,正常情况下,我们仅仅部署一台web单机实例是可以满足需求的,但是实际情况是由于网络,硬件,以及用户访问量提升导致的单机性能瓶颈等各种奇葩的原因,导致单台服务器宕机,影响到服务的稳定性,那么此时我们需要思考一下如何保证我们的web服务持续稳定的对外提供服务了,web服务持续稳定的对外提供服务,是一个企业级web服务需要具备的要素,目前业界也有很多成熟的方案,最近正好我司也有了一次需要搭建一套高可用(主备)web服务的需求,借此机会也实战一下。
实战
准备
- 整体架构图

- 软件
jdk1.8 download.oracle.com/otn-pub/jav…
nginx1.14.2 nginx.org/download/ng…
keepalived-2.0.13 www.keepalived.org/software/ke…
tomcat8.5 mirrors.shu.edu.cn/apache/tomc… - 硬件
| 主机配置 | IP地址 | 操作系统 | 用途 | 部署路径 |
|---|---|---|---|---|
| Intel(R) Xeon(R) CPU E5-2650 v3 @ 2.30GHz(双路40core)内存256G | 192.168.10.157 | RedHat6.5 | nginx-master & keepalived-master | /home/nginx-server &/home/keepalived-server |
| Intel(R) Xeon(R) CPU E5-2650 v3 @ 2.30GHz(双路40core)内存256G | 192.168.10.167 | RedHat6.5 | nginx-slave & keepalived-slave | /home/nginx-server &/home/keepalived-server |
| Intel(R) Xeon(R) CPU E5-2650 v3 @ 2.30GHz(双路40core)内存256G | 192.168.10.121 | RedHat6.5 | tomcat01 | /home/web-server |
| Intel(R) Xeon(R) CPU E5-2650 v3 @ 2.30GHz(双路40core)内存256G | 192.168.10.152 | RedHat6.5 | tomcat02 | /home/web-server |
部署
创建:
在157,167,121,152主机下创建文件夹
mkdir /home/nginx-server
mkdri /home/keepalived-server
mkdri /home/web-server
mkdri /home/web-server
上传:
一般情况下我是使用rz命令上传文件的,但是有时候会出现上传到99%的时候出现错误,同样这次也遇到了这样的问题,所以问了运维的小伙伴,需要使二进制的方式来上传就可以了。所以 -be 是以二进制的方式来上传文件,将下载的文件上传到每个服务器指定的位置。
rz -be
解压:
# 在157,167主机上执行相同的操作
tar -xvf /home/nginx-server/nginx1.14.2.tar.gz
tar -xvf /home/keepalived-server/keepalived-2.0.13.tar.gz
# 在121,152主机上执行相同的操作
tar -xvf /home/web-server
安装:
由于我这边是网络安全的问题,我们使用源码的方式安装,所以需要我们解压后手动编译安装
# 在157,167主机上执行相同的操作
cd /home/nginx-server/nginx-1.14.2
./configure
make && make install
cd /home/keepalived-server/keepalived-2.0.13
./configure --prefix=/usr/local/keepalived
make && make install
配置:
- nginx配置
修改157,167 两台nginx配置
cd /usr/local/nginx/conf
修改nginx.conf文件
#user nobody;
#工作线程
worker_processes 16;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream css{
#web实例服务器
server 192.168.10.121:21000 weight=1;
server 192.168.10.152:21000 weight=1;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
index index.jsp;
proxy_pass http://css; #在这里设置一个代理,和upstream的名字一样
#以下是一些反向代理的配置可删除
proxy_redirect off;
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数
proxy_connect_timeout 300; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 300; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 300; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
proxy_set_header From "NGINX-1"; #一台测试值NGINX-1,另外一台为NGINX-2
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
- keepalived配置
在157,167服务器中,编写check_nginx.sh 脚本,放在/etc/keepalived
#!/bin/bash
#代码一定注意空格,逻辑就是:如果nginx进程不存在则启动nginx,如果nginx无法启动则kill掉keepalived所有进程
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ];then
./usr/local/nginx/sbin/nginx
sleep 3
if [ `ps -C nginx --no-header |wc -l`-eq 0 ];then
killall keepalived
fi
fi
配置keepalived的配置文件
! Configuration File for keepalived
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh" //检测nginx进程的脚本
interval 2
weight -20
}
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
# 主要修改的地方
vrrp_instance VI_1 {
#matser节点的为MASTER slave 节点的为BACKUP
state MASTER
interface eth0
virtual_router_id 51
mcast_src_ip 192.168.10.157
#matser节点值slave节点的大
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
#对外暴露的ip地址
192.168.10.179
}
}
mkdir /etc/keepalived
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf
# 注意:2.0版本的不是在 /usr/local/keepalived/etc/rc.d/init.d/keepalived,而是在源文件安装目录
cp /home/keepalived-server/keepalived-2.0.13/keepalived/etc/init.d/keepalived /etc/rc.d/init.d/keepalived
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/keepalived
cd /etc/init.d/
chmod +x keepalived
ln -s /usr/local/keepalived/sbin/keepalived /usr/bin/
启动:
- nginx启动
分别启动两台nginx
cd /usr/local/nginx/sbin
./nginx
- keepalived启动
分别启动两台keepalived
service keepalived start
chkconfig keepalived on
service keepalived status

- tomcat启动 分别启动两台tomcat
cd /home/web-server/apache-tomcat-8.5.38/bin
./catalina.sh
正常执行的话就安装完成了,由于我们这边的服务器上需要的相关依赖,运维的小伙伴都已经装的差不多了,所以安装的过程中没有遇到报错的问题,如果你是一台全新的服务器,那么肯定会遇到各种问题,此时就需要小伙伴们展示自己动手能力的时候了,学会如何解决问题。
测试




然后我们测试通过kp的vip来测试


总结
| 主机 | 全部正常 | kp-m&nginx-1挂挂 | kp-s&nginx-2 | tomcat-1挂 | tomcat-2挂 |
|---|---|---|---|---|---|
| keepalived-master | ✔️ | ❌ | ✔️ | ✔️ | ✔️ |
| keepalived-slave | ✔️ | ✔️ | ❌ | ✔️ | ✔️ |
| nginx-master | ✔️ | ❌ | ✔️ | ✔️ | ✔️ |
| nginx-salve | ✔️ | ✔️ | ❌ | ✔️ | ✔️ |
| tomcat-01 | ✔️ | ✔️ | ✔️ | ❌ | ✔️ |
| tomcat-02 | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
| 结论 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
当nginx-master & kp-msater节点挂掉之后,nginx-slave & kp-slave会接替主节点的工作,当主节点恢复后,主节点继续工作,备用节点退出工作状态 通过上面的实战,我们基本上可以搭建出来一套基本的高可用的Web服务,可以稳定持续的对外提供服务。
遇到的问题
部署项目到tomcat后,出现部分js文件请求失败的问题,我们每次强制每次从服务器里面请求最新的js,


proxy_buffers_size 512k
proxy_buffers 4 512kk; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_busy_buffers_size 1024k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k;
然后重启nginx,发现报错

proxy_buffers_size 512k
proxy_buffers 4 512kk; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_busy_buffers_size 1024k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 1024k;
然后测试,可以看到可以正常加载静态资源了
