基於LVS、Nginx和Redis的多服務高可用負載均衡集群方案設計與實踐


1、需求分析

1.1、項目背景

伴隨着信息技術的飛速發展,互聯網技術發展突飛猛進,越來越多的業務依靠互聯網來實現,當今計算機技術已進入以網絡為中心的網絡時代。數年來,隨着國民經濟的持續發展,人們的生活水平得以提高,網絡用戶的數量也隨之一路攀升,加之國家的政策倡導,在許多偏遠地區也能夠實現網絡覆蓋,我國網民的數量已躋身世界前列。大量的服務和應用(如:新聞、電子商務、短視頻等)都圍繞着Web運行,加之我國網絡服務性能的不斷提升,網絡產品的不斷迭代與衍生,這就促使着網絡用戶劇烈增長並伴隨着海量的網絡數據流量。這給網絡帶寬和服務端帶來了巨大的挑戰,近幾年網絡服務也在不斷的革新於發展,以華為為代表的第五代網絡通信技術(5G)領跑世界,龐大的用戶群體和先進的網絡服務,使得我國網絡技術的發展和前景良好。隨着網絡通信技術的不斷升級,客戶端的運行壓力會不斷的減小,去核心化的網絡服務理念逐漸深入人心,更多的操作實現均來自於網絡服務端,可以預見的是越來越多的技術瓶頸會出現在服務器端。如何建立一個高可用、高性價比、可擴展並且易管理的網絡服務平台來滿足不斷增長的網絡服務應用依然是網絡發展的關鍵問題之一。在大數據時代實現一個高可用的網絡設計方案已是服務端所不懈追求的目標。

1.2、項目分析

當今世界網絡技術不斷發展,用戶數量不斷攀升,每天都伴隨着海量的數據的處理與應用,這些數據的產生與處理都離不開高性能的網絡集群服務的支撐。傳統的頁面與數據庫的交互設計模式已經不足以支撐如此龐大的用戶數量,傳統的數據處理技術已經無法應對海量數據的運算。這種情況下,基於Linux負載均衡的虛擬服務器集群技術應運而生,基於Linux的虛擬化服務器集群(建成LVS),其實現目的是為了解決當下網絡服務的瓶頸難題,創建一個具有高可用、可伸縮、易管理的基於Linux的負載均衡服務集群,來滿足日益增長的網絡服務需求。傳統數據中心的運維管理是相當繁瑣的,如:機器宕機、服務故障等,一系列問題都是通過運維人員手動實現,這一系列的操作考驗的是網管員技術和體力的工作;但倘若使用了負載均衡方案使用KeepAlived后,在服務設計之初做好一系列的保障工作,對服務運行種所出現任何問題都做好事先的預案,當集群運行中出現故障后,會自動的調試平啟用事先的預案,保障服務的穩定運行。這樣的的高可用與負載均衡的解決方案既是網絡數據中心運維的目標,也是網絡發展的關鍵問題。

2、概要設計

2.1、LVS技術分析

LVS是Linux Virtual
Server的簡稱,即Linux虛擬服務器,是Linux標准內核的一部分,LVS的技術目標是:通過LVS提供的負載均衡技術和Linux操作系統的一個高性能、高可用的服務器集群,它具有良好的可靠性、可擴展性和可操作性,以廉價的成本實現最優的服務性能。LVS采用IP負載均衡技術和技術內容請求分析技術。調度器將請求負載轉移到不同的服務器上執行,將一組服務器構成一個高性能、高可用的虛擬服務器。整個服務器集群的結構對客戶是透明的,而且無需修改客戶端和服務端的程序。

LVS體系結構圖:

2.2、LVS三層結構

(1)負載調度器:是整個集群對外面的前端機,負載將客戶的請求發送到一組服務器上執行。

(2)服務器池:是一組真正執行客戶請求的服務器,可以是Web、Mail、Ftp和DNS服務器等。

(3)共享存儲:它是服務器池提供一個共享的存儲區,這樣很容易使得服務器池擁有相同的內容,提供相同的服務,例如:數據庫、分布式文件系統、網絡存儲等。

2.3、LVS性能優勢分析

(1)高並發連接:LVS是基於內核網絡層工作的,有着超強的承載能力和並發處理能力。單台LVS負載均衡器,可用支持上萬並發連接。

(2)穩定性強:工作在網絡層上僅作為分發使用,穩定性好,對內存和cpu資源消耗極低。

(3)成本低廉:硬件負載均衡器價格昂貴,而LVS只需要一台服務器就能夠免費的部署使用,性價比高。

(4)配置簡單:LVS配置僅需幾行命令即可完成配置,也可實現腳本管理。

