自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用Node.js開發(fā)memcache協(xié)議的反向代理服務器

開發(fā) 前端
memcache是常用的key-value緩存解決方案,它的協(xié)議也被用于nosql數(shù)據(jù)庫tokyo tyrant。最近正好在學習node.js,于是決定用node.js搭一個node.js的反向代理。對php、java等客戶端,實現(xiàn)與memcache相同的協(xié)議。將客戶端的請求,根據(jù)請求的key值分別轉(zhuǎn)發(fā)到后端的數(shù)個memcache上。

memcache是常用的key-value緩存解決方案,它的協(xié)議也被用于nosql數(shù)據(jù)庫tokyo tyrant。

在實際項目中,出于負載均衡等考慮,php、java等客戶端需要訪問多個memcache,將一個對特定key的請求map到特定的memcache上。但這樣就需要在每個客戶端配置多個ip地址并實現(xiàn)map的算法,不便于管理和維護。最近正好在學習node.js,于是決定用node.js搭一個node.js的反向代理。對php、java等客戶端,實現(xiàn)與memcache相同的協(xié)議。將客戶端的請求,根據(jù)請求的key值分別轉(zhuǎn)發(fā)到后端的數(shù)個memcache上。

node基于v8和libevent開發(fā),主要思想是用單線程+事件循環(huán)(event loop),來實現(xiàn)異步io服務器。這種模式類似于nginx,比起傳統(tǒng)的多進程(例如apache的prefork模式)或者線程(例如tomcat等app server),速度更快。

純異步io的服務器實現(xiàn)有很多復雜的因素要考慮,有了錯誤也難以調(diào)試。使用node可以讓你從繁瑣的內(nèi)存處理等底層工作中解放出來,把精力都花在關(guān)注你的核心的模型和應用邏輯。

用node實現(xiàn)一個socket server是非常容易的,如下代碼即可實現(xiàn)簡單的echo server:

  1. server=net.createServer(  
  2.     function(socket) {  
  3.         socket.on('data',function(data){  
  4.             //這個this就是socket  
  5.             this.write(data);  
  6.         });  
  7.     }  
  8. ).listen(port_number); 

由于我要根據(jù)請求的key值接收和分發(fā)memcache請求,需要對收到的data做解析請求的操作。接著根據(jù)請求的key決定采用哪一個memcache,然后將請求寫入memcache連接。當memcache連接收到數(shù)據(jù)時,將數(shù)據(jù)寫回客戶端socket,代理的基本流程就結(jié)束了。

  1. socket.on('data',function(data){  
  2.         var request=mk_request(data);  
  3.         var mc=create_memcache_conn(request.key);  
  4.         mc.write(request);  
  5.         mc.on('data',function(data){  
  6.                 socket.write(data);  
  7.             });  
  8.     }); 

值得注意的是,由于node異步的特性,收到的data可能比一個請求數(shù)據(jù)少,或者比一個請求數(shù)據(jù)多,或者包含好幾個請求,都是有可能的,剩下的數(shù)據(jù)需要加入到下次收到的data之前,才能保證接收請求沒有問題。于是程序修改為如下結(jié)構(gòu):

  1. function process_request(socket,request){  
  2.     var mc=create_memcache_conn(request.key);  
  3.     mc.write(request);  
  4.     mc.on('data',function(data){  
  5.             socket.write(data);  
  6.         });  
  7.    
  8. }  
  9.    
  10. socket.on('data',function(data){  
  11.         do{  
  12.             //將之前剩下的數(shù)據(jù)與新收到的數(shù)據(jù)合并  
  13.             data=new Buffer(this.remain_data,data);  
  14.             //如果mk_request沒解析出一個完整的請求,就返回false  
  15.             var request=mk_request(data);  
  16.             this.remain_data=data.slice(request===false?0:request.length);  
  17.             process_request(this,request);  
  18.         }while(request);  
  19.    
  20.         }); 

