Zmq使用tpc和inproc的效率对比

ZMQ官方介绍inproc是进程内方式进行消息处理,效率更好。

下面写一个demo程序,分别使用tcp和inproc协议发送和接收10万/100万条数据,对比发送耗时、接收耗时、发送前和接收后的耗时,进行对比。

测试代码

package org.zmq.tcp;

import org.zeromq.ZMQ;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Ziegler
 * @date 2023-05-25
 */
public class ZMQPushPullExample {

    /** 测试消息包数量:10万次 */
    public static final int TEST_MESSAGE_COUNT = 100000;
    /** 开始发送消息时的时间戳 */
    private static long beginSendTime;

    public static void main(String[] args) {
        final ZMQPushPullExample zmqPushPullExample = new ZMQPushPullExample();
        zmqPushPullExample.zmqStart("inproc://example");
        zmqPushPullExample.zmqStart("tcp://127.0.0.1:8888");
        delay(2000);
        System.out.println("=====================================上面预热=====================================");
        zmqPushPullExample.zmqStart("inproc://example");
        System.out.println("=====================================分隔符=====================================");
        zmqPushPullExample.zmqStart("tcp://127.0.0.1:8888");
    }

    private void zmqStart(String addr) {
        // 创建 ZeroMQ 上下文
        ZMQ.Context context = ZMQ.context(1);
        // 创建 PUSH 和 PULL 的套接字
        ZMQ.Socket pushSocket = context.socket(ZMQ.PUSH);
        ZMQ.Socket pullSocket = context.socket(ZMQ.PULL);
        // 绑定 PUSH 和 PULL 套接字
        pushSocket.bind(addr);
        pullSocket.connect(addr);
        System.out.printf("ZMQ绑定协议:%s.", addr).println();

        // 启动一个线程来接收消息
        Thread thread = new Thread(() -> {
            // 统计下面循环的时间
            long start = 0;
            List<String> list = new ArrayList<>();
            for (int i = 0; i < TEST_MESSAGE_COUNT; i++) {
                String message = new String(pullSocket.recv());
                if (i == 0) {
                    start = System.currentTimeMillis();
                }
                list.add(message);
            }
            long end = System.currentTimeMillis();
            final long cost = System.nanoTime() - beginSendTime;
            System.out.printf("从接收第一个消息包到第%d个消息包,耗时:%d毫秒", TEST_MESSAGE_COUNT, (end - start)).println();
            System.out.printf("从开始发送到接收完毕总耗时:%d毫秒", TimeUnit.NANOSECONDS.toMillis(cost)).println();
        });

        thread.start();
        // 开始发送消息
        beginSendTime = System.nanoTime();
        // 统计下面循环的时间
        long start = System.currentTimeMillis();
        for (int i = 0; i < TEST_MESSAGE_COUNT; i++) {
            String message = "Message #" + i;
            pushSocket.send(message.getBytes(), 0);
        }
        long end = System.currentTimeMillis();
        // 字符串format
        System.out.printf("Zmq发送%d次,耗时:%d毫秒", TEST_MESSAGE_COUNT, (end - start)).println();

        // 延迟1秒关闭,等待消息接收完毕
        delay(2000L);
        // 关闭套接字和 ZeroMQ 上下文
        pushSocket.close();
        pullSocket.close();
        context.term();
    }

    public static void delay(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

10万条数据,输出结果:

ZMQ绑定协议:inproc://example.
Zmq发送100000次,耗时:39毫秒从接收第一个消息包到第100000个消息包,耗时:39毫秒

从开始发送到接收完毕总耗时:39毫秒
ZMQ绑定协议:tcp://127.0.0.1:8888.
Zmq发送100000次,耗时:23毫秒
从接收第一个消息包到第100000个消息包,耗时:25毫秒
从开始发送到接收完毕总耗时:25毫秒
=====================================上面预热=====================================
ZMQ绑定协议:inproc://example.
Zmq发送100000次,耗时:21毫秒
从接收第一个消息包到第100000个消息包,耗时:21毫秒
从开始发送到接收完毕总耗时:21毫秒
=====================================分隔符=====================================
ZMQ绑定协议:tcp://127.0.0.1:8888.
Zmq发送100000次,耗时:23毫秒
从接收第一个消息包到第100000个消息包,耗时:25毫秒
从开始发送到接收完毕总耗时:25毫秒
  • 备注:因为是并发打印,可能会出现乱序问题。例如:第二行输出与第三行混在了一次,可以忽略。

100万条数据,输出:

ZMQ绑定协议:inproc://example.
Zmq发送1000000次,耗时:325毫秒
从接收第一个消息包到第1000000个消息包,耗时:325毫秒
从开始发送到接收完毕总耗时:325毫秒
ZMQ绑定协议:tcp://127.0.0.1:8888.
Zmq发送1000000次,耗时:252毫秒
从接收第一个消息包到第1000000个消息包,耗时:251毫秒
从开始发送到接收完毕总耗时:251毫秒
=====================================上面预热=====================================
ZMQ绑定协议:inproc://example.
Zmq发送1000000次,耗时:225毫秒
从接收第一个消息包到第1000000个消息包,耗时:225毫秒
从开始发送到接收完毕总耗时:225毫秒
=====================================分隔符=====================================
ZMQ绑定协议:tcp://127.0.0.1:8888.
Zmq发送1000000次,耗时:266毫秒
从接收第一个消息包到第1000000个消息包,耗时:254毫秒
从开始发送到接收完毕总耗时:266毫秒

Process finished with exit code 0

结论:

  1. zmq的tpc和inproc的耗时,相差不大,都很高效。但inproc也确实比tcp更高效一些。
  2. zmq效率很高,100万消息发送耗时250毫秒左右。作为高效的消息队列使用非常试用。线程同步可以使用他,就不要自己做同步了。

你可能感兴趣的:(Java,ZeroMQ,java,ZeroMQ)