前言:
為了使web能適應(yīng)大規(guī)模的訪問,需要實(shí)現(xiàn)應(yīng)用的集群部署。集群最有效的方案就是負(fù)載均衡,而實(shí)現(xiàn)負(fù)載均衡用戶每一個(gè)請(qǐng)求都有可能被分配到不固定的服務(wù)器上,這樣我們首先要解決session的統(tǒng)一來保證無論用戶的請(qǐng)求被轉(zhuǎn)發(fā)到哪個(gè)服務(wù)器上都能保證用戶的正常用,也就是需要實(shí)現(xiàn)session的共享機(jī)制。
目前創(chuàng)新互聯(lián)公司已為超過千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機(jī)、綿陽服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計(jì)、濱海網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
在集群系統(tǒng)下實(shí)現(xiàn)session統(tǒng)一的有如下幾種方案:
1、請(qǐng)求精確定位:sessionsticky,例如基于訪問ip的hash策略,即當(dāng)前用戶的請(qǐng)求都集中定位到一臺(tái)服務(wù)器中,這樣單臺(tái)服務(wù)器保存了用戶的session登錄信息,如果宕機(jī),則等同于單點(diǎn)部署,會(huì)丟失,會(huì)話不復(fù)制。
2、session復(fù)制共享:sessionreplication,如tomcat自帶session共享,主要是指集群環(huán)境下,多臺(tái)應(yīng)用服務(wù)器之間同步session,使session保持一致,對(duì)外透明。 如果其中一臺(tái)服務(wù)器發(fā)生故障,根據(jù)負(fù)載均衡的原理,調(diào)度器會(huì)遍歷尋找可用節(jié)點(diǎn),分發(fā)請(qǐng)求,由于sessio已同步,故能保證用戶的session信息不會(huì)丟失,會(huì)話復(fù)制,。
此方案的不足之處:
必須在同一種中間件之間完成(如:tomcat-tomcat之間).
session復(fù)制帶來的性能損失會(huì)快速增加.特別是當(dāng)session中保存了較大的對(duì)象,而且對(duì)象變化較快時(shí), 性能下降更加顯著,會(huì)消耗系統(tǒng)性能。這種特性使得web應(yīng)用的水平擴(kuò)展受到了限制。Session內(nèi)容通過廣播同步給成員,會(huì)造成網(wǎng)絡(luò)流量瓶頸,即便是內(nèi)網(wǎng)瓶頸。在大并發(fā)下表現(xiàn)并不好。
3、基于cache DB緩存的session共享:即使用cacheDB存取session信息,應(yīng)用服務(wù)器接受新請(qǐng)求將session信息保存在cache DB中,當(dāng)應(yīng)用服務(wù)器發(fā)生故障時(shí),調(diào)度器會(huì)遍歷尋找可用節(jié)點(diǎn),分發(fā)請(qǐng)求,當(dāng)應(yīng)用服務(wù)器發(fā)現(xiàn)session不在本機(jī)內(nèi)存時(shí),則去cache DB中查找,如果找到則復(fù)制到本機(jī),這樣實(shí)現(xiàn)session共享和高可用。
這里將使用第三種方案,實(shí)現(xiàn)session會(huì)話共享,將采用redis來做cache DB。
博文大綱:
一、環(huán)境準(zhǔn)備
二、配置Nginx反向代理服務(wù)器
三、配置Tomcat服務(wù)器
四、配置Redis服務(wù)器
五、配置Tomcat連接Redis
六、安裝部署MySQL數(shù)據(jù)庫
七、配置Tomcat連接MySQL數(shù)據(jù)庫
在進(jìn)行下面配置前,先下載我提供的源碼包,并自行上傳至對(duì)應(yīng)的服務(wù)器。
這里配置Nginx反向代理,只是實(shí)現(xiàn)它一個(gè)簡(jiǎn)單的代理功能,若想優(yōu)化這個(gè)反向代理服務(wù)器,那么最好參考博文:Nginx安裝、實(shí)現(xiàn)反向代理及深度優(yōu)化進(jìn)行配置。
以下操作均在192.168.20.2的Nginx服務(wù)器上進(jìn)行
[root@nginx ~]# yum -y erase httpd #卸載自帶的web服務(wù)
[root@nginx ~]# yum -y install openssl-devel pcre-devel #安裝所需依賴
[root@nginx ~]# tar zxf nginx-1.14.0.tar.gz -C /usr/src #解包
[root@nginx ~]# cd /usr/src/nginx-1.14.0/ #切換至解壓后的目錄
[root@nginx conf]# ./configure --user=www --group=www --prefix=/usr/local/nginx && make && make install
#編譯安裝
[root@nginx nginx-1.14.0]# cd /usr/local/nginx/conf/ #切換至Nginx配置文件主目錄
[root@nginx conf]# vim nginx.conf #編輯Nginx配置文件,寫入以下內(nèi)容
http { #在http字段添加以下內(nèi)容
upstream backend {
server 192.168.20.3:8080 weight=1 max_fails=2 fail_timeout=10s;
server 192.168.20.4:8080 weight=1 max_fails=2 fail_timeout=10s;
}
server { #定位到server字段
location / { #在location字段下面添加以下內(nèi)容,并注釋掉下面開頭兩行
#root html;
#index index.html index.htm;
proxy_pass http://backend; #主要寫入這一行,以下的是優(yōu)化,可選寫入
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}
}
}
#修改完成后,保存退出即可
[root@nginx conf]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ #對(duì)Nginx命令做軟連接
[root@nginx conf]# useradd -M -s /sbin/nologin www #創(chuàng)建運(yùn)行用戶
[root@nginx conf]# nginx -t #檢查配置文件
[root@nginx conf]# nginx #啟動(dòng)Nginx服務(wù)
至此,這臺(tái)Nginx就可以提供基本的反向代理功能了,接下來配置Tomcat服務(wù)器。
以下操作需要在兩臺(tái)Tomcat服務(wù)器上分別配置
主機(jī)Tomcat1操作如下:
[root@tomcat1 ~]# ls | grep tomcat #上傳下面的源碼包
apache-tomcat-8.5.35.tar.gz
[root@tomcat1 ~]# tar zxf apache-tomcat-8.5.35.tar.gz -C /usr/src
[root@tomcat1 ~]# mv /usr/src/apache-tomcat-8.5.35 /usr/local/tomcat
[root@tomcat1 ~]# cd /usr/local/tomcat/conf/
[root@tomcat1 conf]# vim server.xml
#在下面添加以下配置
#以上是配置虛擬主機(jī),指定網(wǎng)頁根目錄是/web/webapp1。添加后保存退出
[root@tomcat1 conf]# mkdir -p /web/webapp1 #創(chuàng)建網(wǎng)頁根目錄
[root@tomcat1 conf]# vim /web/webapp1/index.jsp #編寫首頁文件如下
<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
tomcat-1 #稍后在tomcat2主機(jī)上,需修改title字段中的數(shù)字改為2,以便查看負(fù)載均衡效果
Session serviced by tomcat
Session ID
<%=session.getId() %>
<% session.setAttribute("abc","abc");%>
Created on
<%= session.getCreationTime() %>
[root@tomcat1 conf]# /usr/local/tomcat/bin/startup.sh #啟動(dòng)tomcat服務(wù)
將以上Tomcat1主機(jī)的所有操作在Tomcat2主機(jī)上同樣配置一次
當(dāng)Tomcat2主機(jī)也配置完成后,即可使用客戶端訪問Nginx代理服務(wù)器(訪問:192.168.20.2),多次刷新頁面,會(huì)依次看到以下頁面(注意,其Session ID并不一樣):
接下來配置Redis緩存服務(wù)器,Redis緩存服務(wù)器存在的意義就是將客戶端的session會(huì)話信息保存下來,用于Tomcat服務(wù)器共享這個(gè)session會(huì)話信息,從而使其不要每次客戶端請(qǐng)求都更新session會(huì)話。
[root@redis ~]# ls | grep redis #上傳下面的源碼包
redis-4.0.14.tar.gz
[root@redis ~]# tar zxf redis-4.0.14.tar.gz -C /usr/src #解包
[root@redis ~]# cd /usr/src #切換至解壓后的路徑
[root@redis src]# mv redis-4.0.14/ /usr/local/redis #直接移動(dòng)到指定路徑并重命名
[root@redis src]# cd /usr/local/redis/ #切換至redis目錄
[root@redis redis]# make && make install #無需配置,直接編譯安裝即可
[root@redis redis]# cd utils/ #進(jìn)入該子目錄
[root@redis utils]# ./install_server.sh #對(duì)Redis進(jìn)行初始化
#初始化的所有選項(xiàng)保持默認(rèn),一路回車確認(rèn)即可
#是在確認(rèn)監(jiān)聽端口、配置文件、日志文件、pid存放路徑等信息
.............#省略部分內(nèi)容
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
#出現(xiàn)上述內(nèi)容,則表示初始化成功
[root@redis utils]# vim /etc/redis/6379.conf #編輯Redis配置文件
bind 0.0.0.0 #找到?jīng)]有被注釋的這一行,修改為0.0.0.0
# requirepass foobared #定位到改行,修改如下:
requirepass 123.com #Redis的密碼為123.com
#修改完成后,保存退出即可。
[root@redis utils]# /etc/init.d/redis_6379 restart #重啟Redis服務(wù)
[root@redis utils]# redis-cli -h 192.168.20.5 #登錄數(shù)據(jù)庫
192.168.20.5:6379> set a b #插入數(shù)據(jù)測(cè)試
(error) NOAUTH Authentication required. #插入失敗,因?yàn)闆]有進(jìn)行密碼驗(yàn)證
192.168.20.5:6379> AUTH 123.com #使用AUTH進(jìn)行驗(yàn)證,密碼就是配置文件中定義的“123.com”
OK
192.168.20.5:6379> set a b #再次插入數(shù)據(jù)
OK #成功
至此,Redis服務(wù)器就配置成功了。接下來配置Tomcat,使其可以將Session信息寫入到Redis。
[root@tomcat1 ~]# cd /usr/local/tomcat/lib/
[root@tomcat1 lib]# rz #將我網(wǎng)盤中的以下四個(gè)包文件上傳至當(dāng)前目錄
commons-pool2-2.4.2.jar mysql-connector-java-5.1.22.jar
jedis-2.9.0.jar tomcat85-session-redis-1.0.jar
[root@tomcat1 lib]# vim ../conf/context.xml #編輯這個(gè)文件
#定位到這行,去掉其注釋符號(hào),并在該行下寫入以下內(nèi)容
#以上的內(nèi)容在末尾這行上面添加
#編輯完成后,保存退出即可,然后重啟Tomcat
[root@tomcat1 lib]# /usr/local/tomcat/bin/shutdown.sh
[root@tomcat1 lib]# /usr/local/tomcat/bin/startup.sh
#上述在../conf/context.xml文件中寫入的無注釋配置如下:
上述在主機(jī)Tomcat1上進(jìn)行的操作,需要在主機(jī)Tomcat2上進(jìn)行相同的配置(自行配置,這里就不寫了)。
主機(jī)Tomcat2配置完成后,客戶端訪問Nginx反向代理進(jìn)行測(cè)試,會(huì)看到客戶端的請(qǐng)求依然是分發(fā)到后端兩臺(tái)Tomcat主機(jī)上,但是session會(huì)話ID不會(huì)發(fā)生變化了,說明session會(huì)話信息已經(jīng)保存在了Redis服務(wù)器上,兩臺(tái)Tomcat主機(jī)從Redis上獲取session會(huì)話信息,多次刷新頁面,session會(huì)話都不會(huì)變化,如下:
并且可以在Redis服務(wù)器上查看到保存的session會(huì)話信息,如下:
這里只是測(cè)試環(huán)境,直接下載我提供的源碼包中的MySQL包及mysql.sh腳本文件,進(jìn)行腳本安裝即可,若需要優(yōu)化配置MySQL數(shù)據(jù)庫,還請(qǐng)參考博文:Centos7搭建MySQL數(shù)據(jù)庫進(jìn)行安裝。
腳本安裝過程如下:
[root@mysql ~]# ls | grep mysql #上傳下面兩個(gè)文件到MySQL服務(wù)器上
mysql-5.7.22-linux-glibc2.12-x86_64.tar.gz
mysql.sh
[root@mysql ~]# sh mysql.sh #執(zhí)行此命令后,先去進(jìn)行第七節(jié)操作,這里安裝時(shí)間較長(zhǎng)
Starting MySQL... SUCCESS! #輸出此信息表示MySQL部署成功
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@tomcat1 lib]# cd /usr/local/tomcat/webapps #切換至源碼包默認(rèn)的網(wǎng)頁根目錄
[root@tomcat1 webapps]# mv ROOT /web/webapp1/ #將ROOT目錄復(fù)制到現(xiàn)在的根目錄下
現(xiàn)在客戶端訪問主機(jī)Tomcat1的8080端口/ROOT,如下(這里主要是為了展示Tomcat為我們提供的連接MySQL數(shù)據(jù)庫的方法,可以不跟做):
點(diǎn)擊如下:
然后看到的頁面就是官方給我們的連接MySQL數(shù)據(jù)庫的文檔:
接下來根據(jù)文檔提示,在MySQL數(shù)據(jù)庫上創(chuàng)建用于測(cè)試的用戶及表等。
[root@mysql ~]# mysql -uroot -p123 #登錄到MySQL,腳本安裝的默認(rèn)密碼是123
mysql> grant all on *.* to javauser@'192.168.20.%' identified by 'javapasswd';
#創(chuàng)建測(cè)試用戶
mysql> create database javatest; #創(chuàng)建測(cè)試庫
mysql> use javatest; #切換至創(chuàng)建的庫
mysql> create table testdata(id int not null auto_increment primary key,foo varchar(25),bar int);
#創(chuàng)建表
mysql> insert into testdata(foo,bar) values ('hello','123456'),('ok','654321'),('lvtest','123123');
#向表中插入數(shù)據(jù)
mysql> select * from testdata; #查詢插入的數(shù)據(jù)如下:
+----+--------+--------+
| id | foo | bar |
+----+--------+--------+
| 1 | hello | 123456 |
| 2 | ok | 654321 |
| 3 | lvtest | 123123 |
+----+--------+--------+
3 rows in set (0.00 sec)
[root@tomcat1 ~]# vim /usr/local/tomcat/conf/context.xml #編輯context.xml配置文件
#在文件末尾 之上添加以下內(nèi)容
#在最后這行上面添加以上內(nèi)容
#添加后保存退出即可
[root@tomcat1 ~]# mkdir /web/webapp1/WEB-INF #創(chuàng)建目錄
[root@tomcat1 ~]# vim /web/webapp1/WEB-INF/web.xml #寫入以下內(nèi)容
MySQL Test App
DB Connection
jdbc/TestDB
javax.sql.DataSource
Container
#寫入后,保存退出
[root@tomcat1 ~]# cd /web/webapp1/ #切換至網(wǎng)頁根目錄
[root@tomcat1 webapp1]# vim test.jsp #編寫測(cè)試文件
<%@ page language="java" import="java.sql.*" pageEncoding="GB2312"%>
MySQL-1 #在第二臺(tái)Tomcat進(jìn)行操作時(shí),修改title中的1為2,以便測(cè)試負(fù)載均衡效果
connect MySQL
<%
String driverClass="com.mysql.jdbc.Driver";
String url="jdbc:mysql://192.168.20.6:3306/javatest"; #指定MySQL監(jiān)聽I(yíng)P及端口
String username = "javauser"; #連接MySQL的用戶
String password = "javapasswd"; #用戶密碼
Class.forName(driverClass);
Connection conn=DriverManager.getConnection(url, username, password);
Statement stmt=conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from testdata");
while(rs.next()){
out.println("
foo:"+rs.getString(2)+"bar:"+rs.getString(3));
}
rs.close();
stmt.close();
conn.close();
%>
#寫入后,保存退出即可,然后重啟Tomcat服務(wù)
[root@tomcat1 lib]# /usr/local/tomcat/bin/shutdown.sh
[root@tomcat1 lib]# /usr/local/tomcat/bin/startup.sh
配置至此,客戶端訪問主機(jī)Tomcat1的test.jsp文件,可以看到以下頁面,說明主機(jī)Tomcat1連接數(shù)據(jù)庫沒有問題。得到的頁面如下:
可以看到以上頁面后,然后在Tomcat2進(jìn)行以下操作(與主機(jī)Tomcat1一樣的操作,所以就不寫注釋了)
[root@tomcat2 ~]# vim /usr/local/tomcat/conf/context.xml
[root@tomcat2 ~]# mkdir /web/webapp1/WEB-INF
[root@tomcat2 ~]# vim /web/webapp1/WEB-INF/web.xml
MySQL Test App
DB Connection
jdbc/TestDB
javax.sql.DataSource
Container
[root@tomcat2 ~]# cd /web/webapp1/
[root@tomcat2 webapp1]# vim test.jsp
<%@ page language="java" import="java.sql.*" pageEncoding="GB2312"%>
MySQL-2
connect MySQL
<%
String driverClass="com.mysql.jdbc.Driver";
String url="jdbc:mysql://192.168.20.6:3306/javatest";
String username = "javauser";
String password = "javapasswd";
Class.forName(driverClass);
Connection conn=DriverManager.getConnection(url, username, password);
Statement stmt=conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from testdata");
while(rs.next()){
out.println("
foo:"+rs.getString(2)+"bar:"+rs.getString(3));
}
rs.close();
stmt.close();
conn.close();
%>
[root@tomcat2 lib]# /usr/local/tomcat/bin/shutdown.sh
[root@tomcat2 lib]# /usr/local/tomcat/bin/startup.sh
配置至此,客戶端訪問Nginx代理服務(wù)器(192.168.20.2/test.jsp),多次刷新,可以看到在Tomcat1和Tomcat2之間進(jìn)行切換:
注意,在上面的環(huán)境中,Redis僅僅只是保存Session信息而已,不會(huì)像Memcached一樣,緩存后端服務(wù)器的數(shù)據(jù)的。
———————— 本文至此結(jié)束,感謝閱讀 ————————