Go之NSQ简介,原理和使用
NSQ简介
NSQ是Go语言编写的一个开源的实时分布式内存消息队列,其性能十分优异。
NSQ 是实时的分布式消息处理平台,其设计的目的是用来大规模地处理每天数以十亿计级别的消息。它具有分布式和去中心化拓扑结构,该结构具有无单点故障、故障容错、高可用性以及能够保证消息的可靠传递的特征
适合小型项目使用,用来学习消息队列实现原理、学习 golang channel知识以及如何用 go 来写分布式,为什么说适合小型小型项目使用因为,nsq 如果没有能力进行二次开发的情况存在的问题还是很多的。
NSQ优势
/*
1. NSQ提倡分布式和分散的拓扑,没有单点故障,支持容错和高可用性, 并提供可靠的消息交付保证.
2. NSQ支持横向扩展,没有任何集中式代理
3. NSQ易于配置和部署,并且内置了管理界面
*/
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. 消息不保证有序.
*/
NSQ应用场景
参考上图利用消息队列把业务流程中的非关键流程异步化, 从而显著降低业务请求的响应时间
应用解耦
通过使用消息队列将不同业务逻辑解耦,降低系统间耦合,提高系统的健壮性, 后续有其他的业务要使用订单数据可直接订阅消息队列, 提高系统的灵活性.
流量削峰
类似秒杀(大秒)等场景下,某一时间可能会产生大量的请求,使用消息队列能够为后端处理请求提供一定的缓冲区,保证后端服务的稳定性。
NSQ架构
NSQ模块介绍
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的数据
*/
NSQ工作模式
Topic和Channel
每个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的一部分消息)
NSQ接受和发送消息流程
Centos安装NSQ
下载
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/
本地解析Hosts
[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操作NSQ
安装go客户端
/*
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(nsqAddress)
if err != nil {
fmt.Printf("init producer failed, err:%v\n", err)
return
}
reader := bufio.NewReader(os.Stdin) // 从标准输入读取
for {
data, err := reader.ReadString('\n')
if err != nil {
fmt.Printf("read string from stdin failed, err:%v\n", err)
continue
}
data = strings.TrimSpace(data)
if strings.ToUpper(data) == "Q" { // 输入Q退出
break
}
// 向 'topic_demo' publish 数据
err = producer.Publish("topic_demo", []byte(data))
if err != nil {
fmt.Printf("publish msg to nsq failed, err:%v\n", err)
continue
}
}
}
消费者
在
/nodes
这个页面我们能够很方便的查看当前接入lookupd
的nsqd
节点。
这个
/counter
页面显示了处理的消息数量,因为我们没有接入消费者,所以处理的消息数量为0。
在
/lookup
界面支持创建topic
和channel
。
// nsq_consumer/main.go
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
"github.com/nsqio/go-nsq"
)
// NSQ Consumer Demo
// MyHandler 是一个消费者类型
type MyHandler struct {
Title string
}
// HandleMessage 是需要实现的处理消息的方法
func (m *MyHandler) HandleMessage(msg *nsq.Message) (err error) {
fmt.Printf("%s recv from %v, msg:%v\n", m.Title, msg.NSQDAddress, string(msg.Body))
return
}
// 初始化消费者
func initConsumer(topic string, channel string, address string) (err error) {
config := nsq.NewConfig()
config.LookupdPollInterval = 15 * time.Second
c, err := nsq.NewConsumer(topic, channel, config)
if err != nil {
fmt.Printf("create consumer failed, err:%v\n", err)
return
}
consumer := &MyHandler{
Title: "沙河1号",
}
c.AddHandler(consumer)
// if err := c.ConnectToNSQD(address); err != nil { // 直接连NSQD
if err := c.ConnectToNSQLookupd(address); err != nil { // 通过lookupd查询
return err
}
return nil
}
func main() {
err := initConsumer("topic_demo", "first", "192.168.43.47:4161")
if err != nil {
fmt.Printf("init consumer failed, err:%v\n", err)
return
}
c := make(chan os.Signal) // 定义一个信号的通道
signal.Notify(c, syscall.SIGINT) // 转发键盘中断信号到c
<-c // 阻塞
}
Go之NSQ简介,原理和使用的更多相关文章
- LeakCanary 内存泄漏 监测 性能优化 简介 原理 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- RxJava RxPermissions 动态权限 简介 原理 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- WebService的简介, 原理, 使用,流程图
WebService的简介, 原理, 使用 第一部分: 直观概述 WebService的几种概念: 以HTTP协议为基础,通过XML进行客户端和服务器端通信的框架/组件 两个关键点: 1. ...
- RxJava 教程-1 简介 原理 线程控制 变换
简介 RxJava 是什么? RxJava 在 GitHub 主页上的自我介绍是 RxJava is a Java VM implementation of ReactiveX: a library ...
- Xposed 框架 hook 简介 原理 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- ZooKeeper教程资源收集(简介/原理/示例/解决方案)
菩提树下的杨过: ZooKeeper 笔记(1) 安装部署及hello world ZooKeeper 笔记(2) 监听数据变化 ZooKeeper 笔记(3) 实战应用之[统一配置管理] ZooKe ...
- 04 . Filebeat简介原理及配置文件和一些案例
简介 Beats轻量型数据采集器 Beats 平台集合了多种单一用途数据采集器.它们从成百上千或成千上万台机器和系统向 Logstash 或 Elasticsearch 发送数据. Beats系列 全 ...
- 01 . RPC简介原理及用Go实现一个简单的RCP
RPC简介 本地过程调用 // 正常情况下程序的执行和调用情况.例如有如下go语言代码: package main import "fmt" func main() { var a ...
- lvs负载简介,原理,常见使用案例及Keepalived高可用
Lvs简介 基础概念 LVS(Linux Virtual Server)即Linux虚拟服务器,是由张文嵩博士主导的开源负载均衡项目,目前LVS已经被集成到Linux内核模块中(2.6及以上版本内核) ...
随机推荐
- SpringBoot普通消息队列线程池配置
1 package com.liuhuan.study.config; 2 3 import com.google.common.util.concurrent.ThreadFactoryBuilde ...
- Java随谈(一)魔术数字、常量和枚举
本文适合对 Java 或 C 有一些了解的用户阅读,推荐阅读时间15分钟. 导言 写这个系列的原因? 我曾经听过一种说法,如果不了解Liunx的网络通讯,就很难理解理解Java的IO:如果不知道Jav ...
- Java JVM参数在idea里面配置
找到你需要配置的启动类选择 接着点击Edit Configurations 在VM options里面配置就完成了
- get 跟post的区别
get参数通过url传递,post放在request body中 :get请求在url中传递的参数是有长度限制的,而post没有.
- 071 01 Android 零基础入门 01 Java基础语法 09 综合案例-数组移位 03 综合案例-数组移位-显示数组当中所有元素的的方法
071 01 Android 零基础入门 01 Java基础语法 09 综合案例-数组移位 03 综合案例-数组移位-显示数组当中所有元素的的方法 本文知识点:综合案例-数组移位-显示数组当中所有元素 ...
- lens distortion
来源:http://michel.thoby.free.fr/Fisheye_history_short/International_Standards_about_Distortion.html H ...
- 【题解】[AHOI2013]作业
Link 题目大意:\(n\)个数,\(m\)个询问,每次四个参数,\(l,r,a,b\),问区间\([l,r]\)中出现过的,数值在\([a,b]\)区间中的数的个数以及区间\([l,r]\)中数值 ...
- 111 01 Android 零基础入门 02 Java面向对象 04 Java继承(上)02 继承的实现 01 继承的实现
111 01 Android 零基础入门 02 Java面向对象 04 Java继承(上)02 继承的实现 01 继承的实现 本文知识点: 继承的实现 说明:因为时间紧张,本人写博客过程中只是对知识点 ...
- 这个网易云JS解密,老网抑云看了都直呼内行
最近更新频率慢了,这不是因为CK3发售了嘛,一个字就是"肝".今天来看一下网易云音乐两个加密参数params和encSecKey,顺便抓取一波某歌单的粉丝,有入库哦,使用mysql ...
- 让我们创建屏幕- Android UI布局和控件
下载LifeCycleTest.zip - 278.9 KB 下载ViewAndLayoutLessons_-_Base.zip - 1.2 MB 下载ViewAndLayoutLessons_-_C ...