基於nginx+tomcat的負載均衡以及memcached解決交叉存儲

nginx是以多進程的方式工作的,有一個master進程和多個worker進程
master進程用來管理worker進程
(1)向各worker進程發送信號
(2)監控worker進程,當一個worker進程出現異常後,會啓動新的worker進程。

master進程會先建立好需要監聽的socket,fork函數生成子進程workers,繼承scoket,一般來講,當有連接進入後,所有accept在這個socket上面的進程都會收到通知,而只有一個進程會accept這個連接,其它都會失敗。  ---> 共享鎖

(驚羣現象)當一個事件被觸發以後,,等待這個的所有線程/進程都會被喚醒,但是隻有一個去響應。
解決這種現象nginx提出了共享鎖的概念,有了這把鎖(比如accept_mutex)同一個時刻,就會只有一個進程在accept連接。

nginx比apache高效的原因就是,nginx採用異步非阻塞方式,而apache採用同步阻塞方式

阻塞和非阻塞
阻塞和非阻塞指的是執行一個操作是等操作結束再返回,還是立即返回。
比如去餐廳點菜,傳菜員將菜單給廚師:
(1)阻塞:在窗口等待,直到廚師完成後將菜第到窗口,然後再上菜,這期間服務員不能幹其它事情。
(2)非阻塞:可以先去幹其它事情,過一會來到窗口問好了沒,沒好等會再過來繼續詢問,知道好了爲止。

同步和異步
同步和異步是事件本身的一種屬性;
(1)同步:服務員直接跟廚師打交道,菜好沒好,服務員直接知道,知道菜好了由廚師交給服務員。
(2)異步:廚師和服務員之間還有傳菜員,廚師做好後,由傳菜員將菜遞到傳菜窗口,通知服務員或者不通知。
同步的事情只能以阻塞的方式做
異步的事情可以用阻塞和非阻塞的方式去做。非阻塞既可以是主動查詢,也可以是被動接收,被動接收的效率高於主動查詢。



實驗環境:
redhat6.5虛擬機三臺
server1  172.25.44.1
server2  172.25.44.2
server3  172.25.44.3
火牆和selinux均處於關閉狀態
編輯/etc/hosts文件,加入解析


server1:
用到nginx-1.8.1版本
tar zxf nginx-1.8.1.tar.gz ###解壓
 cd nginx-1.8.1   ###進入解壓目錄

vim src/core/nginx.h    ###屏蔽nginx版本信息,安全性
    14 #define NGINX_VER          "nginx/"
vim auto/cc/gcc        ###關閉debug調式模式(開啓的話軟件臃腫)
    178 # debug
    179 #CFLAGS="$CFLAGS -g"   ###註釋此行

 
yum insall pcre-devel openssl-devel gcc gcc-c++ -y  ###需要解決的一些依賴關係
./configure \
--prefix=/usr/local/nginx \    ###安裝的位置
--with-http_stub_status_module \    ###監控模塊
--with-http_ssl_module
 
make && make install

將路徑/usr/local/nginx/sbin加入~/.bash_profile 文件中
source ~/.bash_profile  ###使文件生效

下面介紹一些nginx常用的命令
nginx              ###開啓nginx
nginx -t           ###檢查配置文件
nginx -s reload    ###重新加載
nginx -s stop      ###停止

vim /usr/local/nginx/conf/nginx.conf
    #user  nobody;
    worker_processes  1;  ###cpu使用個數
    #worker_cpu-affinity 0001 0010 0100 1000;  ##綁定cpu,4個cpu

    events {
        use epoll;      ###異步非阻塞模式
        worker_connections  1024;   ##連接數
    }

     19     upstream linux{
     20         server 172.25.44.2:80;
     21         server 172.25.44.3:80;
     22 }
    
     48         location / {
     49             proxy_pass http://linux;  ###代理
     50            # root   html;
     51            # index  index.html index.htm;
     52         }

重新加載服務nginx -s reload


server2 :
yum install httpd -y
echo "<h1>server2</h1>" > /var/www/html/index.html
/etc/init.d/httpd  start

server3 :
yum install httpd -y
echo "server3" > /var/www/html/index.html
/etc/init.d/httpd  start

測試:網頁訪問測試server1的ip 172.25.44.1
測試結果爲server2和server3輪詢顯示

vim /usr/local/nginx/conf/nginx.conf
     19     upstream linux{
     20         ip_hash;    ###哈希綁定,同一個ip只能訪問一個頁面
     21         server 172.25.44.2:80;
     22         server 172.25.44.3:80;
     23 }
 