但改成這樣之后,測試結(jié)果還是有問題。這是因為客戶端有可能一次發(fā)多個請求到服務器端,服務器端使用多個memcache連接處理這些請求,在memcache連接的ondata中寫回客戶端的時候,無法保證寫回的順序與請求的順序一致,導致出錯。所以需要有一個隊列來保證寫回數(shù)據(jù)的順序。

  1. function process_request(socket,request){  
  2.     var mc=create_memcache_conn(request.key);  
  3.     mc.write(request);  
  4.     mc.queue.push({req:request,res:false});  
  5.     mc.on('data',function(data){  
  6.             //收memcache響應也有和收客戶端請求一樣的問題,可能一次收到一半的請求  
  7.             data=new Buffer(this.remain_data,data);  
  8.             //如果mk_response沒解析出一個完整的響應,就返回false  
  9.             var response=mk_response(data);  
  10.             if(response){  
  11.                 //接收完一個響應,先將響應加入隊列  
  12.                 for(var i=0;i0){  
  13.                     if(socket.queue[0].res){  
  14.                         socket.write(socket.queue.shift().res.buffer);  
  15.                     }else{  
  16.                         break;  
  17.                     }  
  18.                 }  
  19.                 this.removeListener('data',arguments.callee);  
  20.             }  
  21.         });  

另外需要實現(xiàn)mk_request和mk_response這兩個函數(shù),實現(xiàn)是基于memcache的協(xié)議,我的實現(xiàn)參考了文章:memcache協(xié)議中文版(http://www.ccvita.com/306.html),memcache的協(xié)議還是比較簡單的。

在最終實現(xiàn)中,我還加入了memcache連接池的功能,因為建立memcache連接需要花費的時間是很長的,memcache的文檔中也建議與服務器保持長連接,以加快效率。

加入連接池后做了簡單的壓力測試,在普通筆記本機上,幾十個進程并發(fā),每秒幾千次沒問題的,調(diào)整一下應該能上w

完整的代碼請看我的github源:https://github.com/wwwppp0801/nodeproxy

參考文檔:

memcache協(xié)議中文版:http://www.ccvita.com/306

node.js文檔:http://nodejs.org/docs/v0.4.7/api

原文:http://blog.webshuo.com/2011/05/13/%E7%94%A8node-js%E5%BC%80%E5%8F%91memcache%E5%8D%8F%E8%AE%AE%E7%9A%84%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8/

【編輯推薦】

  1. 基于Node.js、Express和Jscex開發(fā)的ToDo網(wǎng)站示例
  2. 如何安裝Node.js
  3. 揭秘Node.js事件
  4. Node.js初探之hello world
  5. 什么是Node.js?
責任編輯:陳貽新 來源: penny的博客
相關(guān)推薦

2019-04-08 08:39:47

Nginx代理服務器

2012-09-18 09:55:28

2018-04-17 12:10:40

2018-11-05 09:34:43

2010-09-17 10:07:17

SIP協(xié)議SIP代理服務器

2020-10-12 08:06:28

HTTP 服務器證書

2019-06-27 08:43:26

服務器Nginx反向代理

2022-06-05 13:52:32

Node.jsDNS 的原理DNS 服務器

2015-12-14 10:39:14

2024-11-21 09:18:08

2024-02-20 14:53:01

2017-12-27 09:49:35

HTTP服務器反向

2020-04-28 22:43:48

反向代理Node.js PHP

2021-09-02 10:49:25

Node.jsPHP服務器開發(fā)

2009-02-10 15:42:00

代理服務器代理服務器設置

2011-08-31 16:37:51

Nginx

2019-02-15 10:49:37

Node.jsweb服務器

2009-02-06 10:54:00

Necsocks5Windows代理服務代理服務器

2009-02-12 15:43:00

CCProxy代理服務器

2009-08-18 11:04:50

代理服務器設置代理服務器地址
點贊
收藏

51CTO技術(shù)棧公眾號