Unix domain socket和memcached
2023-03-14 10:30:06 时间
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:
通过UnixDomainSocketServer创建server,指定类型为SOCK_STREAM,juds也支持UDP类型。client的使用如下:
最后一个例子,通过juds访问memcached的unix domain socket,简单的version协议调用:
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();
}
}
}
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。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访问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();
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"
文章转自庄周梦蝶 ,原文发布时间 2009-10-15
相关文章
- 大数据分析本身的工业化
- 以什么姿势进入DataMining会少走弯路?
- 集成学习方法
- 推荐系统常用的推荐算法
- 数据结构常见的八大排序算法
- R语言的三种聚类方法
- 都在做大数据,你上市了么?
- 大数据下的技术运营:数据采集系统设计与实现
- 大数据时代下的意图搜索 个性化服务是关键
- 岱凯:领先的ICT解决方案和服务,助力企业赢在数字时代
- 大数据时代保护个人隐私的5点建议
- 大数据如何影响商业决策
- 国双成中国首家赴美上市大数据企业,十一年创业的重要里程碑
- 8月份改变行业游戏规则的十款物联网新品
- Spark加速大数据在企业落地
- 数据科学家最常用的10种算法
- “后大数据时代”,看TalkingData如何定义
- 人工智能创新有望解决大数据难题
- 大数据”时代并不是掌握数据,而是利用数据
- 从此,Kubernetes变得简单易用