NSQ


NSQ简介

NSQ是google开发,用go实现的消息队列服务。NSQ具有以下特性:

  • 分布式并且高可用,消除单点故障。
  • 保证消息可靠的分发。
  • 无需担心消息过多时一直占用内存: 如有必要将消息写入磁盘。
  • 对生产侧和消费侧配置极为简单
简单的配置与管理

nsqd实例一次性可以处理多个数据流。数据流又被称为”topics”。 一个topic可同时拥有一个或多个”channels”。每个channel都从与之相关的topic接收所有消息的副本。 在实践中,一个channel映射到一个消费这个主题的下游服务。

topic和channel没有优先级。当第一次发布或者订阅一个命名的topic时,这个topic被就被创建。 当订阅一个命名的channel时,这个channel就被创建。

topic和channel都是各自独立的缓存数据,避免慢消费者造成其他channel堵塞。

一个channel能够而且通常也是这样做的: 一个channel可通常与多个client建立连接。假如所有与之连接的 client都处在等待接受消息的状态时,那么这个channel流出的每条消息都会随机流向一个client。

总结来说,多个topic产生各种消息,每个channel从topic中接收所有消息的副本;最后,每个消费者从这个 channel中接收部分消息。

NSQ有一个辅助程序——nsqlookupd。这个程序为消费者提供服务发现服务:它供消费者查找提供它们感兴趣 的topic的nsqd实例所在的地址。这样做的好处是它解耦了生产者与消费者(二者都只需要知道与共同的nsqlookup 建立连接,而不需要两者之间直接建立联系),减少了复杂的维护。

每个nsqd实例底层都与nsqlookupd建立一个tcp长连接,用来周期性的将自身的状态报告给nsqlookupd。 依靠上报的这些数据,nsqlookup可告诉消费者nsqd的地址。对于消费者来说,可通过nsqlookupd暴露出来的 /lookup HTTP地址来查询。

当要引入一个新的消费主题时,NSQ的客户端只要启动时简单的配置一下nsqlookupd程序的地址就可以了,不需要 为新的consumers或者新的publishers添加或改动配置,这一切都是及其简单的容易的。

在未来的版本中,nsqlookup也许会基于队列深度、连接的客户端数量或其它的“智能”的策略来返回节点信息。 当前的实现只是简单的返回所有信息。总之,nsqlookupd的目标就是确保那些队列深度为0的producers可读取 (我的理解就是负载尽量的均衡,优先于那些比较空闲的nsqd来提供服务)

重点要指出的是,NSQ被设计成nsqdnsqlookupd守护进程之间操作的相互独立性,而不是采用兄弟节点之间 复杂的协作和通信。

有时,我们也需要一个查看,管理集群的有效手段。NSQ提供了nsqadmin的工具来帮我们做到这些。 nsqadmin提供了一个web管理界面来查看topic->channels->consumers之间的继承关系和队列深度,还包括对每层的 其他一些关键统计信息。同时,它还提供一些有用的管理命令,比如移除或者清空一个channel(当需要安全地队列 深度清空成0时这就非常有用了)。

####直接有效的升级方式 这也是我们技术选型中要关心的首要问题。在NSQ目前现有的消息工具之上,我们的生产环境处理着大量的数据流量, 这需要有一种对现有环境几乎没有影响,平滑且有条不紊的方式来升级我们系统基础架构的某些部分。

首先,在消息生产者一方,我们建立了与nsqd的简单消息队列。nsqd为此对外提供了/put的HTTP接口,与simplequeue类似,将二进制数据POST(需要注意的是,这需要一个额外的查询参数来指定topic)。