Go之NSQ简介,原理和使用

/*
1. NSQ提倡分布式和分散的拓扑,没有单点故障,支持容错和高可用性, 并提供可靠的消息交付保证.
2. NSQ支持横向扩展,没有任何集中式代理
3. NSQ易于配置和部署,并且内置了管理界面
/
/

1. 支持无 SPOF 的分布式拓扑
2. 水平扩展(没有中间件,无缝地添加更多的节点到集群)
3. 低延迟消息传递 (性能)
4. 结合负载均衡和多播消息路由风格
5. 擅长面向流媒体(高通量)和工作(低吞吐量)工作负载
6. 主要是内存中(除了高水位线消息透明地保存在磁盘上)
7. 运行时发现消费者找到生产者服务(nsqlookupd)
8. 传输层安全性 (TLS)
9. 数据格式不可知
10. 一些依赖项(容易部署)和健全的,有界,默认配置
11. 任何语言都有简单 TCP 协议支持客户端库
12. HTTP 接口统计、管理行为和生产者(不需要客户端库发布)
13. 为实时检测集成了 statsd
14. 健壮的集群管理界面 (nsqadmin)
*/
注意点

/*
1. 消息默认不持久化, 可以配置成持久化模式, nsq采用的方式是内存+硬盘的模式,当内存到一定程度就会持久化到硬盘.
如果将 --mem-queue-size设置为0, 所有的消息将会存储到磁盘.
服务器重启时也会将在内存中的消息持久化
2. 每条消息至少传递一次
3. 消息不保证有序.
*/

参考上图利用消息队列把业务流程中的非关键流程异步化, 从而显著降低业务请求的响应时间

通过使用消息队列将不同业务逻辑解耦,降低系统间耦合,提高系统的健壮性, 后续有其他的业务要使用订单数据可直接订阅消息队列, 提高系统的灵活性.

类似秒杀(大秒)等场景下,某一时间可能会产生大量的请求,使用消息队列能够为后端处理请求提供一定的缓冲区,保证后端服务的稳定性。

nsqd: 是一个进程监听了http,tcp两种协议, 用来创建topic,channel, 分发消息给消费者,向nsqlooup 注册自己的元数据信息(topic、channel、consumer),自己的服务信息,最核心模块。

nsqd 是一个守护进程,负责接收,排队,投递消息给客户端。也就是说这个服务是干活的。它可以独立运行,不过通常它是由 nsqlookupd 实例所在集群配置的。

/*
特性:
1. 对订阅了同一个topic,同一个channel的消费者使用负载均衡策略(不是轮询)

	2. 只要channel存在,即使没有该channel的消费者,也会将生产者的message缓存到队列中(注意消息的过期处理)
	
	3. 保证队列中的message至少会被消费一次,即使nsqd退出,也会将队列中的消息暂存磁盘上(结束进程等意外情况除外)

	4. 限定内存占用,能够配置nsqd中每个channel队列在内存中缓存的message数量,一旦超出,message将被缓存到磁盘中

	5. topic,channel一旦建立,将会一直存在,要及时在管理台或者用代码清除无效的topic和channel,避免资源的浪费

*/
nsqlookup: 存储了nsqd的元数据和服务信息(endpoind),向消费者提供服务发现功能, 向nsqadmin提供数据查询功能.

nsqlookupd 是守护进程负责管理拓扑信息。客户端通过查询 nsqlookupd 来发现指定话题(topic)的生产者,并且 nsqd 节点广播话题(topic)和通道(channel)信息。也就是说nsqlookupd是管理者。

/*
特性:

	1. 唯一性,在一个Nsq服务中只有一个nsqlookupd服务。当然也可以在集群中部署多个nsqlookupd,但它们之间是没有关联的.
	2. 去中心化,即使nsqlookupd崩溃,也会不影响正在运行的nsqd服务
	3. 充当nsqd和naqadmin信息交互的中间件
	4. 提供一个http查询服务,给客户端定时更新nsqd的地址目录.

*/
nsqadmin: 简单的管理界面,展示了topic, channel以及channel上的消费者,也可以创建topic,channel

/*
特性:

	1. 提供一个对topic和channel统一管理的操作界面以及各种实时监控数据的展示,界面设计的很简洁,操作也很简单
	2. 展示所有message的数量
	3. 能够在后台创建topic和channel
	4. nsqadmin的所有功能都必须依赖于nsqlookupd,nsqadmin只是向nsqlookupd传递用户操作并展示来自nsqlookupd的数据

*/

每个nsqd实例旨在一次处理多个数据流。这些数据流称为“topics”,一个topic具有1个或多个“channels”。每个channel都会收到topic所有消息的副本,实际上下游的服务是通过对应的channel来消费topic消息。

topic和channel不是预先配置的。topic在首次使用时创建,方法是将其发布到指定topic,或者订阅指定topic上的channel。channel是通过订阅指定的channel在第一次使用时创建的。

topic和channel都相互独立地缓冲数据,防止缓慢的消费者导致其他chennel的积压(同样适用于topic级别)。

channel可以并且通常会连接多个客户端。假设所有连接的客户端都处于准备接收消息的状态,则每条消息将被传递到随机客户端。例如:

生产者向某个topic中发送消息,如果topic有一个或者多个channle,那么该消息会被复制多分发送到每一个channel中。类似 rabbitmq中的fanout类型,channle类似队列。 官方说 nsq 是分布式的消息队列服务,但是在我看来只有channel到消费者这部分提现出来分布式的感觉,nsqd 这个模块其实就是单点的,nsqd 将 topic、channel、以及消息都存储在了本地磁盘,官方还建议一个生产者使用一个 nsqd,这样不仅浪费资源还没有数据备份的保障。一旦 nsqd 所在的主机磁损坏,数据都将丢失。

总而言之,消息是从topic–> channel (每个channel接受该topic的所有消息的副本)多播的,但是从channel --> consumers均匀分布 (每个消费者接受该channel的一部分消息)

wget https://s3.amazonaws.com/bitly-downloads/nsq/nsq-1.2.0.linux-amd64.go1.12.9.tar.gz

tar xf nsq-1.2.0.linux-amd64.go1.12.9.tar.gz -C /usr/local/
[root@nsq-47 ~]# tail -1 /etc/hosts
192.168.43.47 nsq-47

开三个终端,分别按顺序启动

./nsqlookupd

./nsqd --lookupd-tcp-address=192.168.43.47:4160

./nsqadmin --lookupd-http-address=192.168.43.47:4161

访问

http://192.168.43.47:4171

/*
go get -u github.com/nsqio/go-nsq
*/
// nsq_producer/main.go
package main

import (
“bufio”
“fmt”
“os”
“strings”

"github.com/nsqio/go-nsq"

)

// NSQ Producer Demo

var producer *nsq.Producer

// 初始化生产者
func initProducer(str string) (err error) {
config := nsq.NewConfig()
producer, err = nsq.NewProducer(str, config)
if err != nil {
fmt.Printf(“create producer failed, err:%v\n”, err)
return err
}
return nil
}

func main() {
nsqAddress := “192.168.43.47:4150”
err := initProducer(n

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值