(5)支持多種算法調度:支持8種負載均衡算法,可根據業務場景靈活調配使用。

(6)支持多種工作模式:可根據業務場景,解決不同的問題,使用不同的工作模式。

(7)使用范圍廣:幾乎可以對所有的應用做負載均衡,包括http、數據庫、DNS等。

2.4、LVS工作模式

當客戶端的請求到達負載均衡器的內核空間時,首先到達PREROUTING鏈,當內核發現請求數據包的目的地址是本機時,將數據包發送到INPUT鏈;LVS由用戶空間ipvsadm和內核空間的IPVS組成,ipvsadm用來定義規則,IPVS利用ipvsadm定義的規則工作,IPVS工作在INPUT鏈上,當數據包到達INPUT時,首先會被IPVS調查,如果數據包里面的目的地址及端口沒有在規則里面,那么這條數據就被放行到用戶空間,如果數據包里面的目的地址及端口在規則里面,那么這條數據報文將被修正為事先定義好的后端服務器,並發往POSTOUTING鏈,最后由POSTROUTING鏈發往后端服務器。

2.5、負載均衡模式

LVS-NAT模式:是通過網絡地址轉換的方法來實現調度的。首先調度器(Director)接收到客戶的請求數據包時(請求的目的IP為VIP),根據調度算法決定將請求發送給哪個后端的真實服務器(RS)。然后調度就把客戶端發送的請求數據包的目標IP地址及端口改成后端真實服務器的IP地址(RIP),這樣真實服務器(RS)就能夠接收到客戶的請求數據包了。真實服務器響應完請求后,查看默認路由(NAT模式下我們需要把RS的默認路由設置為DS服務器。)把響應后的數據包發送給DS,DS再接收到響應包后,把包的源地址改成虛擬地址(VIP)然后發送回給客戶端。

LVS-DR模式:用直接路由技術實現虛擬服務器。當參與集群的計算機和作為控制管理的計算機在同一個網段時可以用此方法,控制管理的計算機接收到請求包時直接送到參與集群的節點。直接路由模式比較特別,很難說和什么方面相似,前種模式基本上都是工作在網絡層上,而直接路由模式則應該是工作在數據鏈路層上。

LVS-TUN模式:在TUN模式下,利用IP隧道技術將請求報文封裝轉發給后端服務器,響應報文能從后端服務器直接返回給客戶。

FULL-NAT模式:FULL-NAT模式可以實際上是根據LVS-NAT模式的一種擴展。在NAT模式下DS需要先對請求進行目的地址轉換(DNAT),然后對響應包進行源地址轉換(SNAT),先后進行兩次NAT,而
FULL-NAT則分別對請求進行和響應進行DNAT和SNAT,進行4次NAT,當然這樣多次數的NAT會對性能大大削減,但是由於對請求報文的目的地址和源地址都進行了轉換,后端的RS可以不在同一個VLAN下。

2.6、調度算法

在內核中的連接調度算法上,IPVS已實現了以下八種調度算法:

輪叫調度rr、加權輪叫調度wrr、最小連接調度lc、加權最小連接調度wlc、基於局部性的最少鏈接LBLC、帶復制的基於局部性最少鏈接LBLCR、目標地址散列調度DH、源地址散列調度SH。

2.7、KeepAlived分析

keepalived類似於layer3, 4 & 5交換機制的軟件,
Keepalived的作用是檢測服務器的狀態,如果有一台web服務器宕機,或工作出現故障,Keepalived將檢測到,並將有故障的服務器從系統中剔除,同時使用其他服務器代替該服務器的工作,當服務器工作正常后Keepalived自動將服務器加入到服務器群中,這些工作全部自動完成,不需要人工干涉,需要人工做的只是修復故障的服務器。

2.8、多服務設計模式

本次高可用與負載均衡設計,采用了多場景下的網站頁面設計架構,支持HTML、PHP、JSP等多種頁面訪問模式,充分考慮了當先流行的網站設計體系,應用了Apache+Tomcat的兩種訪問方式,對其進行了nginx反向代理和動靜分離,進行頁面重定向和端口映射,有效的避免了訪問限制,充分利用了高可用與負載均衡的資源訪問模式,避免單點負載限制,使用了redis高效存儲控制,應用了session共享的設計模式,使得頁面的高效訪問。使用了mysql數據庫的主從復制與讀寫分離的存儲模式,優化了存儲效率,增加了高可用與負載均衡的高效性與穩定性,使用了廉價的機器設備,實現了高可用與負載均衡的訪問控制機制。

2.9、總體架構設計圖

2.10、部署准備

出於性能考慮,本次課程設計准備使用7台虛擬機實現上述設計。

