redis是一個(gè)key-value存儲(chǔ)系統(tǒng)。和memcached類似,它支持存儲(chǔ)的value類型相對(duì)更多,包括string(字符串),list(列表),set(集合),zset(sorted set---有序集合)和hash(哈希類型)。與memcached一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別是redis會(huì)周期性地把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎(chǔ)上實(shí)現(xiàn)master-slave(主從)同步。
創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的于都網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
Redis是一個(gè)高性能的key-value數(shù)據(jù)庫(kù)。redis的出現(xiàn),很大程度補(bǔ)償了memcacehd這類key/value存儲(chǔ)的不足,在部分場(chǎng)合可以對(duì)關(guān)系數(shù)據(jù)庫(kù)起到很好的補(bǔ)充作用。它提供了java,C/C++,C#,php,javaScript,Perl,Object-C,python,Ruby等客戶端,使用很方便。
如果簡(jiǎn)單的比較redis與memcached的區(qū)別,基本上有以下3點(diǎn):
1,redis不僅僅支持簡(jiǎn)單的key/value類型的數(shù)據(jù),同時(shí)還提供list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)。
2,redis支持?jǐn)?shù)據(jù)的備份,即master-slave模式的數(shù)據(jù)備份。
3,redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保持在磁盤中,重啟的時(shí)候可以再次加載進(jìn)行使用。
在Reids中,并不是所有的數(shù)據(jù)都一直存儲(chǔ)在內(nèi)存中。這是和memcacehd相比一個(gè)最大的區(qū)別。
Redis只會(huì)緩存所有的key的信息,如果Reids發(fā)現(xiàn)內(nèi)存的使用量超過了某一個(gè)閥值,將觸發(fā)swap的操作,Redis根據(jù)“swappability = age*log(size_in_memory)”
計(jì)算出那些key對(duì)應(yīng)的value需要swap到磁盤。然后再將這些key對(duì)應(yīng)的value持久化到磁盤中,同時(shí)在內(nèi)存中清除。這種特性使得redis可以保存超過其機(jī)器本身內(nèi)存大小的數(shù)據(jù)。當(dāng)然,機(jī)器本身的內(nèi)存必須要能夠保持所有的eky,因?yàn)檫@些數(shù)據(jù)是不會(huì)進(jìn)行swap操作的。
當(dāng)從Redis中讀取數(shù)據(jù)的時(shí)候,如果讀取的key對(duì)應(yīng)的value不再內(nèi)存中,那么Redis就需要從swap文件中加載相應(yīng)的數(shù)據(jù),然后再返回給請(qǐng)求方。
memcached和redis的比較
1,網(wǎng)絡(luò)IO模型
memcacehd是多線程,非阻塞IO復(fù)用的網(wǎng)絡(luò)模型,分為監(jiān)聽主線程和worker子線程,監(jiān)聽線程監(jiān)聽網(wǎng)絡(luò)連接,接受請(qǐng)求后,將連接描述字pipe 傳遞給worker線程,進(jìn)行讀寫IO,網(wǎng)絡(luò)層使用libevent封裝的事件庫(kù),多線程模型可以發(fā)揮多核作用。
Redis使用單線程的IO復(fù)用模型,自己封裝了一個(gè)簡(jiǎn)單的AeEvent事件處理框架,主要實(shí)現(xiàn)了epoll,kqueue和select,對(duì)于單純只有IO操作來說,單線程可以將速度優(yōu)勢(shì)發(fā)揮到最大,但是Redis也提供了一些簡(jiǎn)單的計(jì)算功能,比如排序,聚合等,對(duì)于這些操作,單線程模型實(shí)際會(huì)嚴(yán)重影響整體吞吐量,CPU計(jì)算過程中,整個(gè)IO調(diào)度都是被阻塞住的。
2,內(nèi)存管理方面
memcacehd使用預(yù)分配的內(nèi)存池的方式,使用slab和大小不同的chunk來管理內(nèi)存,value根據(jù)大小選擇合適的chunk存儲(chǔ)。
Redis使用現(xiàn)場(chǎng)申請(qǐng)內(nèi)存的方式來存儲(chǔ)數(shù)據(jù)。
3,存儲(chǔ)方式及其他方面
memcached基本只支持簡(jiǎn)單的key-value存儲(chǔ),不支持持久化和復(fù)制等功能,Redis除key/value之外,還支持list,set,sortedset,hash等眾多數(shù)據(jù)結(jié)構(gòu)。
目前,為了使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ī)制。
在集群系統(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)求,由于session已同步,故能保證用戶的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共享
基于memcache/redis緩存的session共享,即使用cacheDB存儲(chǔ)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共享和高可用。(推薦使用)
主機(jī) | 操作系統(tǒng) | ip地址 |
---|---|---|
nginx | CentOS 7.3 | 172.16.1.100 |
tomcat-1 | CentOS 7.3 | 172.16.1.110 |
tomcat-2 | CentOS 7.3 | 172.16.1.120 |
mysql | CentOS 7.3 | 172.16.1.130 |
Redis | CentOS 7.3 | 172.16.1.30 |
在這個(gè)圖中,nginx做反向代理,實(shí)現(xiàn)動(dòng)靜分離,將客戶動(dòng)態(tài)請(qǐng)求根據(jù)權(quán)重隨機(jī)分配給兩臺(tái)tomcat服務(wù)器,redis作為兩臺(tái)tomcat的共享session數(shù)據(jù)服務(wù)器,mysql作為兩臺(tái)tomcat的后端數(shù)據(jù)庫(kù)。
1,nginx安裝配置
使用nginx作為tomcat的負(fù)載平衡器,tomcat的會(huì)話session數(shù)據(jù)存儲(chǔ)在redis,能夠?qū)崿F(xiàn)零宕機(jī)的7x24效果。因?yàn)閷?huì)話存儲(chǔ)在redis中,因此nginx就不必配置稱stick粘貼某個(gè)tomcat方式,這樣才能真正實(shí)現(xiàn)后臺(tái)多個(gè)tomcat負(fù)載平衡。
1)安裝依賴工具包:
[root@nginx ~]# yum -y install gcc* pcre-devel openssl-devel zlib-devel make vim
2)創(chuàng)建nginx程序用戶組和用戶:
[root@nginx ~]# groupadd -r nginx && useradd -r -g nginx -s /bin/false -M nginx
3)編譯安裝nginx:
[root@nginx ~]# tar zxf nginx-1.8.0.tar.gz
[root@nginx ~]# cd nginx-1.8.0
[root@nginx nginx-1.8.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx \
> --with-http_stub_status_module --with-http_ssl_module --with-http_dav_module --with-http_flv_module \
> --with-http_mp4_module --with-http_gzip_static_module --with-http_gzip_static_module \
> --with-http_addition_module --with-http_sub_module --with-pcre --with-http_realip_module
[root@nginx nginx-1.8.0]# make && make install
4)優(yōu)化路徑并檢查:
[root@nginx nginx-1.8.0]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
[root@nginx nginx-1.8.0]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
5)編寫nginx服務(wù)腳本:
[root@nginx nginx-1.8.0]# vim /etc/init.d/nginx
#!/bin/bash
# chkconfig: 2345 99 20
# description: Nginx Service Control Script
PROG="/usr/local/nginx/sbin/nginx"
PIDF="/usr/local/nginx/logs/nginx.pid"
case "$1" in
start)
netstat -anplt |grep ":80" &> /dev/null && pgrep "nginx" &> /dev/null
if [ $? -eq 0 ]
then
echo "Nginx service already running."
else
$PROG -t &> /dev/null
if [ $? -eq 0 ] ; then
$PROG
echo "Nginx service start success."
else
$PROG -t
fi
fi
;;
stop)
netstat -anplt |grep ":80" &> /dev/null && pgrep "nginx" &> /dev/null
if [ $? -eq 0 ]
then
kill -s QUIT $(cat $PIDF)
echo "Nginx service stop success."
else
echo "Nginx service already stop"
fi
;;
restart)
$0 stop
$0 start
;;
status)
netstat -anplt |grep ":80" &> /dev/null && pgrep "nginx" &> /dev/null
if [ $? -eq 0 ]
then
echo "Nginx service is running."
else
echo "Nginx is stop."
fi
;;
reload)
netstat -anplt |grep ":80" &> /dev/null && pgrep "nginx" &> /dev/null
if [ $? -eq 0 ]
then
$PROG -t &> /dev/null
if [ $? -eq 0 ] ; then
kill -s HUP $(cat $PIDF)
echo "reload Nginx config success."
else
$PROG -t
fi
else
echo "Nginx service is not run."
fi
;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac
#并加入開機(jī)自啟:
[root@nginx ~]# chkconfig --add nginx
[root@nginx ~]# chkconfig nginx on
#啟動(dòng)nginx:
[root@nginx ~]# systemctl daemon-reload
[root@nginx ~]# systemctl start nginx
[root@nginx ~]# netstat -anput | grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 21812/nginx: master
6)配置nginx反向代理(反向代理+負(fù)載均衡+健康檢測(cè))
注:結(jié)合proxy和upstream模塊實(shí)現(xiàn)后端web負(fù)載均衡;
結(jié)合nginx默認(rèn)自帶的ngx_http_proxy_module模塊 和ngx_http_upstream_module模塊實(shí)現(xiàn)后端服務(wù)器的健康檢查;
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
在http{}字段中添加以下配置項(xiàng):
#load balance Settings:
upstream backend_tomcat {
server 172.16.1.110:8080 weight=1 max_fails=2 fail_timeout=10s;
server 172.16.1.120:8080 weight=1 max_fails=2 fail_timeout=10s;
}
# http_proxy Settings:
proxy_connect_timeout 75; #nginx 跟后端服務(wù)器連接超時(shí)時(shí)間(代理連接超時(shí))
proxy_send_timeout 75; #定義后端服務(wù)器的數(shù)據(jù)回傳時(shí)間,即在規(guī)定時(shí)間之內(nèi)后端服務(wù)器必須傳完所有的數(shù)據(jù),否則,nginx將斷開這個(gè)連接。
proxy_read_timeout 75; #定義從后端服務(wù)器讀取響應(yīng)的超時(shí)
proxy_buffer_size 4k; #設(shè)置緩沖區(qū)的大小(該緩沖區(qū)大小默認(rèn)等于 proxy_buffers 指令設(shè)置的一塊緩沖區(qū)的大小,但它也可以被設(shè)置得更小)
proxy_buffers 4 32k; #為每個(gè)連接設(shè)置緩沖區(qū)的數(shù)量和每塊緩沖區(qū)的大小
proxy_busy_buffers_size 64k; #高負(fù)荷下緩沖大?。J(rèn)大小是 proxy_buffers 指令設(shè)置單塊緩沖大小的 2 倍)
proxy_temp_file_write_size 64k; #當(dāng)緩存被代理的服務(wù)器響應(yīng)到臨時(shí)文件時(shí),這個(gè)選項(xiàng)限制每次寫臨時(shí)文件的大小
參數(shù)解釋:
weight:輪詢權(quán)值,也是可以用在ip_hash的,默認(rèn)值為1
max_fails:運(yùn)行請(qǐng)求失敗的次數(shù),默認(rèn)為1。當(dāng)超過最大次數(shù)時(shí),返回proxy_next_upstream模塊定義的錯(cuò)誤。
fail_timeout:有兩層含義,以時(shí)在10s時(shí)間內(nèi)最多容許2次失??;二是在經(jīng)歷了2次失敗以后,10s時(shí)間內(nèi)不分配請(qǐng)求到這臺(tái)服務(wù)器。
在server模塊中添加:
#proxy_pass Settings:
location ~* \.(jsp|do)$ { #匹配到的動(dòng)態(tài)請(qǐng)求將進(jìn)行轉(zhuǎn)發(fā)
proxy_pass http://backend_tomcat; #請(qǐng)求轉(zhuǎn)向 backend 定義的服務(wù)器列表,即反向代理,對(duì)應(yīng) upstream 負(fù)載均衡器。
proxy_redirect off; #是否定義重定向規(guī)則
proxy_set_header Host $host; #允許重新定義或者添加發(fā)往后端服務(wù)器的請(qǐng)求頭
proxy_set_header X-Real-IP $remote_addr; #web服務(wù)器端獲得用戶的真實(shí)ip, 也可以通過下面的X-Forward-For獲取
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #后端的 Web 服務(wù)器可以通過 X-Forwarded-For 獲取用戶真實(shí) IP
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
#增加故障轉(zhuǎn)移,如果后端的服務(wù)器返回502、 504、執(zhí)行超時(shí)等錯(cuò)誤,自動(dòng)將請(qǐng)求轉(zhuǎn)發(fā)到upstream負(fù)載均衡池中的另一臺(tái)服務(wù)器,實(shí)現(xiàn)故障轉(zhuǎn)移
}
7)重啟nginx服務(wù)并設(shè)置防火墻規(guī)則:
[root@nginx ~]# systemctl restart nginx
[root@nginx ~]# firewall-cmd --add-port=80/tcp --permanent
success
[root@nginx ~]# firewall-cmd --reload
success
2,安裝部署tomcat服務(wù)器
在安裝tomcat之前必須先安裝JDK,JDK是sun公司免費(fèi)提供的java語言的軟件開發(fā)工具包,其中包含java虛擬機(jī)(JVM),編寫好的java源程序經(jīng)過編譯可形成java字節(jié)碼,只要安裝了JDK,就可以利用JVM解釋這些字節(jié)碼文件,從而保證了java的平臺(tái)性。
1)安裝JDK,配置java環(huán)境(tomcat1和tomcat2 服務(wù)器安裝)
[root@tomcat-1 ~]# tar zxf jdk-8u211-linux-x64.tar.gz
[root@tomcat-1 ~]# mv jdk1.8.0_211/ /usr/local/java
[root@tomcat-1 ~]# vim /etc/profile
export JAVA_HOME=/usr/local/java
export PATH=$JAVA_HOME/bin:$PATH
[root@tomcat-1 ~]# source /etc/profile
[root@tomcat-1 ~]# java -version #確保java版本與當(dāng)前版本一致
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
2)安裝tomcat(tomcat1和tomcat2 服務(wù)器相同操作)
可在tomcat官網(wǎng)中下載需要的版本:https://tomcat.apache.org
[root@tomcat-1 ~]# tar zxf apache-tomcat-8.5.35.tar.gz
[root@tomcat-1 ~]# mv apache-tomcat-8.5.35 /usr/local/tomcat8
[root@tomcat-1 ~]# vim /etc/profile
export CATALINA_HOME=/usr/local/tomcat8
export PATH=$JAVA_HOME/bin:$CATALINA_HOME/bin:$PATH
[root@tomcat-1 ~]# source /etc/profile
#啟動(dòng)tomcat:
[root@tomcat-1 ~]# /usr/local/tomcat8/bin/startup.sh
#這里只是展示啟動(dòng)腳本的路徑,因?yàn)樯线呍O(shè)置了環(huán)境變量,可直接執(zhí)行startup.sh腳本
Using CATALINA_BASE: /usr/local/tomcat8
Using CATALINA_HOME: /usr/local/tomcat8
Using CATALINA_TMPDIR: /usr/local/tomcat8/temp
Using JRE_HOME: /usr/local/java
Using CLASSPATH: /usr/local/tomcat8/bin/bootstrap.jar:/usr/local/tomcat8/bin/tomcat-juli.jar
Tomcat started.
[root@tomcat-1 ~]# netstat -anput | grep 8080
tcp6 0 0 :::8080 :::* LISTEN 15408/java
#防火墻規(guī)則配置:
[root@tomcat-1 ~]# firewall-cmd --add-port=8080/tcp --permanent
success
[root@tomcat-1 ~]# firewall-cmd --reload
success
#瀏覽器測(cè)試訪問兩臺(tái)tomcat服務(wù)器
3)修改tomcat配置文件(tomcat1和tomcat2操作)
[root@tomcat-1 ~]# vim /usr/local/tomcat8/conf/server.xml
#設(shè)置默認(rèn)虛擬主機(jī),并增加jvmRoute
#修改默認(rèn)虛擬主機(jī),并將網(wǎng)站文件路徑指向/web/webapp1,在host段增加context段
#添加該行內(nèi)容
#tomcat-2服務(wù)器的配置文件:
#兩臺(tái)配置只是jvmRoute不同,其他配置保持一致:
說明:jvmRoute是jvm標(biāo)識(shí),就是頁(yè)面最頂部的標(biāo)簽,在實(shí)際生產(chǎn)環(huán)境中,所有的后臺(tái)tomcat標(biāo)識(shí)都要一樣,這里為了實(shí)驗(yàn)的說明性,我兩臺(tái)tomcat的標(biāo)識(shí)改成不一樣的。等會(huì)為了驗(yàn)證時(shí)候好驗(yàn)證。
4)創(chuàng)建網(wǎng)頁(yè)目錄與測(cè)試文件:(tomcat-1和tomcat-2操作相同)
[root@tomcat-1 ~]# mkdir -p /web/webapp1
[root@tomcat-1 ~]# vim /web/webapp1/index.jsp #編寫動(dòng)態(tài)網(wǎng)頁(yè)文件
#內(nèi)容如下:
<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
tomcat-1
Session serviced by tomcat
Session ID
<%=session.getId() %>
<% session.setAttribute("abc","abc");%>
Created on
<%= session.getCreationTime() %>
#注意:為了測(cè)試負(fù)載均衡,tomcat-2節(jié)點(diǎn)index.jsp文件的title修改為“tomcat-2”(生產(chǎn)環(huán)境兩個(gè)tomcat服務(wù)器提供的網(wǎng)頁(yè)內(nèi)容是相同的),其他配置相同。
5)重啟tomct服務(wù),并驗(yàn)證負(fù)載均衡
#tomcat-1和tomcat-2都需要重啟
[root@tomcat-1 ~]# shutdown.sh
[root@tomcat-1 ~]# startup.sh
[root@tomcat-1 ~]# netstat -anput | grep 8080
tcp6 0 0 :::8080 :::* LISTEN 15551/java
#用戶使用瀏覽器通過訪問nginx web服務(wù),驗(yàn)證負(fù)載均衡:
第一次訪問的結(jié)果:
第二次訪問的結(jié)果:
從上面的結(jié)果能看出兩次訪問,nginx把訪問請(qǐng)求分別分發(fā)給了后端的tomcat-1和tomcat-2,客戶端的訪問請(qǐng)求實(shí)現(xiàn)了負(fù)載均衡,但session id不一樣(即:沒有實(shí)現(xiàn)session保持),這樣的話,會(huì)給后端服務(wù)器造成很大的壓力。
6)驗(yàn)證健康檢查
#可以關(guān)掉一臺(tái)tomcat主機(jī),模擬宕機(jī),用客戶端瀏覽器測(cè)試訪問
[root@tomcat-1 ~]# shutdown.sh
Using CATALINA_BASE: /usr/local/tomcat8
Using CATALINA_HOME: /usr/local/tomcat8
Using CATALINA_TMPDIR: /usr/local/tomcat8/temp
Using JRE_HOME: /usr/local/java
Using CLASSPATH: /usr/local/tomcat8/bin/bootstrap.jar:/usr/local/tomcat8/bin/tomcat-juli.jar
無論你怎么刷新頁(yè)面,一直都是tomcat2提供服務(wù),說明健康檢查起到了作用,驗(yàn)證成功。
#前邊可以說是準(zhǔn)備工作,下面才是該項(xiàng)目的重點(diǎn)。
1)安裝redis
官網(wǎng)下載地址:http://download.redis.io/releases/
[root@redis ~]# tar zxf redis-4.0.14.tar.gz
[root@redis ~]# cd redis-4.0.14/
[root@redis redis-4.0.14]# make && make install
通過上圖,我們可以很容易的看出,redis安裝到/usr/local,/usr/local/bin,/usr/local/share,/usr/local/include,/usr/local/lib,/usr/local/share/man目錄下。
#然后再切換到utils目錄下,執(zhí)行redis初始化腳本install_server.sh,如下:
[root@redis redis-4.0.14]# cd utils/
[root@redis utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port : 6379
Config file : /etc/redis/6379.conf
Log file : /var/log/redis_6379.log
Data dir : /var/lib/redis/6379
Executable : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
#上面全部默認(rèn)回車就好
通過上面的安裝過程,我們可以看出redis初始化后redis配置文件為/etc/redis/6379.conf,日志文件為/var/log/redis_6379.log,數(shù)據(jù)文件dump.rdb存放到/var/lib/redis/6379目錄下,啟動(dòng)腳本為/etc/init.d/redis_6379。
#如果需要使用systemd,可以在/etc/systemd/system 下創(chuàng)建一個(gè)單位文件名字為redis_6379.service。
[root@redis utils]# vim /etc/systemd/system/redis_6379.service
#內(nèi)容如下:
[Unit]
Description=Redis on port 6379
[Service]
Type=forking
ExecStart=/etc/init.d/redis_6379 start
ExecStop=/etc/init.d/redis_6379 stop
[Install]
WantedBy=multi-user.target
#注:這里Type=forking是后臺(tái)運(yùn)行的形式
#啟動(dòng)redis
[root@redis utils]# systemctl daemon-reload
[root@redis utils]# systemctl enable redis_6379.service
[root@redis utils]# systemctl start redis_6379.service
#從上圖我們可以看到,服務(wù)狀態(tài)是死亡狀態(tài),解決辦法就是重啟一下服務(wù)即可,如下圖所示:
#防火墻規(guī)則設(shè)置:
[root@redis utils]# firewall-cmd --add-port=6379/tcp --permanent
success
[root@redis utils]# firewall-cmd --reload
success
2)配置redis
[root@redis ~]# vim /etc/redis/6379.conf
#修改內(nèi)容如下(去掉注釋并修改):
bind 172.16.1.30 #將redis的監(jiān)聽地址修改為redis主機(jī)的ip
requirepass pwd@123 #考慮到安全性,需要啟動(dòng)redis的密碼驗(yàn)證功能requirepass參數(shù)。
#重新啟動(dòng)redis服務(wù):
[root@redis ~]# systemctl restart redis_6379.service
[root@redis ~]# netstat -anput | grep redis
tcp 0 0 172.16.1.30:6379 0.0.0.0:* LISTEN 12261/redis-server
#redis配置文件配置完畢后,啟動(dòng)redis并進(jìn)行簡(jiǎn)單操作(測(cè)試),如下:
[root@redis ~]# redis-cli -h 172.16.1.30 -p 6379 -a pwd@123
Warning: Using a password with '-a' option on the command line interface may not be safe.
172.16.1.30:6379> keys *
(empty list or set)
172.16.1.30:6379> set name lisi
OK
172.16.1.30:6379> get name
"lisi"
172.16.1.30:6379> quit
以上參數(shù)解釋:
首先我們利用redis的命令行工具redis-cli,連接redis服務(wù)器,ip是172.16.1.30(這里就以本機(jī)進(jìn)行測(cè)試),端口是6379,密碼是pwd@123
keys *:是查看redis所有的鍵值對(duì)
set nam lisi:添加一個(gè)key(name)-value(lisi)
get name:查看name這個(gè)鍵值的內(nèi)容
quit:退出連接
#redis的其他操作命令,會(huì)在后面講解到
到此,redis的所有部署完畢,接下來配置tomcat的session同步。
3)配置tomcat session redis同步(tomcat1和tomcat2操作相同)
#下載tomcat-redis-session-manager相應(yīng)的jar包,主要有三個(gè):
tomcat85-session-redis-1.0.jar
jedis-2.9.0.jar
commons-pool2-2.4.2.jar
① 下載完成后分別拷貝到$TOMCAT_HOME/lib目錄中:
[root@tomcat-1 ~]# cp tomcat85-session-redis-1.0.jar jedis-2.9.0.jar commons-pool2-2.4.2.jar /usr/local/tomcat8/lib/
② 修改tomcat的context.xml文件:
[root@tomcat-1 ~]# vim /usr/local/tomcat8/conf/context.xml
添加以下內(nèi)容:
圖中內(nèi)容如下:
#session的失效時(shí)間(單位s)
③ 修改完,重啟tomcat:
[root@tomcat-1 ~]# shutdown.sh
[root@tomcat-1 ~]# startup.sh
[root@tomcat-1 ~]# netstat -anput | grep 8080
tcp6 0 0 :::8080 :::* LISTEN 16931/java
在tomcat-2主機(jī)上重復(fù)以上操作。
④驗(yàn)證session會(huì)話是否一致
#模擬用戶通過瀏覽器訪問http://172.16.1.100/index.jsp 測(cè)試頁(yè)
第一次訪問:
第二次訪問(刷新頁(yè)面):
可以看出,分別訪問了不同的tomcat,但是得到的session卻是相同的,說明session會(huì)話保持同步,達(dá)到了集群的目的。
注:從tomcat6開始默認(rèn)開啟了session持久化設(shè)置,測(cè)試時(shí)可以關(guān)閉本地session持久化,其實(shí)也很簡(jiǎn)單,在tomcat的conf目錄下的context.xml文件中,取消注釋下面那段配置即可:
#修改前:
#修改后:
⑤ 查看redis:
[root@redis ~]# redis-cli -h 172.16.1.30 -p 6379 -a pwd@123
Warning: Using a password with '-a' option on the command line interface may not be safe.
172.16.1.30:6379> keys *
1) "3585F7426EBBC83802C0407575FEAC72tMLrlI.tomcat-2"
2) "name"
172.16.1.30:6379> quit
可以看出,redis為保持在tomcat2上的session會(huì)話保持建立了鍵值對(duì)。
tomcat的session會(huì)話保持通過redis把這個(gè)問題解決掉了,現(xiàn)在該解決tomcat連接數(shù)據(jù)庫(kù)問題了。(主機(jī)172.16.1.130作為mysql DB 服務(wù)器)
1)安裝mysql服務(wù)(二進(jìn)制方式)
[root@mysql ~]# vim mysql5.7.sh
#!/bin/bash
rpm -qa | grep mariadb &> /dev/null
if [ $? -eq 0 ]
then
rpm -e mariadb-libs --nodeps
fi
tar zxf mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz
mv mysql-5.7.28-linux-glibc2.12-x86_64 /usr/local/mysql
ln -s /usr/local/mysql/bin/* /usr/local/bin
groupadd -r mysql && useradd -r -g mysql -s /bin/false -M mysql
mkdir /usr/local/mysql/data
chown -R mysql:mysql /usr/local/mysql
cat > /etc/my.cnf <
[root@mysql ~]# sh mysql5.7.sh
Starting MySQL. SUCCESS!
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@mysql ~]# ss -anput | grep 3306
tcp LISTEN 0 80 :::3306 :::* users:(("mysqld",pid=16753,fd=12))
#防火墻規(guī)則設(shè)置:
[root@mysql ~]# firewall-cmd --add-port=3306/tcp --permanent
success
[root@mysql ~]# firewall-cmd --reload
success
2)在數(shù)據(jù)庫(kù)中創(chuàng)建數(shù)據(jù)
[root@mysql ~]# mysql -uroot -p123.com
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> grant all on *.* to javauser@'172.16.1.%' identified by 'pwd@123'; //授權(quán)一個(gè)用戶
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> create database javadb; //創(chuàng)建庫(kù)
Query OK, 1 row affected (0.00 sec)
mysql> use javadb
Database changed
mysql> create table testtb(id int primary key auto_increment,
-> name varchar(25),
-> age int(3)); //創(chuàng)建表
Query OK, 0 rows affected (0.00 sec)
mysql> insert into testtb(name,age) values('zhangsan','20'),('lisi','21'),('sunqian','22'); //插入數(shù)據(jù)
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from testtb; #查看一下
+----+----------+------+
| id | name | age |
+----+----------+------+
| 1 | zhangsan | 20 |
| 2 | lisi | 21 |
| 3 | sunqian | 22 |
+----+----------+------+
3 rows in set (0.00 sec)
3)配置tomcat服務(wù)器連接mysql數(shù)據(jù)庫(kù)(兩臺(tái)tomcat操作相同)
(1)下載mysql-connector-java-5.1.22-bin.jar并復(fù)制到$CATALINA_HOME/lib目錄下:
[root@tomcat-1 ~]# cp mysql-connector-java-5.1.22.jar /usr/local/tomcat8/lib/
(2)Context文件設(shè)置:
[root@tomcat-1 ~]# vim /usr/local/tomcat8/conf/context.xml
#上圖在中添加的內(nèi)容如下:
(3)在/web/webapp1/根目錄下新建目錄,用于存放網(wǎng)站xml配置文件,用于tomcat連接mysql數(shù)據(jù)庫(kù)
[root@tomcat-1 ~]# mkdir /web/webapp1/WEB-INF
[root@tomcat-1 ~]# vim /web/webapp1/WEB-INF/web.xml
添加內(nèi)容如下:
MySQL Test App
DB Connection
jdbc/TestDB
javax.sql.DataSource
Container
#保存修改并退出,重啟tomcat服務(wù):
[root@tomcat-1 ~]# shutdown.sh
Using CATALINA_BASE: /usr/local/tomcat8
Using CATALINA_HOME: /usr/local/tomcat8
Using CATALINA_TMPDIR: /usr/local/tomcat8/temp
Using JRE_HOME: /usr/local/java
Using CLASSPATH: /usr/local/tomcat8/bin/bootstrap.jar:/usr/local/tomcat8/bin/tomcat-juli.jar
[root@tomcat-1 ~]# startup.sh
Using CATALINA_BASE: /usr/local/tomcat8
Using CATALINA_HOME: /usr/local/tomcat8
Using CATALINA_TMPDIR: /usr/local/tomcat8/temp
Using JRE_HOME: /usr/local/java
Using CLASSPATH: /usr/local/tomcat8/bin/bootstrap.jar:/usr/local/tomcat8/bin/tomcat-juli.jar
Tomcat started.
tomcat-2進(jìn)行和tomcat-1相同的操作。
(4)測(cè)試代碼
#現(xiàn)在創(chuàng)建一個(gè)簡(jiǎn)單的測(cè)試.jsp頁(yè)面,測(cè)試tomcat和mysql的連通性
[root@tomcat-1 ~]# vim /web/webapp1/test.jsp
#內(nèi)容如下:(根據(jù)自己的環(huán)境,修改相對(duì)應(yīng)的參數(shù))
<%@ page language="java" import="java.sql.*" pageEncoding="GB2312"%>
MySQL
connect MySQL
<%
String driverClass="com.mysql.jdbc.Driver";
String url="jdbc:mysql://172.16.1.130:3306/javadb";
String username = "javauser";
String password = "pwd@123";
Class.forName(driverClass);
Connection conn=DriverManager.getConnection(url, username, password);
Statement stmt=conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from testtb");
while(rs.next()){
out.println("
name:"+rs.getString(2)+"age:"+rs.getString(3));
}
rs.close();
stmt.close();
conn.close();
%>
注:在tomcat-2節(jié)點(diǎn)上創(chuàng)建同樣的測(cè)試代碼,但是為了更好的驗(yàn)證,把標(biāo)題修改為”MySQL-2“。
(5)通過瀏覽器進(jìn)行訪問測(cè)試頁(yè),URL:http://172.16.1.100/test.jsp ,還是通過nginx反向代理后端的tomcat服務(wù)器。
從上圖可以看出,現(xiàn)在tomcat-1和tomcat-2已經(jīng)可以連接到數(shù)據(jù)庫(kù)了。
到此,項(xiàng)目搭建完畢。。。
安裝包和jar包已上傳至網(wǎng)盤:鏈接:https://pan.baidu.com/s/133H7oEbBWiBvaNWUoFgH3Q
提取碼:2fj1
以上就是nginx+tomcat+redis+mysql實(shí)現(xiàn)session會(huì)話技術(shù)共享做了簡(jiǎn)略的介紹,當(dāng)然詳細(xì)使用上面的不同還得要大家自己使用過才干領(lǐng)會(huì)。如果想了解更多,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道哦!