用go语言开发消息中间件 go语言开发的消息队列( 二 )


因此,我们这次犯的错误就是多线程复用了同一个 Channel 导致的问题 。所以 , 如果你也用到 streadway/amqp 这个库的话 , 需要特别注意这点 。
不过,不同语言的SDK内部实现不同,我们分别使用 Golang 的 AMQP 库 streadway/amqp , 和 RabbitMQ 官方提供的 C# 版本的库分别模拟过同样的场景 , 前者出现问题,后者却没有问题 。
受限于时间原因,没有具体去核实 C# 库的源码,主观猜测是 C# 库内部多做了一些对于单个 Channel 的线程安全处理 。
最后,我整理了三点使用 streadway/amqp 库的最佳实践,你可以看看:
01
golang 中使用 streadway/amqp 时,需要保证每一个线程单独一个 Channel 。
streadway/amqp 库中的获取一个 Channel 的方法「Connection.channel()」是线程安全的 。但是内部有一个 defaultChannelMax 的参数对 Channel 的数量进行了限制,默认是 (210) - 1,2047 。这个需要注意:
?
02
我们可以通过调用 amqp.DialConfig(url string, config Config) 来调整个限制 。
?
但是 , 并不是你调整了多少就是多少 , 还需要和 RabbitMQ 服务端的配置进行 min() 函数的处理 , 最终为两者的最小值 。
Tips:特别是用云厂商的 MQ 产品,因为阶梯收费的原因会对很多性能参数做限制,需要格外关注这点 , 比如某版本的阿里云 RabbitMQ 实例限制是单个 Connection 最多 64 个 Channel)
03
正如前面对 Erlang 的简单介绍,Erlang 是一个天然支持多“进程”设计的语言 , 所以在 RabbitMQ 的服务端设计中,每一个 Queue,每一个 Connection 都是单独的一个“进程” 。因此如果你想尽可能地压榨 RabbitMQ 性能 , 可以通过建立更多的 Connection 或者创建更多的 Queue 来实现,当然需要注意到 Connection 的创建和销毁的性能开销问题 。
推荐阅读:
减少联调、高效集成,试试这个工具
golang使用3周总结
也可以「关注」我,带你以技术思维看世界~
想更进一步和我一起玩耍 , 欢迎「搜索微信公号:跨界架构师」 。
内容包括:架构设计丨分布式系统丨产品丨运营丨个人深度思考 。
golang使用Nsq1. 介绍
最近在研究一些消息中间件 , 常用的MQ如RabbitMQ,ActiveMQ,Kafka等 。NSQ是一个基于Go语言的分布式实时消息平台,它基于MIT开源协议发布,由bitly公司开源出来的一款简单易用的消息中间件 。
官方和第三方还为NSQ开发了众多客户端功能库 , 如官方提供的基于HTTP的nsqd、Go客户端go-nsq、Python客户端pynsq、基于Node.js的JavaScript客户端nsqjs、异步C客户端libnsq、Java客户端nsq-java以及基于各种语言的众多第三方客户端功能库 。
1.1 Features
1). Distributed
NSQ提供了分布式的 , 去中心化 , 且没有单点故障的拓扑结构 , 稳定的消息传输发布保障,能够具有高容错和HA(高可用)特性 。
2). Scalable易于扩展
NSQ支持水平扩展,没有中心化的brokers 。内置的发现服务简化了在集群中增加节点 。同时支持pub-sub和load-balanced 的消息分发 。
3). Ops Friendly
NSQ非常容易配置和部署,生来就绑定了一个管理界面 。二进制包没有运行时依赖 。官方有Docker image 。
4.Integrated高度集成
官方的 Go 和 Python库都有提供 。而且为大多数语言提供了库 。
1.2 组件
1.3 拓扑结构
NSQ推荐通过他们相应的nsqd实例使用协同定位发布者 , 这意味着即使面对网络分区,消息也会被保存在本地,直到它们被一个消费者读取 。更重要的是 , 发布者不必去发现其他的nsqd节点,他们总是可以向本地实例发布消息 。

推荐阅读