golang 的channel是否适合做消息队列?

做视频直播服务器的时候遇到一个问题,我用带缓冲的channel做消息队列,开启一个go程,专门接受消息队列,并发送消息,我记得在别人的文文章上有说过channel不适合做消息队列,但没说为什么,我的程序目前没任何问题,但是因为对channel的机制并不是理解的很透彻,所以特来问一下,如果channel不是做队列,请告诉我为何不适合?我觉得channel就是天生的队列啊!而且还线程安全

已邀请:

astaxie - 创造、获取、分享、传播和应用Go

赞同来自: sheepbao niugou jiayx godonggua CTO heygo更多 »

我猜你看到的文章的担心是万一程序挂了怎么办,在缓冲channel里面的数据就可能丢失了,如果这个是可以忍受的话其实是非常适合做消息队列的

bigpyer

赞同来自: godonggua CTO sujunxuan asdfsx

这也取决于你的应用场景
1.channel就是用来作为goroutine之间通信的,并发安全、可以传递任何类型,支持阻塞等待,如果是程序内部,并且能容忍一定的消息丢失(已经在channel里了,但是没被消费)非常适合,并且这种场景用的很多的
2.如果是程序之间的消息队列,需要消息可靠投递并且需要其他的策略(比如重复消费),这样的化就考虑一些第三方的消息队列比如kafka、rabbitmq等
1和2的解耦力度也不一样,就看你自己的需求了

changjixiong - 时常做白日梦的程序员

赞同来自: sheepbao heygo

NSQ是一个基于Go语言的分布式实时消息平台,它基于MIT开源协议发布,代码托管在GitHub,其当前最新版本是0.3.1版。NSQ可用于大规模系统中的实时消息服务,并且每天能够处理数亿级别的消息,其设计目标是为在分布式环境下运行的去中心化服务提供一个强大的基础架构。NSQ具有分布式、去中心化的拓扑结构,该结构具有无单点故障、故障容错、高可用性以及能够保证消息的可靠传递的特征。NSQ非常容易配置和部署,且具有最大的灵活性,支持众多消息协议。另外,官方还提供了拆箱即用Go和Python库。如果读者兴趣构建自己的客户端的话,还可以参考官方提供的协议规范。

小平

赞同来自:

队列设置大一些

godonggua - java,go爱好者

赞同来自:

觉得 @谢大 和@bigpyer 说的很有道理。channel确实是天生的队列,但是这个作为语言的一个基础,为了保证效率,应该是用相对简单的队列数据结构实现的,数据再内存里,丢了就丢了没办发恢复,不过可以通过封装channel做更高层、更可靠的队列

张明锋

赞同来自:

还是直接用kafka, rebbitmq这样的rpc中间件来承担消息队列机制。nsq不推荐,因为遇到节点故障会丢消息。

asdfsx

赞同来自:

正好今天看了heka开发者的一封邮件,谈到了在它的项目中channel的问题。由于设计问题,它们这个项目里大量使用了channel进行消息传递。在发现遇到性能瓶颈以后这帮人就弃坑了~~~


https://mail.mozilla.org/pipermail/heka/2016-May/001059.html


简单概括下就是以下的问题



  • 性能没有想象中的那么好
    they don't perform well enough...we've consistently hit a throughput ceiling thanks to all of the synchronization that channels require

  • 不带缓存的channel无法避免消息丢失

  • 带缓存的channel太消耗内存


不知道你的具体使用场景,个人感觉消息队列还是用现成的产品好,让程序尽量维持stateless的状态,这样更新维护都更容易。

要回复问题请先登录注册