最近发现公司项目中用的activemq队列总出现这样那样的问题,可能没有相关告诉解决,很是头疼。作为个人来说也很想寻找一款跨语言、高速的消息队列“玩一玩”,发现zeromq比较满足这个要求。
于是在oschina中看到相关的介绍(http://www.oschina.net/p/0mq),到相关网站下载了最新版本3.2.3各种安装包。首先安装ZeroMQ-3.2.3~miru2.3-x86这个,发现里面只有c接口,就目前来说可能不太符合我测试的要求,我首先需要的java接口的zeromq,在网上寻找了相关资料发现:zeromq (The ØMQ project) · GitHub 有很多语言支持包,需要下载后编译,目前我下载的是jzmq-master,是个实现是jni方式,当时也有纯java版的接口包,感兴趣的朋友可以试一试。
其实最主要的问题是zeromq和jzmq-master在window下的编译。最新版本的zeromq支持vs2010,刚好我机器上安装vs2010,但是jzmq-master没有,需要用vs2010打开后转换一下工程。
编译zeromq
解压zeromq.zip包,我存放的目录是:E:\c_project\,打开vs2010,导入项目(项目目录为E:\c_project\zeromq-3.2.3\builds\msvc),然后编译即可,如果没有特殊修改会编译出debug方式的库,由于jzmq-master编译需要是release方式的库,所以编译zeromq时再修改一下release编译相关库,如果不出异常的话会在E:\c_project\zeromq-3.2.3\lib\Win32目录中编译出libzmq、libzmq_d等文件,在E:\c_project\zeromq-3.2.3\bin\Win32目录中会编译出libzmq.dll等文件(注意libzmq.dll这个文件在java实现的时候需要导入,我在做这个过程中由于不知道,耽误了半天时间怎么也搞不明白,后来经过depends.exe分析动态库依赖关系工具才知道需要这个库,后来拷贝出来java代码测试通过)
编译jzmq-master
解压jzmq-master到E:\c_project\jzmq-master目录,vs2010导入jzmq-master项目,由于最新的不支持vs2010,所以项目会提示转换,我们只需要确定转换就可以。由于需要编译jni接口,所以在vs2010中的项目需要进行以下设置:
1、打开属性页,点击vc++目录
2、选择包含目录,编辑添加以下三项:E:\c_project\zeromq-3.2.3\include(zeromq的头文件),C:\Java\jdk1.6.0_43\include和C:\Java\jdk1.6.0_43\include\win32(java的头文件)
3、选择引用目录,编辑添加E:\c_project\zeromq-3.2.3\lib\Win32一项(增加相关库连接)
4、选择库目录,编辑添加E:\c_project\zeromq-3.2.3\lib\Win32(增加相关库连接)
然后就可以编译了,正常的话会编译出E:\c_project\jzmq-master\lib目录下的jzmq.dll和zmq.jar文件。
对zeromq的java接口测试
打开myeclipse或者eclipse,新建工程,将zmq.jar添加到工程,写测试程序。直接上代码:
客户端:
import org.zeromq.ZMQ;
public class zeromqclient {
/**
* @param args
*/
public static void main(String[] args) {
ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket socket = context.socket(ZMQ.REQ);
socket.connect("tcp://localhost:5555");
socket.setReceiveTimeOut(60000);
for (int request_nbr = 0; request_nbr <= 1000; request_nbr++) {
try{
// 创建一个末尾为0的字符串
String requestString = "Hello" + " ";
byte[] request = requestString.getBytes();
request[request.length - 1] = 0;
// 发送
socket.send(request, ZMQ.NOBLOCK);
// 获得返回值
byte[] reply = socket.recv(0);
if(reply!=null)
// 输出去掉末尾0的字符串
System.out.println("Received reply " + request_nbr + ": [" + new String(reply, 0, reply.length - 1) + "]");
}catch(Exception e){
socket.close();
e.printStackTrace();
try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
socket = context.socket(ZMQ.REQ);
socket.connect("tcp://localhost:5555");
socket.setReceiveTimeOut(2000);
}
}
}
}
服务端:
import org.zeromq.ZMQ;
public class zeromqserver {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//System.load("C:/WINDOWS/system32/libzmq");
//System.load("C:/WINDOWS/system32/jzmq.dll");
// System.load(System.getProperty("user.dir")+"/lib/MFC42D.dll");
// System.load(System.getProperty("user.dir")+"/lib/getcpu.dll");
ZMQ.Context context = ZMQ.context(3);
ZMQ.Socket socket = context.socket(ZMQ.REP);
socket.bind("tcp://*:5555");
//socket.send("ddd".getBytes(), ZMQ.NOBLOCK);
System.out.println(System.currentTimeMillis());
while (true) {
byte[] request;
// 等待下一个client端的请求
// 等待一个以0结尾的字符串
// 忽略最后一位的0打印
request = socket.recv(0);
String hello = new String(request, 0, request.length - 1);
if(hello.equals("Hello"))
System.out.println("Received request: [" + hello + "]");
else
System.out.println("Received request: [ fuck ]");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 返回一个最后一位为0的字符串到客户端
String replyString = "World" + " ";
byte[] reply = replyString.getBytes();
reply[reply.length - 1] = 0;
socket.send(reply, ZMQ.NOBLOCK);
}
}
}
这里需要注意的就是libzmq.dll文件,如果这个文件找不到就会报错:找不到相关的库,由于开始不知道,所以我用库依赖工具查找出来后将jzmq.dll和libzmq.dll文件放到了C:\Java\jdk1.6.0_43\bin目录下,这样程序就直接可以引用了,编译也成功了。