環境介紹:

主機名 IP 系統 部署應用
Lvs1 192.168.60.111 Centos7 Lvs+keepalived
Lvs2 192.168.60.112 Centos7 Lvs+keepalived
192.168.60.110 VIP
Nginx1 192.168.60.101 Centos7 Nginx(靜態頁面)
Nginx2 192.168.60.102 Centos7 Nginx(靜態頁面)
Tomcat1 192.168.60.103 Centos7 Tomcat、Apache、Mysql(動態頁面)
Tomcat2 192.168.60.104 Centos7 Tomcat、Apache、Mysql(動態頁面)
Redis 192.168.60.105 Centos7 Redis(session會話共享)

版本設置:

軟件包 版本
Keepalived 1.3.5
Nginx 1.16.1
Tomcat 7.0.104
Jdk 1.8
Apache 2.4.6
Redis 5.0.5
Mysql 5.7
Ipvs 1.27

3、系統實現

3.1、環境搭建

准備7台虛擬機,使用最小化安裝,分配1G內存+20G內存,預設好主機名與IP地址。

由於是最小化安裝,一些常用插件工具沒有安裝上,需要手動下載安裝。

# yum install net-tools

# yum install vim -y

3.2、lvs+keepalived部署

3.2.1、keepalived部署准備

關閉防火牆和selinux

# systemctl stop firewalld

# systemctl disable firewalld

# setenforce 0

3.2.2、安裝keepalived

# yum install keepalived -y

修改keepalived配置文件,為例防止文件改壞,首先復制一份原版。

# cp

/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak

# vim keepalived.conf

3.3、nginx部署

3.3.1、部署准備

關閉防火牆和selinux

# systemctl stop firewalld

# systemctl disable firewalld

# setenforce 0

為了防止nginx負載均衡調度器無法訪問tomcat服務,這里設置關閉SElinux

# vim /etc/selinux/config

SELINUX=disabled

為了方便安裝,需要添加yum源

[aliyun]

name=aliyun epel

baseurl=http://mirrors.aliyun.com/epel/7Server/x86_64/

gpgcheck=0

3.3.2、安裝nginx服務

# yum install -y nginx

3.3.3、配置腳本

腳本用於節點服務器綁定VIP,抑制節點相應VIP的ARP請求。以此當關於VIP的ARP廣播時,禁止節點服務器應答,這樣就很好的保障了網絡環境的通暢,因此,在打開nginx所在的服務器的路由功能、關閉ARP查詢功能,並且設置回環ip,nginx1和nginx2配置腳本內容為:

# vim /etc/rc.d/init.d/realserver.sh

# chmod u+x /etc/rc.d/init.d/realserver.sh

#!/bin/bash

VIP=192.168.60.110

/etc/rc.d/init.d/functions

case "$1" in

start)

ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP

/sbin/route add -host $VIP dev lo:0

echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore

echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce

echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore

echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

sysctl -p >/dev/null 2>&1

echo "RealServer Start OK"

;;

stop)

ifconfig lo:0 down

route del $VIP >/dev/null 2>&1

echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore

echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce

echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore

echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce

echo "RealServer Stoped"

;;

*)

echo "Usage: $0 {start|stop}"

exit 1

esac

exit 0

啟動服務

# /etc/rc.d/init.d/realserver.sh start

查看VIP信息:

3.3.4、nginx啟動測試

首先進入nginx的配置文件查看網站根目錄位置信息:

在根目錄添加自定義網頁用於測試:

# echo "This is nginx1 web site."

> /usr/share/nginx/html/default.html

# echo "This is nginx2 web site."

> /usr/share/nginx/html/default.html

然后啟動nginx服務:

# systemctl start nginx

訪問站點網頁查看nginx運行情況:

http://192.168.60.101/default.html

http://192.168.60.102/default.html

3.5、動靜分離實現

修改兩台nginx配置,實現負載均衡與動靜分離。

# vim /etc/nginx/nginx.conf

location ~ \.(jsp|do)$ {

proxy_pass http://tomcat;

}

upstream tomcat {

server 192.168.60.103:8080 max_fails=3 fail_timeout=20s weight=2;

server 192.168.60.104:8080 max_fails=3 fail_timeout=20s weight=2;

}

3.6、tomcat部署

3.6.1、部署准備

為了保障頁面的正常訪問,首先在兩台tomcat虛擬機關閉防火牆和selinux

# systemctl stop firewalld

# systemctl disable firewalld

# setenforce 0

jdk安裝部署

自行到java官網下載Jdk8版本到虛擬機,解壓安裝。