nginx -t    nginx -s reload
網頁測試訪問,因爲哈希綁定ip,第一次顯示server2,當server2一直不掛掉的話,一直刷新,就一直顯示sever2,掛掉的話就顯示server3


如果一個局域網的客戶同時訪問服務器,導致服務器分配不均衡;sticky實現了基於cookie的負載均衡
sticky  粘制算法  需要靜態編譯
nginx -s stop   ###停止nginx
tar zxf nginx-sticky-module-1.0.tar.gz -C nginx-1.8.1  ###解壓到指定位置
make clean
 ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module  \
--add-module=nginx-sticky-module-1.0/   ###需要加上nginx  sticky模塊

make && make install


sticky no_fallback;###不做故障轉移;當server2掛掉,網頁出現錯誤頁面,不往server3上轉移
server 172.25.33.22:80 down ;不參加調度
server 172.25.33.22:80 weight=5 ; 權重爲5,與出現次數成正比關係

真機for in in $(seq 10);do curl http://172.25.44.1;done     ###用命令進行檢測


常見的fair url_hash 第三方 同stiky,需要重新編譯
rr ip_hash weight 本地,不需要重新編譯



tomcat 輕量級應用服務器,項目部署到tomcat上,就可以通過外部訪問項目的頁面。
server2 server3
cd /usr/local
sh  jdk-6u32-linux-x64.bin
tar zxf apache-tomcat-7.0.37.tar.gz
ln -s jdk1.6.0_32 java
ln -sapache-tomcat-7.0.37  tomcat
vim /etc/profile
    export JAVA_HOME=/usr/local/java
    export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
    export PATH=$PATH:$JAVA_HOME/bin
source /etc/profile

cd /usr/local/tomcat/bin
./startup.sh
訪問:172.25.44.2:8080   172.25.44.3:8080


默認發佈目錄/usr/local/tomcat/webapps/ROOT
vim test.jsp     ###編輯測試頁
      The time is: <%=new java.util.Date() %>
訪問http://172.25.44.2:8080/test.jsp
    http://172.25.44.3:8080/test.jsp


server1
vim /usr/local/nginx/conf/nginx.conf
     18 http {
     19     upstream linux{
     20         server 172.25.44.2:8080;  輪詢監聽8080端口
     21         server 172.25.44.3:8080;
     22 }

     48         location / {
     49           #  proxy_pass http://linux;
    50             root   html;
     51             index  index.html index.htm;
    52         }
     
     65         location ~ \.jsp$ {
     66             proxy_pass   http://linux;
     67         }
重啓服務
server2 server3

test.jsp內容
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info:
<%
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<%
out.println("<br> ID " + session.getId()+"<br>");
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.print("<b>Session list</b>");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value+"<br>");
System.out.println( name + " = " + value);
}
%>
<form action="test.jsp" method="POST">
name:<input type=text size=20 name="dataName">
<br>
key:<input type=text size=20 name="dataValue">
<br>
<input type=submit>
</form>
</body>
</html>

測試:172.25.44.1/test.jsp
sticky 模式當用戶訪問,只要訪問主機tomcat不掛,就一直訪問同一個
server2:bin/shutdown.sh
存儲的數據保存在44.2中,當44.2掛掉,轉到44.3上,但44.2之前的數據已經不在了
由此提出交叉存儲的概念

memcache高速緩存 交叉存儲解決session問題

server2 server3
yum install memcached -y
/usr/local/tomcat/conf/context.xml
19 <Context>
 20
 21     <!-- Default set of monitored resources -->
 22     <WatchedResource>WEB-INF/web.xml</WatchedResource>
 23
 24     <!-- Uncomment this to disable session persistence across Tomcat restart    s -->
 25     <!--
 26     <Manager pathname="" />
 27     -->
 28
 29     <!-- Uncomment this to enable Comet connection tacking (provides events
 30          on session expiration as well as webapp lifecycle) -->
 31     <!--
 32     <Valve className="org.apache.catalina.valves.CometConnectionManagerValve    " />
 33     -->
 34 <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
 35     memcachedNodes="n1:172.25.44.2:11211,n2:172.25.44.3:11211"  ####
 36    failoverNodes="n1"   ###根據自己的ip修改節點號
 37    requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
 38  transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscode    rFactory"
 39  />
 40 </Context>


傳jar包至目錄/usr/local/tomcat/lib,
rm -fr memcached-session-manager-tc6-1.6.3.jar
(這裏tomcat用的7.0版本,所以刪掉6版本)

/etc/init.d/memcached  start
bin/startup.sh

測試訪問http://172.25.44.1/test.jsp
這種做法主要解決了交叉存儲問題,T1存儲到T2的memcache中,這樣即使當T1和M1同時掛掉,數據也不會丟失。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章