Perl 綫程 Network Cache Server 例子

本文示範一個簡單方法編寫多綫程網絡緩存服務。通過 SocketService.pm 函數包輕鬆開發,基本上你只需要關心一個 callback,處理一個新網絡連接的業務邏輯便可,其它的瑣碎和高深服務開發代碼可以交函數包完成。

SocketService.pm

多綫程服務函數庫,裏面包括一個class,可以產生一個多綫程Socket對象。UNIX SOCKET 和 INET SOCKET 均可以,還可以在同一個程序產生多個對象,同時偵聽多個端口和本地unix socket。應用極度簡單,按以下順序調用已經可以:

my $server0 = new ThreadSocketService( port => 4001, verbose => 1, name => 'tcp', numproc => 5, callback => \&dosomething );
&runasconsole('/var/tmp/.xserver.pid');
$server0->startserver();
while ($server0->isrunning) {
    sleep 3;
}
$server0->stopserver();

其中$server0是產生的服務對象,通過startserver方法啟動listen,并產生5個綫程處理網絡請求。而dosomething就是你的callback業務邏輯。當中會得到3個參數:$socket, $idx, $server。即你的callback方法定義如下:

sub dosomething {
  my($socket, $idx, $server) = @_;
  my $buffer = <$socket>;
  ...
}

一般可以通過一個內部循環處理 $socket 連接需要干的活。用不著一次連接只干一個活,這處理就是apache的keepalive on處理方法。因為TCP連接啟動與釋放是需要一定成本的。如通過apache來做cvs或svn服務,不是keepalive on我保證你斷綫報錯收場。

回說callback的參數,$socket不用說了,$idx是綫程的序號,由 0 至 numproc-1。$server 是服務對象自己。其中 $server->name.$idx 是整個程序唯一的。假如你只啟動一個對象,那$idx已經是唯一的了。當此方法 return 便結束了本次連接,函數庫會幫你 close 這個連接,萬大事 return 就可以。退出方法後綫程會繼續等待連接,有生意便處理。

runasconsole 是一個準備開始程序的方式,還有 runasdaemon,參數都是一個路徑,讓我幫你管理程序本身的process id,只要 kill 這個 process id便可以終止程序。假如要編寫服務,通過runasdaemon開始吧,再難的事我都幫你處理了,假如需要syslog,別翻書看了,在程序開始前調用 &usesyslog() 便可以,之後程序可以調用 &syslogmessage(),把信息送到syslog。

$server0->isrunning是一個檢驗方法,程序內部可以運行 &killme 去自殺。而外部kill或CTRL-C程序也會調用killme,讓isrunning變為false,你可以好好的處理退出事宜。程序不會立刻就地正法的。

 

CacheProvider.pm

一個管理內存緩存函數包,你可以通過 timeout(life) 和 idleperiod 來管理每個緩存數據的生命週期。其中 timeout (life) 是代表由產生數據開始的數據壽命,以秒為單位。存放的數據死活不會超過這個壽命,過了提取時會返回 undef。而 idleperiod 控制一個數據是否很久沒人提取過,假如超過這個時間沒人關心過,這個數據也會被 expire(設為無效)。

這個緩存函數庫是支持多綫程調用的。但必須注意存在的內容必須是簡單數據類型。假如是複雜類型,需要通過 scalar 來保存并需要事先 share() 你的數據,否則是不讓你保存的!假如是網絡調用就必須要是簡單類型,或自己先序列化。

 

cacheprovider

隨函數包附送演示程序,看源碼有足夠備註介紹如何調用 SocketService.pm 和 CacheProvider.pm 函數包。啟動了cacheprovider程序便可以成為一個網絡上的緩存容器。

 

cacheclient

這是一個調用cacheprovider的客戶端演示程序。裏面簡單示範了通過網絡保存(PUT)緩存數據和提取(GET)數據、測試緩存生命週期等。

 

函數包下載 socketservice_116.tgz

還有一個Java客戶端供研究 CacheClient.java

最後還是一句,Perl是很低層次的開發語言,不可能應付大量頻密訪問。不過,最少她是Multi-Thread(多綫程),總比php好點點。