前言:
爲了使web能適應大規模的訪問,須要實現應用的集羣部署。集羣最有效的方案就是負載均衡,而實現負載均衡用戶每個請求都有可能被分配到不固定的服務器上,這樣咱們首先要解決session的統一來保證不管用戶的請求被轉發到哪一個服務器上都能保證用戶的正經常使用,也就是須要實現session的共享機制。html
在集羣系統下實現session統一的有以下幾種方案:
一、請求精肯定位:sessionsticky,例如基於訪問ip的hash策略,即當前用戶的請求都集中定位到一臺服務器中,這樣單臺服務器保存了用戶的session登陸信息,若是宕機,則等同於單點部署,會丟失,會話不復制。
二、session複製共享:sessionreplication,如tomcat自帶session共享,主要是指集羣環境下,多臺應用服務器之間同步session,使session保持一致,對外透明。 若是其中一臺服務器發生故障,根據負載均衡的原理,調度器會遍歷尋找可用節點,分發請求,因爲sessio已同步,故能保證用戶的session信息不會丟失,會話複製,。
此方案的不足之處:
必須在同一種中間件之間完成(如:tomcat-tomcat之間).
session複製帶來的性能損失會快速增長.特別是當session中保存了較大的對象,並且對象變化較快時, 性能降低更加顯著,會消耗系統性能。這種特性使得web應用的水平擴展受到了限制。Session內容經過廣播同步給成員,會形成網絡流量瓶頸,即使是內網瓶頸。在大併發下表現並很差。
三、基於cache DB緩存的session共享:即便用cacheDB存取session信息,應用服務器接受新請求將session信息保存在cache DB中,當應用服務器發生故障時,調度器會遍歷尋找可用節點,分發請求,當應用服務器發現session不在本機內存時,則去cache DB中查找,若是找到則複製到本機,這樣實現session共享和高可用。java
這裏將使用第三種方案,實現session會話共享,將採用Redis來作cache DB。mysql
博文大綱:
1、環境準備
2、配置Nginx反向代理服務器
3、配置Tomcat服務器
4、配置Redis服務器
5、配置Tomcat鏈接Redis
6、安裝部署MySQL數據庫
7、配置Tomcat鏈接MySQL數據庫linux
在進行下面配置前,先下載我提供的源碼包,並自行上傳至對應的服務器。nginx
這裏配置Nginx反向代理,只是實現它一個簡單的代理功能,若想優化這個反向代理服務器,那麼最好參考博文:Nginx安裝、實現反向代理及深度優化進行配置。web
如下操做均在192.168.20.2的Nginx服務器上進行redis
[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服務器。sql
如下操做須要在兩臺Tomcat服務器上分別配置數據庫
主機Tomcat1操做以下:apache
[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> <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> [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同樣,緩存後端服務器的數據的。
———————— 本文至此結束,感謝閱讀 ————————