【Linux运维-集群技术进阶】Nginx+Keepalived+Tomcat搭建高可用/负载均衡/动静分离的Web服务器集群

本文主要是介绍【Linux运维-集群技术进阶】Nginx+Keepalived+Tomcat搭建高可用/负载均衡/动静分离的Web服务器集群,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

额,博客名字有点长。。。

前言

终于到这篇文章了,心情是有点激动的。因为这篇文章会集中以前博客讲到的所有Nginx功能点,包括基本的负载均衡,还有动静分离技术再加上这篇文章的重点,通过Keepalived实现的HA(High Available),为什么要实现高可用呢?以前在搭建的时候只用了一台Nginx服务器,这样的话如果Nginx服务器宕机了,那么整个网站就会挂掉,所以要实现Nginx的高可用,一台挂掉还会有另一台顶上去,从而保证网站可以持续的提供服务。关于负载均衡和动静分离在前面博客中都有相关的介绍,这篇博客就不在详细提了,只会在配置文件中体现。不多说了,下面开始搭建。


拓扑环境

下面表格是这次测试需要的拓扑环境,几台服务器,每台服务器上安装什么,都有介绍。

服务器名称系统版本预装软件IP地址/VIP
Nginx主服务器CentOS 7 最小安装Nginx +Keepalived192.168.22.227/192.168.22.231
Nginx从服务器CentOS 7 最小安装Nginx +Keepalived192.168.22.228/192.168.22.231
Web服务器ACentOS 7 最小安装tomcat+jdk192.168.22.229
Web服务器BCentOS 7 最小安装tomcat+jdk192.168.22.230


前置条件

这是一个系列博客,如果有困难可以查看之前的博客。
服务器配置VIP:http://blog.csdn.net/u010028869/article/details/50574907
Keepalived安装见:http://blog.csdn.net/u010028869/article/details/50527817
Keepalived原理解析:http://blog.csdn.net/u010028869/article/details/50596805
Nginx动静分离、负载均衡:http://blog.csdn.net/u010028869/article/details/50522033


原理图

这里写图片描述


开始搭建

一、配置VIP

关于VIP(即虚拟IP)的作用,上篇博客《Keepalived原理篇》已经介绍过了。227和228服务器需要配置相同的VIP,虚拟IP在某时刻只能属于某一个节点,另一个节点作为备用节点存在。当主节点不可用时,备用节点接管虚拟IP,成为主节点(即虚拟IP漂移至从节点),提供正常服务。这个VIP就像个墙头草,两头跑,谁是主他就为谁服务。配置VIP的博客,上面也有链接哦。

二、安装软件

按照上面的表格,在相应服务器上安装软件,安装过程不再多说了,有问题可以点击上面的博客链接哦。

三、配置Nginx

