莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          Unix domain socket和memcached

          Posted on 2009-10-15 06:12 dennis 閱讀(5391) 評論(0)  編輯  收藏 所屬分類: javaunix網絡編程
              unix域協議并不是一個實際的協議族,而是在單個主機上執行客戶/服務器通信的一種方法,是IPC的方法之一,特定于*nix平臺。使用unix domain socket有三個好處:
          1)在同一主機上,unix domain socket比一般的tcp socket快上一倍,性能因素這是一個主要原因。
          2)unix domain socket可以在同一主機的不同進程之間傳遞文件描述符
          3)較新的unix domain socket實現把客戶的ID和組ID提供給服務器,可以讓服務器作安全檢查。

             memcached的FAQ中也提到為了安全驗證,可以考慮讓memcached監聽unix domain socket。Memcached支持這一點,可以通過-s選項指定unix domain socket的路徑名,注意,為了可移植性,盡量使用絕對路徑,因為Posix標準聲稱給unix domain socket綁定相對路徑將導致不可預計的后果,我在linux的測試是可以使用相對路徑。假設我將memcached綁定到/home/dennis/memcached,可以這樣啟動memcached:

          memcached -s /home/dennis/memcached


          端口呢?沒有端口了,/home/dennis/memcached這個文件你可以理解成FIFO的管道,unix domain socket的server/client通過這個管道通訊。

             libmemcached支持通過unix domain socket來訪問memcached,基于libmemcached實現的client應該都可以使用這一功能。目前來看,java平臺由于不支持平臺相關的unix domain socket,因此無法享受memcached的這一特性。

             不過有一個開源項目通過jni支持實現了unix domain socket,這個項目稱為juds。核心類就三個,使用非常簡單。下載文件后,解壓縮,make & make install即可。注意,Makefile中寫死了JAVA_HOME,手工修改即可。看一個例子,經典的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();
                  }

              }

          }

              通過UnixDomainSocketServer創建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,考慮可進一步使用select、poll來擴展實現非阻塞IO。

              最后一個例子,通過juds訪問memcached的unix domain socket,簡單的version協議調用:
          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"
          主站蜘蛛池模板: 得荣县| 达孜县| 睢宁县| 湟中县| 平潭县| 沙河市| 江油市| 丰台区| 阜阳市| 南江县| 西宁市| 邮箱| 赤峰市| 新民市| 东乡县| 樟树市| 太仓市| 浠水县| 弋阳县| 二连浩特市| 仁寿县| 佳木斯市| 奉化市| 清水河县| 岚皋县| 新兴县| 社旗县| 定州市| 高陵县| 临江市| 沅陵县| 正镶白旗| 吉木萨尔县| 泸西县| 阿拉善左旗| 小金县| 镇远县| 嘉峪关市| 翁源县| 江达县| 谢通门县|