Keepalived+Nginx+Tomcat配置高可用负载均衡系统示例

前言

此示例为keepalived+nginx+tomcat的基础配置示例,某些特定配置此例中不会出现,在示例中会用到三个虚拟机:两个纯命令行用于模拟服务端配置,一个带桌面环境的用于模拟客户端访问,这样三台虚拟机使用NAT模式连接的时候是在同一个虚拟网络中,更符合服务器的实际使用场景,虚拟机软件为VMPlayer,这个对于个人可以免费使用,用起来来不错,推荐一下。

本实例中是模拟使用场景,机器性能有限,所有nginx和Tomcat就放到一个机器上了,实际场景中如果可以尽量分开,防止nginx所在服务器出问题时跟着当掉一个或多个Tomcat

创建虚拟机

此部分是为了照顾对于虚拟机安装不熟悉的同学,如果已经熟悉了虚拟机的安装或有实体机环境等,可以跳过此步骤

  1. 创建服务器虚拟机(mini安装)

    • 打开VMPlayer,然后界面如下,点击创建新虚拟机

    • 弹出页面后选择最后一项,稍后安装操作系统,这里一定要选择这个,因为如果选择其他直接安装的话会使用简易安装,默认安装完是带桌面的

    • 下一步,然后选择Centos 64位的操作系统,这个需要针对镜像来选择,我这里选这个是因为我有现成的64位镜像

    • 下一步,这里设置下虚拟机的名字和安装地址,便于区分

    • 下一步,然后需要设置硬盘,大小随意(虚拟机创建之后硬盘大小只能增大不能减小了,所以这里可以设置的小一点,亲测配置完成后也就才2G,这里设置5G应该就足够了),下边两项也是二选一随意

    • 下一步,界面如下,这里我们需要点击“自定义硬件”来配置系统的光驱,如果实体机的配置低的话可以在这里降低下虚拟机的CPU和内存等,命令行模式下的CentOS并不需要多高的配置(单核512M可以无压力运行)

    • 在打开的界面中选择光驱,然后选择使用ISO镜像,点击浏览选择镜像即可,这个镜像可以从CentOS官网下载

    • 之后点击关闭,再点击完成即可,此时的界面如下:

    • 此时虚拟机的硬件已经准备完毕,接下来我们点击播放虚拟机配置系统,点击后界面如下,选择第一项Install

    • 接下来稍等片刻会进入图形化界面,这里不用担心,这个只是安装的图形界面,与之后系统没关系,如下:

    • 因为是要最小化安装,所以语言默认英文即可,点击Continue,跳转后的界面为配置界面,我们仅需要修改下图中红框的部分,其他的默认即可。

    • 第一项是配置系统的硬盘,这里我们不需要进行任何配置,点击进入之后直接点击左上角的Done按钮即可

    • 第二项是配置系统的网络,默认不连接,所以我们需要点击进入配置页面,然后将右上角的OFF置成ON,然后点击DONE,之后会跳转回一开始的设置页,我们就可以开始系统的安装了,点击Begin Installation,接下来需要设置用户

    • ROOT用户的密码是必须要创建的,其他用户可以根据需要进行创建,这里我只设置了ROOT用户的密码,方便后续的操作,不用考虑权限问题,实际应用中是要用其他用户操作的,后续的操作可视情况赋予权限即可。还有需要注意的是如果用户的密码强度很低,需要点击两次DONE来确定。

    • 接下来就是等待结束重启即可,至此CentOS就安装完成了

  2. 创建客户端虚拟机(简易安装安装)
    在这个实例中客户端有两个用处,一是通过浏览器测试服务端的服务是否好用;二是通过FTP向服务端上传几个源码包。其实上传源码包这个功能大部分情况下实体机也是可以操作的,但实体机的浏览器在我测试过程中是无法访问服务端的服务的,这个具体的原因不清楚。

    客户端虚拟机对操作系统无限制,只要可以运行浏览器即可,其实命令行模式下的linux也是可以访问的,不过不太直观,如果想用实体机进行访问的话也可以,不过需要将虚拟机的网络连接模式改为桥接模式,而且对网络有要求,需要支持DHCP才可以。

    安装过程和服务端的很类似,只有第二部有所区别,服务器需要选择稍后安装操作系统,但客户端的虚拟机使用第二项选择镜像即可,之后会提示设置系统的用户名和密码,之后的步骤就一样了,而且自定义硬件的时候不再需要设置光驱。