227服务器上的Nginx配置:

    user nobody;worker_processes 2;events{worker_connections 1024; }http{#设置默认类型为二进制流default_type    application/octet-stream;server_names_hash_bucket_size   128;#指定来自客户端请求头的headerbuffer大小,设置为32KBclient_header_buffer_size   32k;#指定客户端请求中较大的消息头的缓存最大数量和大小,这里是4个32KBlarge_client_header_buffers 4 32k;#上传文件大小client_max_body_size 356m;#nginx的HttpLog模块指定,指定nginx日志的输出格式,输出格式为accesslog_format access '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';#access日志存在未知access_log  /usr/local/nginx/logs/access.log    access;#开启高效模式文件传输模式,将tcp_nopush和tcp_nodelay两个指另设置为on,用于防止网络阻塞。sendfile    on;tcp_nopush  on;tcp_nodelay on;#设置客户端连接保持活动的超时时间keepalive_timeout   65;server_tokens   off;#客户端请求主体读取缓存client_body_buffer_size 512k;proxy_connect_timeout   5;proxy_send_timeout      60;proxy_read_timeout      5;proxy_buffer_size       16k;proxy_buffers           4 64k;proxy_busy_buffers_size 128k;proxy_temp_file_write_size 128k;#fastcgi_connect_timeout 300;#fastcgi_send_timeout   300;#fastcgi_read_timeout   300;#fastcgi_buffer_timeout 300;#fastcgi_buffers 4 64k;#fastcgi_busy_buffers_size 128k;#fastcgi_temp_file_write_size 128k;#开启gzipgzip    on;#允许压缩的最小字节数gzip_min_length 1k;#4个单位为16k的内存作为压缩结果流缓存gzip_buffers 4 16k;#设置识别HTTP协议版本,默认是1.1gzip_http_version 1.1;#gzip压缩比,可在1~9中设置,1压缩比最小,速度最快,9压缩比最大,速度最慢,消耗CPUgzip_comp_level 2;#压缩的类型gzip_types text/plain application/x-javascript text/css application/xml;#让前端的缓存服务器混村经过的gzip压缩的页面gzip_vary   on;upstream mycluster{server 192.168.22.229:8080 weight=1;server 192.168.22.230:8080 weight=1;}server{listen 8088;server_name 192.168.22.227;charset    utf-8; #设置编码为utf-8#root   html;#location / {#    root   html;#    index  index.html index.htm;#}#location ~ .*\.(jsp|do|action)$location / {proxy_next_upstream http_502 http_504 error timeout invalid_header;proxy_pass http://mycluster;# 真实的客户端IPproxy_set_header   X-Real-IP        $remote_addr; # 请求头中Host信息proxy_set_header   Host             $host; # 代理路由信息,此处取IP有安全隐患proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;# 真实的用户访问协议proxy_set_header   X-Forwarded-Proto $scheme;}#静态文件交给nginx处理location ~ .*\.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)${root /usr/local/webapps;expires 30d;}#静态文件交给nginx处理location ~ .*\.(js|css)?${root /usr/local/webapps;expires 1h;}error_page   500 502 503 504  /50x.html;  location = /50x.html {root   html;}}}

228服务器上的Nginx配置:

    user nobody;worker_processes 2;events{worker_connections 1024; }http{#设置默认类型为二进制流default_type    application/octet-stream;server_names_hash_bucket_size   128;#指定来自客户端请求头的headerbuffer大小,设置为32KBclient_header_buffer_size   32k;#指定客户端请求中较大的消息头的缓存最大数量和大小,这里是4个32KBlarge_client_header_buffers 4 32k;#上传文件大小client_max_body_size 356m;#nginx的HttpLog模块指定,指定nginx日志的输出格式,输出格式为accesslog_format access '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';#access日志存在未知access_log  /usr/local/nginx/logs/access.log    access;#开启高效模式文件传输模式,将tcp_nopush和tcp_nodelay两个指另设置为on,用于防止网络阻塞。sendfile    on;tcp_nopush  on;tcp_nodelay on;#设置客户端连接保持活动的超时时间keepalive_timeout   65;server_tokens   off;#客户端请求主体读取缓存client_body_buffer_size 512k;proxy_connect_timeout   5;proxy_send_timeout      60;proxy_read_timeout      5;proxy_buffer_size       16k;proxy_buffers           4 64k;proxy_busy_buffers_size 128k;proxy_temp_file_write_size 128k;#fastcgi_connect_timeout 300;#fastcgi_send_timeout   300;#fastcgi_read_timeout   300;#fastcgi_buffer_timeout 300;#fastcgi_buffers 4 64k;#fastcgi_busy_buffers_size 128k;#fastcgi_temp_file_write_size 128k;#开启gzipgzip    on;#允许压缩的最小字节数gzip_min_length 1k;#4个单位为16k的内存作为压缩结果流缓存gzip_buffers 4 16k;#设置识别HTTP协议版本,默认是1.1gzip_http_version 1.1;#gzip压缩比,可在1~9中设置,1压缩比最小,速度最快,9压缩比最大,速度最慢,消耗CPUgzip_comp_level 2;#压缩的类型gzip_types text/plain application/x-javascript text/css application/xml;#让前端的缓存服务器混村经过的gzip压缩的页面gzip_vary   on;upstream mycluster{server 192.168.22.229:8080 weight=1;server 192.168.22.230:8080 weight=1;}server{listen 8088;server_name 192.168.22.228;charset    utf-8; #设置编码为utf-8#root   html;#location / {#    root   html;#    index  index.html index.htm;#}#location ~ .*\.(jsp|do|action)$location / {proxy_next_upstream http_502 http_504 error timeout invalid_header;proxy_pass http://mycluster;# 真实的客户端IPproxy_set_header   X-Real-IP        $remote_addr; # 请求头中Host信息proxy_set_header   Host             $host; # 代理路由信息,此处取IP有安全隐患proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;# 真实的用户访问协议proxy_set_header   X-Forwarded-Proto $scheme;}#静态文件交给nginx处理location ~ .*\.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)${root /usr/local/webapps;expires 30d;}#静态文件交给nginx处理location ~ .*\.(js|css)?${root /usr/local/webapps;expires 1h;}error_page   500 502 503 504  /50x.html;  location = /50x.html {root   html;}}}

另外还需要在227,228服务器上新建一个目录/usr/local/webapps/drp/img,在img文件夹中存放图片girl.jpg。如果Nginx服务器较多的话,可以使用Rsync做服务端自动同步或者使用NFS、MFS分布式共享存储,避免一个个拷贝文件。

还有,这块Nginx配置是做过一些优化的,比如开启gzip压缩,开启高效文件传输模式,设置缓存,动静分离,负载均衡等,可以直接拿到项目中使用。

四、配置Keepalived

227服务器上的Keepalived配置:

! Configuration File for keepalived#配置邮件相关信息global_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id LVS_DEVEL}#配置Nginx健康监测脚本vrrp_script check_nginx {script "</dev/tcp/127.0.0.1/8088"interval 3weight -2}vrrp_instance VI_1 {state MASTER#网卡名称interface eno16777736virtual_router_id 151priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}track_script {check_nginx}virtual_ipaddress {192.168.22.231}}

228服务器上的Keepalived配置:

    ! Configuration File for keepalivedglobal_defs {notification_email {acassen@firewall.locfailover@firewall.locsysadmin@firewall.loc}notification_email_from Alexandre.Cassen@firewall.locsmtp_server 192.168.200.1smtp_connect_timeout 30router_id LVS_DEVEL}vrrp_script check_nginx {#script "/opt/chknginx.sh"script "</dev/tcp/127.0.0.1/8088"interval 3weight -2}vrrp_instance VI_1 {state MASTERinterface eno16777736virtual_router_id 151priority 99advert_int 1authentication {auth_type PASSauth_pass 1111}track_script {check_nginx}virtual_ipaddress {192.168.22.231}}


特别注意,Nginx健康监测脚本。在本地写一个shell脚本,Keepalived监测不到。不知道为什么,网上的博客都是这么写的。但是在我这里就不行。最后直接在Keepalived配置文件的script标签中写了这段监测的脚本,才得以成功。

    vrrp_script chk_http_port {script "</dev/tcp/192.168.22.227/80"interval 1weight -10}

另外,如果你不明白某些配置的意思,可以查看上篇博客,里面针对每条配置文件都做了详细解析。

五、Tomcat配置

229服务器,添加默认页

在Tomcat的webapps目录下新建文件夹drp,并且创建index.jsp页面

        <%@ page language="java" contentType="text/html; charset=GB18030"pageEncoding="GB18030"%><HTML><head><meta http-equiv="Content-Type" content="text/html; charset=GB18030"><title>Nginx+Keepalived高可用,负载均衡,动静分离测试</title></head><body><h1>您正在访问服务器:192.168.22.229</h1><img src="/drp/img/girl.jpg"  alt="女孩" /></body></html>

230服务器同上


六、启动服务并测试

分别启动各个服务器上的Nginx、Keepalived、Tomcat,并测试能否正常访问。

①启动测试Tomcat

这里写图片描述

这里写图片描述

可以看到229和230服务器上的Tomcat已经可以正常访问,图片没有加载出来,是因为图片没有在Tomcat服务器上存储,而放在了Nginx上。

②启动测试Nginx

这里写图片描述

可以看到227和228上的Nginx启动成功,并且实现了负载均衡和动静分离的效果,图片被成功的加载了出来。

③ 保证所有服务均可正常访问后,启动Keepalived测试。

启动227,228服务器上的Keepalived,在浏览器中输入地址:http://192.168.22.231:8088/drp/index.jsp

这里写图片描述

192.168.22.231是咱们设置的虚拟ip,在访问网站的时候不在通过Nginx的ip了,而要通过这个vip进行访问。

Keepalived启动后咱们可以通过查看/var/log 下的messages文件(日志文件),查看主从状态。
查看227服务器/var/log/messages:

这里写图片描述

可以看到227为Master服务器,那么咱们现在通过192.168.22.231访问的就是227上的Nginx。


Nginx高可用测试

现在咱们通过两个方面来测试高可用:

① 服务器层的双机热备,模拟方式为关闭服务器,或者关闭Keepalived。

a. 关闭227Keepalived进程

现在提供服务的是227服务器,使用命令service keepalived stop将227上的Keepalived进程关闭掉之后。

查看227服务器messas日志:

这里写图片描述

将192.168.22.231这个虚拟ip移除,关闭Keepalived。

查看228服务器messages日志:

这里写图片描述

228原来为从服务器,当227服务器宕机后,228服务器由从服务器升级为主服务器,并且绑定上192.168.22.231这个虚拟IP,以继续提供服务,网站能够继续访问。

b. 启动227Keepalived

查看227服务器messas日志:

这里写图片描述

Keepalived成功启动后,227服务器继续接管192.168.22.231,成为MASTER服务器,继续提供服务。

查看228服务器messages日志:

这里写图片描述

相应的228服务器,转变为BACKUP服务器,并且移除VIP。


② 应用层的双机热备,模拟方式为Kill掉Nginx进程

a. 关闭227Nginx

查看227服务器messages日志:

这里写图片描述

VRRP_Script(check_nginx) failed ,意思是健康监测脚本执行失败,表明Nginx服务坏掉,或者没有启动。然后Keepalived会使227服务器转变为BACKUP状态,移除VIP。

查看228服务器messages日志:

这里写图片描述

当然不出所料,228服务器已经变为MASTER状态,从而继续提供服务。

b. 重新启动227Nginx

查看227服务器messages日志:

这里写图片描述

VRRP_Script(check_nginx) succeeded ,意思是健康监测脚本执行成功,Nginx正常运行。然后227服务器就会转变为MASTER状态,并提供服务。

查看228服务器messages日志:

这里写图片描述

228服务器已经变为BUCKUP状态。


小结


至此,高可用的一系列测试就已经完成了。在整个测试过程中,无论是关闭某台服务器的Nginx,Keepalived还是整个服务器宕机,网站一直没有中断提供服务,这已经达到了基本的高可用;但是还有个缺陷就是如果Nginx主服务器不出问题的话,那么备用服务器将长期处于备份状态,这样的巨大资源浪费是不能容忍的。当然这也有相应的方案来解决:Nginx双主集群+DNS轮询,敬请期待。。。

这就是一个架构不断演变,进化的过程。

这篇关于【Linux运维-集群技术进阶】Nginx+Keepalived+Tomcat搭建高可用/负载均衡/动静分离的Web服务器集群的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/958128

相关文章

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

linux系统上安装JDK8全过程

《linux系统上安装JDK8全过程》文章介绍安装JDK的必要性及Linux下JDK8的安装步骤,包括卸载旧版本、下载解压、配置环境变量等,强调开发需JDK,运行可选JRE,现JDK已集成JRE... 目录为什么要安装jdk?1.查看linux系统是否有自带的jdk:2.下载jdk压缩包2.解压3.配置环境

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

Nginx中配置使用非默认80端口进行服务的完整指南

《Nginx中配置使用非默认80端口进行服务的完整指南》在实际生产环境中,我们经常需要将Nginx配置在其他端口上运行,本文将详细介绍如何在Nginx中配置使用非默认端口进行服务,希望对大家有所帮助... 目录一、为什么需要使用非默认端口二、配置Nginx使用非默认端口的基本方法2.1 修改listen指令

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、