JAVA—咖啡館

          ——?dú)g迎訪問(wèn)rogerfan的博客,常來(lái)《JAVA——咖啡館》坐坐,喝杯濃香的咖啡,彼此探討一下JAVA技術(shù),交流工作經(jīng)驗(yàn),分享JAVA帶來(lái)的快樂(lè)!本網(wǎng)站部分轉(zhuǎn)載文章,如果有版權(quán)問(wèn)題請(qǐng)與我聯(lián)系。

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            447 Posts :: 145 Stories :: 368 Comments :: 0 Trackbacks

          首先,我們明確目標(biāo),做Tomcat集群的目的是為了提供更高的負(fù)載能力,把訪問(wèn)均攤到不同的服務(wù)器上。

          直觀地來(lái)說(shuō),就是訪問(wèn)test.localhost.com時(shí),nignx會(huì)隨機(jī)將訪問(wèn)請(qǐng)求分發(fā)到tomcat1,tomcat2,為了保持session同步,使用memcached去管理session。

          為此我們準(zhǔn)備的配置清單是: windows x 1 nginx x 1 memcached x 1 tomcat x 2 mysql x 1

          部署的架構(gòu)圖如下:

          架構(gòu)圖

          首先,我準(zhǔn)備了一個(gè)Java Web項(xiàng)目、tomcat 6、jdk6。

          Step1 配置tomcat

          先將項(xiàng)目部署到tomcat,因?yàn)橐玫絻蓚€(gè)tomcat,當(dāng)然地要把其中一個(gè)tomcat的端口修改一下。

          Step2 配置nginx

          下載安裝nginx,http://kevinworthington.com/nginx-for-windows/

          在host里準(zhǔn)備一個(gè)測(cè)試域名。打開(kāi)C:\Windows\System32\drivers\etc\host, 添加域名映射

              127.0.0.1    test.local.com 

          打開(kāi)nginx的根目錄,在conf里添加test.conf,內(nèi)容大概如下。

              upstream  test.local.com  {                     server   127.0.0.1:8080 weight=1;                     server   127.0.0.1:8083 weight=1;           }     server {             listen       80;          server_name test.local.com;              error_page   500 502 503 504  /50x.html;             location = /50x.html {                 root   html;             }      root /data/projects/ycp/bill;          # - rewrite: if( path ~ "^/assets/(.*)" ) goto "/public/assets/$1"     #    location ~ ^/static/assets/(.*)$     #    {     #alias /data/projects/payment/web/public/assets/$1;     #      access_log off;     #      #expires 3d;     #    }      location / {                 index  index.html index.htm  index.jsp;             }          location ~ .* {     # proxy_pass_header Server;      proxy_set_header Host $http_host;     # proxy_redirect off;      proxy_set_header X-Real-IP $remote_addr;      proxy_set_header X-Scheme $scheme;      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;     add_header Pragma "no-cache";     proxy_pass http://test.local.com;         }           rewrite ^/admin/?$ /admin/login redirect;          # for rewrite         rewrite ^/(channel|admin|mobile|api|web)/(.*)$ /public/index.php/$2 last;          #redirect to mobile wap     #rewrite ^$ /m redirect;     #rewrite ^/$ /mobile/user redirect;        } 

          然后將test.conf引入到nginx.conf里面

              include ycp-test.conf;   

          此時(shí),我們可以啟動(dòng)nginx和tomcat,訪問(wèn)http://test.local.com,試試效果。

          Step3 配置和調(diào)試memcached

          上一步,我們配好了nginx集群,但是tomcat的session還沒(méi)有集到一起。接下來(lái)我們會(huì)用memcached管理session。
          下載安裝memcached。http://blog.couchbase.com/memcached-windows-64-bit-pre-release-available
          點(diǎn)擊這里直接下載
          ps: memcached官網(wǎng)
          解壓放某個(gè)盤(pán)下面,比如在c:\memcached
          在CMD下輸入 "c:\memcached\memcached.exe -d install" 安裝。
          再輸入:"c:\memcached\memcached.exe -d start" 啟動(dòng)。NOTE: 以后memcached將作為windows的一個(gè)服務(wù)每次開(kāi)機(jī)時(shí)自動(dòng)啟動(dòng)。
          如圖:
          memcached服務(wù)

          啟動(dòng)時(shí)可添加其他參數(shù)
          -p 監(jiān)聽(tīng)的端口
          -l 連接的IP地址, 默認(rèn)是本機(jī)
          -d start 啟動(dòng)memcached服務(wù)
          -d restart 重起memcached服務(wù)
          -d stop|shutdown 關(guān)閉正在運(yùn)行的memcached服務(wù)
          -d install 安裝memcached服務(wù)
          -d uninstall 卸載memcached服務(wù)
          -u 以的身份運(yùn)行 (僅在以root運(yùn)行的時(shí)候有效)
          -m 最大內(nèi)存使用,單位MB。默認(rèn)64MB
          -M 內(nèi)存耗盡時(shí)返回錯(cuò)誤,而不是刪除項(xiàng)
          -c 最大同時(shí)連接數(shù),默認(rèn)是1024
          -f 塊大小增長(zhǎng)因子,默認(rèn)是1.25
          -n 最小分配空間,key+value+flags默認(rèn)是48
          -h 顯示幫助

          另外,我們可以用telnet操作memcached
          windows如果本來(lái)沒(méi)有telnet命令的話,可以在控制面板-程序和功能-啟動(dòng)或關(guān)閉Windows功能里面勾選telnet客戶端
          telnet客戶端

              telnet 127.0.0.1 11211       stats 

          可得到描述Memcached服務(wù)器運(yùn)行情況的參數(shù)。如下圖:
          stats參數(shù)
          ps:網(wǎng)上給出的一些參數(shù)解釋

          1. pid: memcached服務(wù)進(jìn)程的進(jìn)程ID
          2. uptime: memcached服務(wù)從啟動(dòng)到當(dāng)前所經(jīng)過(guò)的時(shí)間,單位是秒。
          3. time: memcached服務(wù)器所在主機(jī)當(dāng)前系統(tǒng)的時(shí)間,單位是秒。
          4. version: memcached組件的版本。這里是我當(dāng)前使用的1.2.6。
          5. pointer_size:服務(wù)器所在主機(jī)操作系統(tǒng)的指針大小,一般為32或64.
          6. curr_items:表示當(dāng)前緩存中存放的所有緩存對(duì)象的數(shù)量。不包括目前已經(jīng)從緩存中刪除的對(duì)象。
          7. total_items:表示從memcached服務(wù)啟動(dòng)到當(dāng)前時(shí)間,系統(tǒng)存儲(chǔ)過(guò)的所有對(duì)象的數(shù)量,包括目前已經(jīng)從緩存中刪除的對(duì)象。
          8. bytes:表示系統(tǒng)存儲(chǔ)緩存對(duì)象所使用的存儲(chǔ)空間,單位為字節(jié)。
          9. curr_connections:表示當(dāng)前系統(tǒng)打開(kāi)的連接數(shù)。
          10. total_connections:表示從memcached服務(wù)啟動(dòng)到當(dāng)前時(shí)間,系統(tǒng)打開(kāi)過(guò)的連接的總數(shù)。
          11. connection_structures:表示從memcached服務(wù)啟動(dòng)到當(dāng)前時(shí)間,被服務(wù)器分配的連接結(jié)構(gòu)的數(shù)量,這個(gè)解釋是協(xié)議文檔給的,具體什么意思,我目前還沒(méi)搞明白。
          12. cmd_get:累積獲取數(shù)據(jù)的數(shù)量,這里是3,因?yàn)槲覝y(cè)試過(guò)3次,第一次因?yàn)闆](méi)有序列化對(duì)象,所以獲取數(shù)據(jù)失敗,是null,后邊有2次是我用不同對(duì)象測(cè)試了2次。
          13. cmd_set:累積保存數(shù)據(jù)的樹(shù)立數(shù)量,這里是2.雖然我存儲(chǔ)了3次,但是第一次因?yàn)闆](méi)有序列化,所以沒(méi)有保存到緩存,也就沒(méi)有記錄。
          14. get_hits:表示獲取數(shù)據(jù)成功的次數(shù)。
          15. get_misses:表示獲取數(shù)據(jù)失敗的次數(shù)。
          16. evictions:為了給新的數(shù)據(jù)項(xiàng)目釋放空間,從緩存移除的緩存對(duì)象的數(shù)目。比如超過(guò)緩存大小時(shí)根據(jù)LRU算法移除的對(duì)象,以及過(guò)期的對(duì)象。
          17. bytes_read:memcached服務(wù)器從網(wǎng)絡(luò)讀取的總的字節(jié)數(shù)。
          18. bytes_written:memcached服務(wù)器發(fā)送到網(wǎng)絡(luò)的總的字節(jié)數(shù)。
          19. limit_maxbytes:memcached服務(wù)緩存允許使用的最大字節(jié)數(shù)。這里為67108864字節(jié),也就是是64M.與我們啟動(dòng)memcached服務(wù)設(shè)置的大小一致。
          20. threads:被請(qǐng)求的工作線程的總數(shù)量。

          我們還可以用Java操作memcached
          首先下載相關(guān)的jar包 Memcached-Java-Client
          然后編寫(xiě)客戶端OCSUtil.java

              package net.bill.commons.util;      import org.springframework.stereotype.Component;     import com.danga.MemCached.MemCachedClient;     import com.danga.MemCached.SockIOPool;      @Component     public class OCSUtil {          private static OCSUtil session;          public static OCSUtil getSession() {             if (session == null) {                 synchronized(OCSUtil.class){                     if(session==null){                         session=new OCSUtil();                     }                 }             }             return session;         }          /**          * memcached客戶端          */         private MemCachedClient memcache = null;          public OCSUtil(){             if (memcache == null) {                 memcache =new MemCachedClient();                   String [] addr ={"127.0.0.1:11211"};                   Integer [] weights = {3};                   SockIOPool pool = SockIOPool.getInstance();                   pool.setServers(addr);                   pool.setWeights(weights);                   pool.setInitConn(5);                   pool.setMinConn(5);                   pool.setMaxConn(200);                   pool.setMaxIdle(1000*30*30);                   pool.setMaintSleep(30);                   pool.setNagle(false);                   pool.setSocketTO(30);                   pool.setSocketConnectTO(0);                   pool.initialize();               }         }          public void setAttribute(String key, Object value){             memcache.set(key, value, 1000);         }          public  Object getAttribute(String key){             return memcache.get(key);         }          public void removeAttribute(String key){             memcache.delete(key);         }      } 

          再編寫(xiě)測(cè)試代碼BaseTest.java和OCSTest.java

              package net.test.modules;      import org.junit.Before;     import org.junit.runner.RunWith;     import org.springframework.beans.BeansException;     import org.springframework.context.ApplicationContext;     import org.springframework.context.ApplicationContextAware;     import org.springframework.test.context.ContextConfiguration;     import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;      @RunWith(SpringJUnit4ClassRunner.class)     @ContextConfiguration(locations="/applicationContext.xml")     public class BaseTest implements ApplicationContextAware{         public ApplicationContext ctxt;          public void setApplicationContext(ApplicationContext arg0) throws BeansException {             this.ctxt = arg0;         }          @Before         public void setUp() throws Exception {         }     }   

              package net.test.modules;      import net.bill.commons.util.OCSUtil;     import net.bill.modules.pojo.User;     import org.junit.Test;     import org.springframework.beans.factory.annotation.Autowired;      public class OCSTest extends BaseTest {          @Autowired         OCSUtil session;          /**          * 通過(guò)spring注入獲得客戶端          */         @Test         public void test1() {             session.setAttribute("user", new User("13355558888"));             System.out.println(session.getAttribute("user"));         }          /**          * 通過(guò)靜態(tài)方法獲得客戶端(單例)          */         @Test         public void test2() {             OCSUtil session = OCSUtil.getSession();             System.out.println(session.getAttribute("user"));         }     } 

          要注意的是,User類必須實(shí)現(xiàn)Serializable接口,進(jìn)行序列化。因?yàn)閙emcached的value類型是String。

          接下來(lái)我要用memcached替換tomcat的session
          在這之前,可以先看一下memcached-session-manager(google的),或中文翻譯的memcached-session-manager配置
          session的序列化方案官方推薦的有4種:

          • kryo-serializer
          • javolution-serializer
          • xstream-serializer
          • flexjson-serializer

          我使用的是最簡(jiǎn)單的一種,就是 java serialization。這個(gè)只要Java中存入session的對(duì)象實(shí)現(xiàn)Serializable就可以了。 然后下載以下jar包,并放在tomcat\lib\里

          1. memcached-session-manager-1.8.3.jar
          2. memcached-session-manager-tc6-1.8.3.jar
          3. spymemcached-2.11.1.jar

          在tomcat\conf\context.xml,<Context>里加上以下配置:

              <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:127.0.0.1:11211" username="root" password="" sticky="false" sessionBackupAsync="false" lockingMode="uriPattern:/path1|/path2" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"               /> 

          啟動(dòng)tomcat,可以看見(jiàn)日志輸出以下信息:

              信息: --------       - MemcachedSessionService finished initialization:     - sticky: false     - operation timeout: 1000     - node ids: [n1]       - failover node ids: []       - storage key prefix: null       --------   

          Step4 整體測(cè)試

          現(xiàn)在可以測(cè)一下是否成功。

          1. 啟動(dòng)tomcat1
          2. 訪問(wèn)test.local.com,并登錄
          3. 啟動(dòng)tomcat2,關(guān)閉tomcat1
          4. 查看登錄信息是否還在

          測(cè)試通過(guò)的話,就基本上沒(méi)問(wèn)題了。

          posted on 2016-09-19 09:53 rogerfan 閱讀(383) 評(píng)論(0)  編輯  收藏 所屬分類: 【開(kāi)源技術(shù)】【操作系統(tǒng)】
          主站蜘蛛池模板: 武邑县| 甘谷县| 建湖县| 望城县| 枝江市| 图木舒克市| 禄劝| 清流县| 肃北| 石家庄市| 定陶县| 巫溪县| 杭锦后旗| 博兴县| 津市市| 民乐县| 木里| 泽普县| 湟中县| 台东市| 平顺县| 东阳市| 通山县| 上犹县| 连城县| 邵武市| 扎赉特旗| 板桥市| 玉溪市| 资溪县| 改则县| 老河口市| 南开区| 驻马店市| 二手房| 德庆县| 特克斯县| 佳木斯市| 凌海市| 同江市| 南充市|