# tar -zxvf jdk-8u144-linux-x64.tar.gz -C /usr/local/

# mv jdk1.8.0_144/ jdk1.8

配置環境變量

# vim /etc/profile

export JAVA_HOME=/usr/local/jdk1.8

export PATH=$PATH:$JAVA_HOME/bin

export CALSSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH

# source /etc/profile

同樣的將tomcat2也添加上jdk,使用復制的方式添加。

# scp -r /usr/local/jdk1.8 root@192.168.60.104:/usr/local/

驗證配置情況。

3.6.2、配置tomcat

下載tomcat安裝包:

# wget

https://mirror.bit.edu.cn/apache/tomcat/tomcat-7/v7.0.104/bin/apache-tomcat-7.0.104.tar.gz

# tar -zxvf apache-tomcat-7.0.104.tar.gz -C /usr/local

重命名文件夾

# mv /usr/local/apache-tomcat-7.0.104/ /usr/local/tomcat

將tomcat文件拷貝到tomcat2中。

# scp -r /usr/local/tomcat root@192.168.60.104:/usr/local/

3.7、redis部署

3.7.1、redis部署准備

關閉防火牆和selinux

# systemctl stop firewalld

# systemctl disable firewalld

# setenforce 0

下載redis源碼安裝包,解壓到/usr/loca/目錄下。

# wget http://download.redis.io/releases/redis-5.0.5.tar.gz

# tar -zxvf redis-5.0.5.tar.gz -C /usr/local

由於redis是源碼安裝,所以要下載編譯工具。

# yum install -y gcc gcc-c++ make

移動到redis根目錄下編譯安裝。

# make && make install

初始化redis

# cd utils/

# ./install_server.sh

初始化成功后,redis文件會連接到/etc目錄下,其中:

(1)配置文件為/etc/redis/6379.conf

(2)日志文件問/var/log/redis_6379.log

(3)數據文件dump.rdb存放到/var/lib/redis/6379目錄下

(4)啟動腳本為/etc/init.d/redis_6379

接下來需要設置redis的啟動腳本到系統變量中。

[Unit]

Description=Redison port 6379

[Service]

Type=forking

ExecStart=/etc/init.d/redis_6379 start

ExecStop=/etc/init.d/redis_6379 stop

[Install]

WantedBy=multi-user.target

3.7.2、啟動redis

修改配置文件

# vim /etc/redis/6379.conf

bind 127.0.0.1 192.168.60.105

requirepass pwd@123

啟動redis服務

# systemctl restart redis_6379.service

3.8、配置會話共享

下載tomcat-redis-session-manager相應的jar包,將其拷貝到兩台tomcat根目錄的lib目錄下。

修改tomcat的context.xml文件

# vim /usr/local/tomcat/conf/context.xml

<Valve
className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve"/>

<Manager
className="com.orangefunction.tomcat.redissessions.RedisSessionManager"

host="192.168.60.105"

password="password@123"

port="6379"

database="0"

maxInactiveInterval="60"

/>

3.9、配置mysql主從復制

設tomcat1為mysql-master節點,tomcat2為mysql-slave節點進行配置。在兩台tomcat上配置mysql讀寫分離,使用yum的形式手動安裝mysql數據庫,啟動數據庫,修改初始化密碼:

# mysqladmin -u root password 123456

3.9.1、配置server_id

# vim /etc/my.cnf

重啟兩台tomcat的Mysql服務,查看service_id的狀態信息。

# systemctl restart mysqld

# show variables like 'server_id';

3.9.2、部署主從復制

在mysql-master上建立slave復制賬號

mysql> CREATE USER 'slave'@'%' IDENTIFIED BY '123';

mysql> GRANT REPLICATION SLAVE,RELOAD,SUPER ON *.* TO slave@'%' IDENTIFIED
BY '123';

mysql>show grants for slave@'%';

mysql>flush privileges; #刷新權限

在master創建並備份temp數據庫,拷貝到slave

mysql>create database temp;

mysql>use temp;

mysql> create table users(user_name char(16) not null,user_passwd char(48)
default "",primary key(user_name));

mysql>insert into users(user_name,user_passwd) values ("zhangsan","123");

# mysqldump -u root -p temp > /root/tempdata.sql

在mysql-slave恢復數據庫temp。

mysql>create database temp;

在mysql-master上查看master配置信息

在mysql-slave配置復制參數 ,啟動復制,查看復制狀態。

mysql> change master to master_host='192.168.60.103', master_user='slave',
master_password='123', master_log_file='mysql-bin.000002', master_log_pos=120,
master_connect_retry=30;

mysql> start slave;

mysql> show slave status \G

