unix域協(xié)議并不是一個(gè)實(shí)際的協(xié)議族,而是在單個(gè)主機(jī)上執(zhí)行客戶/服務(wù)器通信的一種方法,是IPC的方法之一,特定于*nix平臺(tái)。使用unix domain socket有三個(gè)好處:
1)在同一主機(jī)上,unix domain socket比一般的tcp socket快上一倍,性能因素這是一個(gè)主要原因。
2)unix domain socket可以在同一主機(jī)的不同進(jìn)程之間傳遞文件描述符
3)較新的unix domain socket實(shí)現(xiàn)把客戶的ID和組ID提供給服務(wù)器,可以讓服務(wù)器作安全檢查。
memcached的FAQ中也提到為了安全驗(yàn)證,可以考慮讓memcached監(jiān)聽(tīng)unix domain socket。Memcached支持這一點(diǎn),可以通過(guò)-s選項(xiàng)指定unix domain socket的路徑名,注意,為了可移植性,盡量使用絕對(duì)路徑,因?yàn)镻osix標(biāo)準(zhǔn)聲稱給unix domain socket綁定相對(duì)路徑將導(dǎo)致不可預(yù)計(jì)的后果,我在linux的測(cè)試是可以使用相對(duì)路徑。假設(shè)我將memcached綁定到/home/dennis/memcached,可以這樣啟動(dòng)memcached:
memcached -s /home/dennis/memcached
端口呢?沒(méi)有端口了,/home/dennis/memcached這個(gè)文件你可以理解成FIFO的管道,unix domain socket的server/client通過(guò)這個(gè)管道通訊。
libmemcached支持通過(guò)unix domain socket來(lái)訪問(wèn)memcached,基于libmemcached實(shí)現(xiàn)的client應(yīng)該都可以使用這一功能。目前來(lái)看,java平臺(tái)由于不支持平臺(tái)相關(guān)的unix domain socket,因此無(wú)法享受memcached的這一特性。
不過(guò)有一個(gè)開(kāi)源項(xiàng)目通過(guò)jni支持實(shí)現(xiàn)了unix domain socket,這個(gè)項(xiàng)目稱為
juds。核心類就三個(gè),使用非常簡(jiǎn)單。下載文件后,解壓縮,make & make install即可。注意,Makefile中寫(xiě)死了JAVA_HOME,手工修改即可??匆粋€(gè)例子,經(jīng)典的Time server:
package com.google.code.juds.test;
import java.io.IOException;
import com.google.code.juds.*;
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TimeServer {
public static void main(String[] args) {
try {
UnixDomainSocketServer server = new UnixDomainSocketServer(
"/home/dennis/time", UnixDomainSocket.SOCK_STREAM);
OutputStream output = server.getOutputStream();
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
output.write(dateFormat.format(date).getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
}
通過(guò)
UnixDomainSocketServer創(chuàng)建server,指定類型為SOCK_STREAM,juds也支持UDP類型。client的使用如下:
byte[] b = new byte[128];
UnixDomainSocketClient socket = new UnixDomainSocketClient("/home/dennis/time",
UnixDomainSocket.SOCK_STREAM);
InputStream in = socket.getInputStream();
in.read(b);
System.out.println("Text received: \"" + new String(b) + "\"");
socket.close();
顯然,juds還只支持阻塞IO,考慮可進(jìn)一步使用select、poll來(lái)擴(kuò)展實(shí)現(xiàn)非阻塞IO。
最后一個(gè)例子,通過(guò)juds訪問(wèn)memcached的unix domain socket,簡(jiǎn)單的version協(xié)議調(diào)用:
byte[] b = new byte[128];
UnixDomainSocketClient socket = new UnixDomainSocketClient("/home/dennis/memcached",
UnixDomainSocket.SOCK_STREAM);
OutputStream out = socket.getOutputStream();
String text = "version\r\n";
out.write(text.getBytes());
InputStream in = socket.getInputStream();
in.read(b);
System.out.println("Text received: \"" + new String(b) + "\"");
socket.close();
輸出
Text received: "VERSION 1.4.1"