RabbitMQ性能测试

作者一直在寻找一个极低延时的消息队列,从目前的测试结果来看,只有nats达到了<1ms的水平,本文旨在测试rabbitmq的国latency,撰文记录并与大家分享。

1. 搭建rabbitmq svr

最方便的方式一定是docker,一行命令搞定,这里需要注意的是,没有用rabbitmq:latest,原因是因为这个版本不支持web管理

docker run -d --name rabbitmq -p 5673:5672 -p 15673:15672 docker.io/rabbitmq:3-management

启动后,在浏览器中访问http://localhost:15673/,可以打开管理界面,默认guest:guest

当然,如果希望修改用户名和密码的话,可以用下面的方式启动:

docker run -d -p 15673:15672  -p  5673:5672  -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin --name rabbitmq --hostname=rabbitmqhostone  docker.io/rabbitmq:3-management

docker exec -it rabbitmq /bin/bash cd etc/rabbitmq/ vim rabbitmq.config {rabbit,[{tcp_listeners,[5672]},{loopback_users,["admin"]}]} rabbitmqctl add_user admin admin rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*" rabbitmqctl set_user_tags admin administrator rabbitmqctl list_users rabbitmqctl list_permissions -p /

2. 安装amqp库

方便起见,本次选用go client。

首先下载amqp的go库 https://github.com/streadway/amqp

https://github.com/streadway/amqp.git

下载完成后,放到GOROOT指定目录下,作者的目录对应/usr/local/go/src/github.com/streadway/amqp

3. 下载客户端库

下载https://github.com/rabbitmq/rabbitmq-tutorials

进入go子目录,go build send.go,go build receive.go,测试可以正常的发送\接收。

下面在代码中记录发送和接收的毫秒值,用于计算latency。

实测结果,同机测试时延<=1毫秒,可以满足业务的需要。

send.go

package main

import (
	"log"
	"github.com/streadway/amqp"
    "strconv"
    "time"
)

func failOnError(err error, msg string) {
	if err != nil {
		log.Fatalf("%s: %s", msg, err)
	}
}

func main() {
	conn, err := amqp.Dial("amqp://guest:guest@localhost:5673/")
	failOnError(err, "Failed to connect to RabbitMQ")
	defer conn.Close()

	ch, err := conn.Channel()
	failOnError(err, "Failed to open a channel")
	defer ch.Close()

	q, err := ch.QueueDeclare(
		"hello", // name
		false,   // durable
		false,   // delete when unused
		false,   // exclusive
		false,   // no-wait
		nil,     // arguments
	)
	failOnError(err, "Failed to declare a queue")

    for i:=0; i < 1000; i++ {
        time.Sleep(10 * time.Millisecond)
        now := time.Now().UnixNano()/1e6
        body := strconv.FormatInt(now, 10)
        //log.Printf("%d %s\n", now, body)

        err = ch.Publish(
            "",     // exchange
            q.Name, // routing key
            false,  // mandatory
            false,  // immediate
            amqp.Publishing{
                ContentType: "text/plain",
                Body:        []byte(body),
            })
        //log.Printf(" [x] Sent %s", body)
        failOnError(err, "Failed to publish a message")
    }
}

receive.go

package main

import (
	"log"
    "time"
    "strconv"

	"github.com/streadway/amqp"
)

func failOnError(err error, msg string) {
	if err != nil {
		log.Fatalf("%s: %s", msg, err)
	}
}

func main() {
	conn, err := amqp.Dial("amqp://guest:guest@localhost:5673/")
	failOnError(err, "Failed to connect to RabbitMQ")
	defer conn.Close()

	ch, err := conn.Channel()
	failOnError(err, "Failed to open a channel")
	defer ch.Close()

	q, err := ch.QueueDeclare(
		"hello", // name
		false,   // durable
		false,   // delete when unused
		false,   // exclusive
		false,   // no-wait
		nil,     // arguments
	)
	failOnError(err, "Failed to declare a queue")

	msgs, err := ch.Consume(
		q.Name, // queue
		"",     // consumer
		true,   // auto-ack
		false,  // exclusive
		false,  // no-local
		false,  // no-wait
		nil,    // args
	)
	failOnError(err, "Failed to register a consumer")

	forever := make(chan bool)

	go func() {
		for d := range msgs {
            now := time.Now().UnixNano()/1e6
            str := string(d.Body[:])
            send_tm, err2 := strconv.ParseInt(str, 10, 64)
            failOnError(err2, "Failed to declare a queue")
			log.Printf("Received a message: %s send_tm:%d now:%d cost:%d", d.Body, send_tm, now, now-send_tm)
		}
	}()

	log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
	<-forever
}

参考:

https://www.rabbitmq.com/download.html

https://github.com/alanxz/rabbitmq-c

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员互动联盟

【Windows编程】系列第七篇:Menubar的创建和使用

上一篇我们学习了利用windows API创建工具栏和状态栏,与上一篇紧密联系的就是菜单栏,菜单栏是一个大多数复杂一些的Windows应用程序不可或缺的部分。比...

2828
来自专栏Objective-C

Swift-MVVM 简单演练(三)

2963
来自专栏前端知识分享

第159天:前端知识体系框架

Web Components:http://css-tricks.com/modular-future-web-components//

1363
来自专栏Java技术栈

Spring Boot定制启动图案

启动图案 Spring Boot在启动的时候会显示一个默认的Spring的图案,对应的类为SpringBootBanner。 . ____ ...

3517
来自专栏CRPER折腾记

React 折腾记 - (3) 结合Mobx实现一个比较靠谱的动态tab水平菜单,同时关联侧边栏

4192
来自专栏黑白安全

kali使用指南---安装中文输入法

作为一个中国人,国语是我们最熟悉的,也是最容易、最常用的,但是我们在Kali中却并没有默认的中文输入法,我们在使用Kali进行一些搜索时会变得非常非常麻烦,当然...

1002
来自专栏向治洪

React Native 使用react-native-image-picker库实现图片上传功能

react-native-image-picker作为一个集成相机和相册的功能的第三方库,因为其使用相对简单受到前端开发人员的喜爱。 react-native-...

6219
来自专栏前端布道

前端开发必备之Emmet

·介绍 Emmet (前身为 Zen Coding) 是一个能大幅度提高前端开发效率的一个工具。 基本上,大多数的文本编辑器都会允许你存储和重用一些代码块,我们...

3254
来自专栏mukekeheart的iOS之旅

iOS项目——基本框架搭建

项目开发过程中,在完成iOS项目——项目开发环境搭建之后,我们首先需要考虑的就是我们的项目的整体框架与导航架构设计,然后在这个基础上考虑功能模块的完成。 一 ...

4478
来自专栏文大师的新世界

7. 偷用Swiper简改

看这段代码应该就很清楚了,如果是android系统就渲染Pager如果是ios就使用横向的ScrollView,修改后的app首页如下:

1033

扫码关注云+社区

领取腾讯云代金券