3.10、配置php的session共享

在mysql-master的temp數據庫上創建表再插入數據。

mysql> create table user(uid int(4),username char(16) not null,password
char(48) default "",primary key(username));

mysql>insert into user(uid,username,password) values (1,"tom",MD5("123"));

在mysql-slave數據庫中查看插入信息。

可以看到mysql的讀寫分離測試成功。

自定義一個php網站頁面,移動到apache網站的根目錄。

4、系統測試

4.1、負載均衡測試

啟動服務

# systemctl start keepalived

# systemctl enable keepalived

查看VIP情況判定是否配置成功,lvs1(master)有而lvs2(backup)節點沒有。

# ip addr 使用ifconfig是不顯示的

此時,lvs1處於開啟狀態,lvs2處於待機狀態,表示配置成功。

4.2、壓力測試VIP節點

首先查看lvs機器是否安裝啟用了ipvsadm命令,正常情況是伴隨keepalived的安裝的啟動運行的一個工具。ipvsadm是一個管理ipvs的工具。

# lsmod| grep ip_vs 查看是ipvs模塊是否加載成功

若沒安裝成功則使用yum安裝上:

# yum install ipvsadm -y

在另外的一台虛擬機執行壓力測試命令

# ab -c 1000 -n 1000 http://192.168.60.110/default.html

在lvs1上查看節點數據流量,lvs2模式是backup模式,是沒有數據經過的,采取的是rr輪詢的方式。

4.3、tomcat測試

4.3.1、設置tomcat虛擬主機

# vim /usr/local/tomcat/conf/server.xml

修改默認虛擬主機,並將網站路徑指向/var/www/tomcat1/

# mkdir p /var/www/tomcat1

tomcat2也是類似的操作。

# mkdir p /var/www/tomcat2

4.3.2、在兩台網站指定根目錄下添加自定義測試文件

<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<html>

<head>

<title>tomcat1</title>

</head>

<body>

<h1><font color="red">Session serviced by tomcat</font></h1>

<table aligh="center" border="1">

<tr>

<td>Session ID</td>

<td><%=session.getId() %></td>

<% session.setAttribute("abc","abc");%>

</tr>

<tr>

<td>Created on</td>

<td><%= session.getCreationTime() %></td>

</tr>

</table>

</body>

<html>

在兩台tomcat虛擬機啟動tomcat測試,驗證負載均衡。

# /usr/local/tomcat/bin/startup.sh

使用主機瀏覽器訪問VIP的index.jsp頁面,不停的刷新可用看到頁面的轉換。

由此實現了lvs+nginx+tomcat的高可用負載均衡測試。

4.4、測試session共享

配置完tomcat和redis配置后,重新啟動redis和tomcat,在瀏覽器訪問VIP的指定網頁查看session

回到redis客戶端頁面查看緩存內存中的session數據。

可以看到顯示的session一致,表示session共享配置成功。

4.5、測試php的session共享

在nginx的配置文件添加修改如下配置,使得.html和.php文件重定向到兩台tomcat服務器地址。

upstream app {

server 192.168.60.103;

server 192.168.60.104;

}

location ~ \.(php|html)$ {

proxy_pass http://app;

}

在主機瀏覽器訪問http://192.168.60.110/phplogin/index.php頁面。

采用的是輪詢的方式(rr)訪問兩台tomcat虛擬機,可以看到網頁的服務器IP地址在變化,而session並未改變。

再測試驗證mysql主從復制讀寫分離的實現。

從mysql-master(192.168.60.103)中向數據庫temp的user表寫入數據:

# insert into user(uid,username,password) values (1,"jake",MD5("123456"));

修改php登錄頁面的數據庫訪問信息,使其訪問mysql-slave的temp數據庫。

再次使用瀏覽器訪問php的登錄頁面,使用jake和123456用戶登錄。

由此可知mysql主從復制讀寫分離配置成功。

4.6、高可用測試

對lvs1和nginx1進行宕機測試,首先在各個服務正常運行的情況下,手動停止keepalived1和nginx1查看服務的訪問情況。

停止keepalived1和nginx1

查看lvs和nginx服務器的IP

站點依然可以正常訪問

對宕機后的高可用集群進行壓力測試。

# ab -c 1000 -n 1000 http://192.168.60.110/index.jsp

使用ipvs工具在Lvs2上查看連接情況。

可以看到只有一台lvs服務器正常運轉,頁面仍然可用正常運轉,下面啟用着兩個被宕機的服務器。

可用看到服務正常啟動,表明lvs+nginx高可用與負載均衡配置、php和tomcat的session共享機制以及mysql主從復制讀寫分離的配置成功。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM