您好,登錄后才能下訂單哦!
前言:
為了使web能適應大規模的訪問,需要實現應用的集群部署。集群最有效的方案就是負載均衡,而實現負載均衡用戶每一個請求都有可能被分配到不固定的服務器上,這樣我們首先要解決session的統一來保證無論用戶的請求被轉發到哪個服務器上都能保證用戶的正常用,也就是需要實現session的共享機制。
在集群系統下實現session統一的有如下幾種方案:
1、請求精確定位:sessionsticky,例如基于訪問ip的hash策略,即當前用戶的請求都集中定位到一臺服務器中,這樣單臺服務器保存了用戶的session登錄信息,如果宕機,則等同于單點部署,會丟失,會話不復制。
2、session復制共享:sessionreplication,如tomcat自帶session共享,主要是指集群環境下,多臺應用服務器之間同步session,使session保持一致,對外透明。 如果其中一臺服務器發生故障,根據負載均衡的原理,調度器會遍歷尋找可用節點,分發請求,由于sessio已同步,故能保證用戶的session信息不會丟失,會話復制,。
此方案的不足之處:
必須在同一種中間件之間完成(如:tomcat-tomcat之間).
session復制帶來的性能損失會快速增加.特別是當session中保存了較大的對象,而且對象變化較快時, 性能下降更加顯著,會消耗系統性能。這種特性使得web應用的水平擴展受到了限制。Session內容通過廣播同步給成員,會造成網絡流量瓶頸,即便是內網瓶頸。在大并發下表現并不好。
3、基于cache DB緩存的session共享:即使用cacheDB存取session信息,應用服務器接受新請求將session信息保存在cache DB中,當應用服務器發生故障時,調度器會遍歷尋找可用節點,分發請求,當應用服務器發現session不在本機內存時,則去cache DB中查找,如果找到則復制到本機,這樣實現session共享和高可用。
這里將使用第三種方案,實現session會話共享,將采用Redis來做cache DB。
博文大綱:
一、環境準備
二、配置Nginx反向代理服務器
三、配置Tomcat服務器
四、配置Redis服務器
五、配置Tomcat連接Redis
六、安裝部署MySQL數據庫
七、配置Tomcat連接MySQL數據庫
在進行下面配置前,先下載我提供的源碼包,并自行上傳至對應的服務器。
這里配置Nginx反向代理,只是實現它一個簡單的代理功能,若想優化這個反向代理服務器,那么最好參考博文:Nginx安裝、實現反向代理及深度優化進行配置。
以下操作均在192.168.20.2的Nginx服務器上進行
[root@nginx ~]# yum -y erase httpd #卸載自帶的web服務
[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配置文件,寫入以下內容
http { #在http字段添加以下內容
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字段下面添加以下內容,并注釋掉下面開頭兩行
#root html;
#index index.html index.htm;
proxy_pass http://backend; #主要寫入這一行,以下的是優化,可選寫入
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/ #對Nginx命令做軟連接
[root@nginx conf]# useradd -M -s /sbin/nologin www #創建運行用戶
[root@nginx conf]# nginx -t #檢查配置文件
[root@nginx conf]# nginx #啟動Nginx服務
至此,這臺Nginx就可以提供基本的反向代理功能了,接下來配置Tomcat服務器。
以下操作需要在兩臺Tomcat服務器上分別配置
主機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
<Host name="localhost" appBase="webapps" #找到Host字段
unpackWARs="true" autoDeploy="true"> #在下面添加以下配置
<Context docBase="/web/webapp1" path="" reloadable="true"/>
#以上是配置虛擬主機,指定網頁根目錄是/web/webapp1。添加后保存退出
[root@tomcat1 conf]# mkdir -p /web/webapp1 #創建網頁根目錄
[root@tomcat1 conf]# vim /web/webapp1/index.jsp #編寫首頁文件如下
<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>tomcat-1</title> #稍后在tomcat2主機上,需修改title字段中的數字改為2,以便查看負載均衡效果
</head>
<body>
<h2><font color="red">Session serviced by tomcat</font></h2>
<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>
[root@tomcat1 conf]# /usr/local/tomcat/bin/startup.sh #啟動tomcat服務
將以上Tomcat1主機的所有操作在Tomcat2主機上同樣配置一次
當Tomcat2主機也配置完成后,即可使用客戶端訪問Nginx代理服務器(訪問:192.168.20.2),多次刷新頁面,會依次看到以下頁面(注意,其Session ID并不一樣):
接下來配置Redis緩存服務器,Redis緩存服務器存在的意義就是將客戶端的session會話信息保存下來,用于Tomcat服務器共享這個session會話信息,從而使其不要每次客戶端請求都更新session會話。
[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 #直接移動到指定路徑并重命名
[root@redis src]# cd /usr/local/redis/ #切換至redis目錄
[root@redis redis]# make && make install #無需配置,直接編譯安裝即可
[root@redis redis]# cd utils/ #進入該子目錄
[root@redis utils]# ./install_server.sh #對Redis進行初始化
#初始化的所有選項保持默認,一路回車確認即可
#是在確認監聽端口、配置文件、日志文件、pid存放路徑等信息
.............#省略部分內容
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
#出現上述內容,則表示初始化成功
[root@redis utils]# vim /etc/redis/6379.conf #編輯Redis配置文件
bind 0.0.0.0 #找到沒有被注釋的這一行,修改為0.0.0.0
# requirepass foobared #定位到改行,修改如下:
requirepass 123.com #Redis的密碼為123.com
#修改完成后,保存退出即可。
[root@redis utils]# /etc/init.d/redis_6379 restart #重啟Redis服務
[root@redis utils]# redis-cli -h 192.168.20.5 #登錄數據庫
192.168.20.5:6379> set a b #插入數據測試
(error) NOAUTH Authentication required. #插入失敗,因為沒有進行密碼驗證
192.168.20.5:6379> AUTH 123.com #使用AUTH進行驗證,密碼就是配置文件中定義的“123.com”
OK
192.168.20.5:6379> set a b #再次插入數據
OK #成功
至此,Redis服務器就配置成功了。接下來配置Tomcat,使其可以將Session信息寫入到Redis。
[root@tomcat1 ~]# cd /usr/local/tomcat/lib/
[root@tomcat1 lib]# rz #將我網盤中的以下四個包文件上傳至當前目錄
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 #編輯這個文件
<Manager pathname="" /> #定位到這行,去掉其注釋符號,并在該行下寫入以下內容
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="192.168.20.5" #指定Redis服務器IP
password="123.com" #指定Redis的密碼
port="6379" #指定Redis監聽端口
database="0" #是否可以寫入Redi數據庫,0為是
</Context> #以上的內容在末尾這行上面添加
#編輯完成后,保存退出即可,然后重啟Tomcat
[root@tomcat1 lib]# /usr/local/tomcat/bin/shutdown.sh
[root@tomcat1 lib]# /usr/local/tomcat/bin/startup.sh
#上述在../conf/context.xml文件中寫入的無注釋配置如下:
<Manager pathname="" />
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="192.168.20.5"
password="123.com"
port="6379"
database="0"
maxInactiveInterval="60" />
上述在主機Tomcat1上進行的操作,需要在主機Tomcat2上進行相同的配置(自行配置,這里就不寫了)。
主機Tomcat2配置完成后,客戶端訪問Nginx反向代理進行測試,會看到客戶端的請求依然是分發到后端兩臺Tomcat主機上,但是session會話ID不會發生變化了,說明session會話信息已經保存在了Redis服務器上,兩臺Tomcat主機從Redis上獲取session會話信息,多次刷新頁面,session會話都不會變化,如下:
并且可以在Redis服務器上查看到保存的session會話信息,如下:
這里只是測試環境,直接下載我提供的源碼包中的MySQL包及mysql.sh腳本文件,進行腳本安裝即可,若需要優化配置MySQL數據庫,還請參考博文:Centos7搭建MySQL數據庫進行安裝。
腳本安裝過程如下:
[root@mysql ~]# ls | grep mysql #上傳下面兩個文件到MySQL服務器上
mysql-5.7.22-linux-glibc2.12-x86_64.tar.gz
mysql.sh
[root@mysql ~]# sh mysql.sh #執行此命令后,先去進行第七節操作,這里安裝時間較長
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 #切換至源碼包默認的網頁根目錄
[root@tomcat1 webapps]# mv ROOT /web/webapp1/ #將ROOT目錄復制到現在的根目錄下
現在客戶端訪問主機Tomcat1的8080端口/ROOT,如下(這里主要是為了展示Tomcat為我們提供的連接MySQL數據庫的方法,可以不跟做):
點擊如下:
然后看到的頁面就是官方給我們的連接MySQL數據庫的文檔:
接下來根據文檔提示,在MySQL數據庫上創建用于測試的用戶及表等。
[root@mysql ~]# mysql -uroot -p123 #登錄到MySQL,腳本安裝的默認密碼是123
mysql> grant all on *.* to javauser@'192.168.20.%' identified by 'javapasswd';
#創建測試用戶
mysql> create database javatest; #創建測試庫
mysql> use javatest; #切換至創建的庫
mysql> create table testdata(id int not null auto_increment primary key,foo varchar(25),bar int);
#創建表
mysql> insert into testdata(foo,bar) values ('hello','123456'),('ok','654321'),('lvtest','123123');
#向表中插入數據
mysql> select * from testdata; #查詢插入的數據如下:
+----+--------+--------+
| 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配置文件
#在文件末尾</Context> 之上添加以下內容
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
username="javauser" password="javapasswd" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://192.168.20.6:3306/javatest"/>
</Context> #在最后這行上面添加以上內容
#添加后保存退出即可
[root@tomcat1 ~]# mkdir /web/webapp1/WEB-INF #創建目錄
[root@tomcat1 ~]# vim /web/webapp1/WEB-INF/web.xml #寫入以下內容
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<description>MySQL Test App</description>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
#寫入后,保存退出
[root@tomcat1 ~]# cd /web/webapp1/ #切換至網頁根目錄
[root@tomcat1 webapp1]# vim test.jsp #編寫測試文件
<%@ page language="java" import="java.sql.*" pageEncoding="GB2312"%>
<html>
<head>
<title>MySQL-1</title> #在第二臺Tomcat進行操作時,修改title中的1為2,以便測試負載均衡效果
</head>
<body>
connect MySQL<br>
<%
String driverClass="com.mysql.jdbc.Driver";
String url="jdbc:mysql://192.168.20.6:3306/javatest"; #指定MySQL監聽IP及端口
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("<br>foo:"+rs.getString(2)+"bar:"+rs.getString(3));
}
rs.close();
stmt.close();
conn.close();
%>
</body>
</html>
#寫入后,保存退出即可,然后重啟Tomcat服務
[root@tomcat1 lib]# /usr/local/tomcat/bin/shutdown.sh
[root@tomcat1 lib]# /usr/local/tomcat/bin/startup.sh
配置至此,客戶端訪問主機Tomcat1的test.jsp文件,可以看到以下頁面,說明主機Tomcat1連接數據庫沒有問題。得到的頁面如下:
可以看到以上頁面后,然后在Tomcat2進行以下操作(與主機Tomcat1一樣的操作,所以就不寫注釋了)
[root@tomcat2 ~]# vim /usr/local/tomcat/conf/context.xml
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
username="javauser" password="javapasswd" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://192.168.20.6:3306/javatest"/>
</Context>
[root@tomcat2 ~]# mkdir /web/webapp1/WEB-INF
[root@tomcat2 ~]# vim /web/webapp1/WEB-INF/web.xml
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<description>MySQL Test App</description>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
[root@tomcat2 ~]# cd /web/webapp1/
[root@tomcat2 webapp1]# vim test.jsp
<%@ page language="java" import="java.sql.*" pageEncoding="GB2312"%>
<html>
<head><title>MySQL-2</title>
</head>
<body>
connect MySQL<br>
<%
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("<br>foo:"+rs.getString(2)+"bar:"+rs.getString(3));
}
rs.close();
stmt.close();
conn.close();
%>
</body>
</html>
[root@tomcat2 lib]# /usr/local/tomcat/bin/shutdown.sh
[root@tomcat2 lib]# /usr/local/tomcat/bin/startup.sh
配置至此,客戶端訪問Nginx代理服務器(192.168.20.2/test.jsp),多次刷新,可以看到在Tomcat1和Tomcat2之間進行切換:
注意,在上面的環境中,Redis僅僅只是保存Session信息而已,不會像Memcached一樣,緩存后端服務器的數據的。
———————— 本文至此結束,感謝閱讀 ————————
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。