1. 程式人生 > 資料庫 >基於LVS、Nginx和Redis的多服務高可用負載均衡叢集方案設計與實踐

基於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執行情況:

3.5、動靜分離實現

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

# vim /etc/nginx/nginx.conf

location ~ \.(jsp|do)$ {

proxy_pass ;

}

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 [email protected]:/usr/local/

驗證配置情況。

3.6.2、配置tomcat

下載tomcat安裝包:

# wget

# 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 [email protected]:/usr/local/

3.7、redis部署

3.7.1、redis部署準備

關閉防火牆和selinux

# systemctl stop firewalld

# systemctl disable firewalld

# setenforce 0

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

# wget

# 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

在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://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

使用ipvs工具在Lvs2上檢視連線情況。

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

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

5、總結

通過對高可用與負載均衡課程的學習,我學到了很多關於伺服器叢集搭建與運維方面的知識和技能,對伺服器運維領域有了更深層次的學習和理解。通過完成這個專案,使得我對Lvs、Nginx高可用架構有了整體的瞭解,Lvs、Nginx高可用與負載均衡叢集是當前伺服器部署與應用中應用最為廣泛的伺服器叢集建設方式。對海量的資料進行處理的能力遠超傳統的伺服器搭建模式,能夠獨立的處理高併發與高負載的大規模網站服務建設,有效的排除了單點故障所帶來的網路癱瘓危機,實現了Lvs、Keepalived和Nginx的高可用訪問控制,以及Apache和Tomcat多頁面場景下的網站型別的動靜分離與高效訪問,同時還包括Mysql主從複製與讀寫分離的高效儲存設計與實現,使得能夠對伺服器長期、穩定、高效的執行提供可靠保障。

非常感謝老師能夠給我這次機會,然我能夠獨立的完成一個多場景的高可用與負載均衡叢集的部署與應用的過程,以此來結合所學的知識對我之前學到的知識有了更深層次的立即與感悟,對今後的學習與工作有著極其重要的意義。