web集群高可用实战

1,529 阅读6分钟

前言

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

实战

准备

  • 整体架构图

主机配置 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

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

测试

可以看到nginx反向代理按照我们配置的权重策略来执行的

然后我们测试通过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,

刚开始怀疑的原因是静态资源路径经过nginx路径出现问题,然后把js的url直接拿出来请求判断,不是路径问题。然后再经过对比分析,所有的静态资源只有这一个是超过100kb的,大概700kb左右,然后就想是否是文件过大,超过了限制的文件大小。那么我们就去查看了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 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; 

然后测试,可以看到可以正常加载静态资源了