配置基础环境

  • 这里以Server01为示例,其实我们需要配置两台的,我使用的用户是root用户,实际应用中可能需要在其他用户下进行,视情况赋予权限即可。

  • 因为我们需要向虚拟机上传一些用到的软件(当然可以使用wget来下载,只不过有点麻烦),所以这里我们实体机或者客户端使用FTP客户端进行连接(工具有很多,挑选自己顺手的使用,这里推荐Xftp和FileZilla,对于个人使用都是免费的),虚拟机的IP地址可以通过ip addr进行查看,红框中就是当前虚拟机的IP地址

  • 接下来在FTP客户端中输入主机地址,需要注意的是CentOS使用的是SFTP,所以我们输入的地址应该是sftp://192.168.59.130,输入账户密码之后点击快速连接,如果看到如下界面则表示连接成功了

  • 现在系统是配置完成了,不过IP是随机分配的,如果有需要可以将服务器的地址改为静态IP,不过这个IP一般不会发生变化,这里我就先不改了,但是服务器的话是一定会设置固定IP的。

安装JDK

  • 我们常用的SUN JDK不支持yum安装,所以需要从JDK官网下载合适的JDK,这里我使用的是JDK-8u111-linux-x64.rpm,通过ftp上传到/usr/local/download下(这个位置随意),然后分别执行以下命令进行安装,JDK的默认安装地址为/usr/java
cd /usr/local/download
rpm -i jdk-8u111-linux-x64.rpm
  • 安装后即可运行java -version查看安装的版本信息

安装Tomcat

  • Tomcat是可以通过yum进行安装的,不过示例中我们需要两个Tomcat,单独下载更方便,我这里下载的是tomcat 7.0.72。通过FTP将tomcat上传到/usr/local/download下,然后分别运行以下命令解压并移动到/usr/local下,因为后续要使用两个Tomcat,所以我们执行两次操作
tar -xvf apache-tomcat-7.0.72.tar.gz
mv apache-tomcat-7.0.72 /usr/local/Tomcat01
tar -xvf apache-tomcat-7.0.72.tar.gz
mv apache-tomcat-7.0.72 /usr/local/Tomcat02
  • 此时我们的Tomcat已经解压完成了,接下来是修改端口号,防止两个Tomcat端口冲突,Tomcat默认会占用三个端口:8005,8080和8009,这里我们修改成如下,文件为/usr/local/Tomcat01/conf/server.xml和/usr/local/Tomcat02/conf/server.xml(这里如果不熟悉vi编辑器的小伙伴可以将配置文件下载到本地然后修改完成后再上传回服务器)
Tomcat01   8015 8081 8019
Tomcat02   8025 8082 8029
  • 修改完成以后我们进入/usr/local/Tomcat01/bin目录下运行 ./start.sh,会提示Tomcat Started,此时实体机依然是无法访问的,因为防火墙没有开放端口,执行以下命令开放端口,以下命令仅当前会话有效,增加--permanent可以永久保留端口开放状态,不过我们是要做的负载均衡中nginx只会访问本机的Tomcat,所以Tomcat的端口没有必要一直开放,现在测试下就够了
firewall-cmd --zone=public --add-port=8081/tcp
  • 此时我们在客户端虚拟机中访问 http://192.168.59.130:8081 即可看到Tomcat的欢迎页了,此时还有一个问题,两个Tomcat的首页是一样的,负载均衡成功后无法分辨来自哪个Tomcat,所以我们要加点东西区分一下,我是在每个欢迎页的body中增加了一行标识如下,文件位于/usr/local/Tomcat01/webapps/ROOT/index.jsp

安装Nginx

nginx可以通过修改源的方式进行yum安装,有需要的同学可以自行搜索下,本例中使用源码安装

  • 从官网下载源码包后通过FTP将nginx的源码上传到/usr/local/download下,然后执行以下命令解压,我这里使用的是1.10.2
tar -xvf nginx-1.10.2.tar.gz 
  • 之后我们就要用到gcc来编译nginx的源码了,需要先安装gcc
yum install gcc
  • 之后分别执行以下命令,--prefix是指定软件的安装位置
cd /usr/local/download/nginx-1.10.2
./configure --prefix=/usr/local/nginx 
  • 执行之后我们会的到以下错误,我们需要去下载PCRE的源码,然后通过FTP上传到/usr/local/download下,我这里用的是8.39
  • 解压缩pcre的源码,命令和以前的一样,解压后不需要进行其他操作
tar -xvf pcre-8.39.tar.gz 
  • 然后我们再次编译nginx,根据上次的提示我们追加上pcre的源码位置
cd /usr/local/download/nginx-1.10.2
./configure --prefix=/usr/local/nginx --with-pcre=/usr/local/download/pcre-8.39
  • 恭喜,又报错了,这次提示换成了这个,所以我们又需要下载zlib的源码,老办法上传到老地方,然后解压,这里命令就不详细说了,跟之前一样,我下载的版本是1.2.8

  • 解压完成后,我们根据提示追加zlib命令,是的,就追加这两个,不需要再追加了

cd /usr/local/download/nginx-1.10.2
./configure --prefix=/usr/local/nginx --with-pcre=/usr/local/download/pcre-8.39 --with-zlib=/usr/local/download/zlib-1.2.8
  • 编译完成了,执行安装,命令如下
make && make install && make clean
  • 本来以为可以愉快的结束了的,结果。。。。。。

  • 好吧,只能继续安装了

yum install gcc-c++
  • 现在执行前一步的make命令安装就可以了,接下来进入/usr/local/nginx/sbin目录下执行./nginx启动nginx,然后分别执行以下命令开放80端口(永久开放的端口在设置后必须执行reload,本次有效的不需要执行,执行reload后本次有效的端口也将失效)
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --reload
  • 之后我们可以在客户端的浏览器中输入 http://192.168.59.130 进行测试,如果出现如下页面表示nginx启动成功了

  • nginx是可以做成系统服务的,实际应用中也大多是这么做的,不过这里只是个示例,就不做成服务了,如果有需要的可以自行百度,当然如果使用yum安装的话安装完成就已经注册服务了

配置负载均衡

  • 之前Tomcat我们已经做好了配置,接下来只需要在nginx中配置即可,配置文件为/usr/local/nginx/conf/nginx.conf,如下图添加upstream部分,将localtion部分更改为图中部分即可,server可以是其他服务器上的服务,weight越高越容易被分发请求,这里我暂时写本机的,另外实际使用中upstream第一行要加入ip_hash来保证同一用户一次只能访问同一台服务器,解决session跨服务器丢失的问题,如果系统内使用其他方法处理了session的共享问题就不要加了,这个实例中我们就不加入了,因为加入了以后刷新浏览器页面不会变化

  • 接下来就可以进行负载均衡的测试了,因为修改过nginx的配置文件所以我们需要重启一下nginx,然后开启两个Tomcat,命令如下:

/usr/local/nginx/sbin/nginx -s stop
/usr/local/nginx/sbin/nginx
/usr/local/Tomcat01/bin/start.sh
/usr/local/Tomcat02/bin/start.sh
  • 接下来可以在实体机的浏览器进行测试了,连续访问虚拟机的nginx,这时Tomcat欢迎页就会在01和02之间来回切换,至此负载均衡配置结束,然后大家可以回过头去再创建一个Server02重新配置一遍了,因为keepalived就需要根据机器分主次了,配置文件是不一样的,配置完成的话server01的nginx也可以设置将请求分发到server02的tomcat上,不过这里为了演示就不添加了,后续好区分请求由哪台机器响应

配置keepalived

yum install keepalived
  • 安装完成后需要配置keepalived的配置文件,文件位于/etc/keepalived/keepalived.conf,下图中为需要修改的部分,默认的配置文件中在其后还有很多内容,本实例只是简单的DEMO,所以那些内容暂时用不上,可以全部删除,接下来说下图中这部分的配置

    • state 主服务器为MASTER,其他服务器均为BACKUP
    • interface 通信用的网卡,在之前查看IP时可以看到
    • virtual_router_id 主从服务器此ID必须一致
    • priority 优先级,主服务器必须大于其他服务器,数值越大优先级越高
    • authentication 主从服务器必须一致
    • virtual_ipaddress 虚拟IP地址,主从服务器必须一致,此IP为客户端访问时使用的IP
    • 更多详细的配置请参考:Nginx+Keepalived实现站点高可用

    keepalivedconf

  • 配置完此文件后保存退出,然后重启keepalived服务,此时通过ip addr查看发现主从服务器上都有192.168.59.100的虚拟IP,原因是防火墙阻止了服务器之间的vrrp通信,分别执行以下命令,需要针对自己电脑进行修改的只有interface后的网卡,其他的照抄即可

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface eno16777736 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 --out-interface eno16777736 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload
  • 至此Keepalived的配置也完成了,通过ip addr查看可发现主服务上带有192.168.59.100的虚拟IP而从服务器上没有,关闭主服务器的keepalived,虚拟IP则会转移到从服务器上来,测试服务器通过浏览器访问 http://192.168.59.100 可看到虚拟IP转移的效果,页面会从主服务器的页面转换为从服务器的页面,这里就不上图片了

  • 完成上述步骤之后keepalived已经可以实现虚拟IP转移了,但是实际应用当中我们需要的是自动进行虚拟IP的转移,所以我们还需要配置keepalived的脚本,使其能够在某一个nginx无法提供服务的时候自动将虚拟IP转移到备用服务器,以下脚本来自于上边提供的链接,原理是通过curl访问某一个链接,如果连续两次三秒没有响应则降低服务器的优先级,我们在/etc/keepalived目录下创建一个名为check_status.sh的文件,然后键入以下内容

#!/bin/bash
count=0
for (( k=0; k<2; k++ ))
do
    check_code=$( curl --connect-timeout 3 -sL -w "%{http_code}\n" http://localhost/login.html -o /dev/null )
    if [ "$check_code" != "200" ]; then
        count=$(expr $count + 1)
        sleep 3
        continue
    else
        count=0
        break
    fi
done
if [ "$count" != "0" ]; then
    exit 1
else
    exit 0
fi
  • 因为脚本后续是需要执行的,所以我们需要赋予可执行的权限,此脚本是我们自定义的,没有什么安全问题,此项操作需要在root用户下执行,代码如下(这里感谢 程序人生0407 的提醒)
chmod +x check_status.sh
  • 之后我们在keepalived.conf中配置脚本,配置内容如下
vrrp_script check_status {
    script "/etc/keepalived/check_status.sh"
    interval 5
    weight -5
}
vrrp_instance VI_1 {
    state MASTER
    interface eno16777736
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.59.100
    }
    track_script {
        check_status
    }
}
  • 配置完成后重启keepavlied即可,此时如果关闭本机的nginx的话可以看到在5秒后虚拟IP会漂移到备用服务器上去,这里因为演示的话图片太多了,就不上图片了,nginx退出可以执行nginx -s stop命令,如果是使用yum安装的nginx可以通过systemctl来停止nginx服务

  • 实际使用当中经常使用到的还有在切换服务器时发送邮件用以提醒运维人员主服务器异常,方法有很多种,此例中就不再赘述,有兴趣的可以自行查找相关资料

本示例到此结束,如果各位有什么意见或建议,欢迎留言指教,转载请注明源地址
另说明,markdown文档中的代码由于未知原因传上来以后格式有点混乱,大家使用的时候注意下格式,不要少个括号之类的

原文地址:https://www.cnblogs.com/aotian/p/6132071.html