NSQ消息队列---总结篇

架构

概念

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

nsqd: 是接收、队列和传送消息到客户端的守护进程。

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

消息可靠性

(1)生产者不保证消息可靠

(2)消费者保证至少一次消费

发送逻辑

(1)根据配置指定的nsqd的ip, 选择一个机器,通过 HTTP API(也可以TCP)将消息发布到 nsqd的指定 topic

(2)当 producer初次发布的消息的 topic不存在,则会创建。

(3)对topic加锁,将消息发送给 memoryMsgChan中,然后释放锁。如果 memoryMsgChan满了,申请一个buff,把消息写到 Backend,后期被 backendMsgChan接收。

(4)messagePump 不断从 memoryChan/backend队列中读消息,并将消息每个复制一遍,发送给 topic下的所有channel

//nsqd/topic.go:220
func (t *Topic) messagePump() {...for {select {case msg = <-memoryMsgChan:case buf = <-backendChan:msg, err = decodeMessage(buf)...case <-t.channelUpdateChan:...case pause := <-t.pauseChan:...case <-t.exitChan:goto exit}for i, channel := range chans {chanMsg := msgif i > 0 {chanMsg = NewMessage(msg.ID, msg.Body)chanMsg.Timestamp = msg.TimestampchanMsg.deferred = msg.deferred}if chanMsg.deferred != 0 {channel.PutMessageDeferred(chanMsg, chanMsg.deferred)continue}err := channel.PutMessage(chanMsg)...}}
}

(5)channel的PutMessage和 topic类似,首先先写 memoryMsgChan, 满了写入 backend.

(6)protocol实例的messagePump方法从memoryMsgChan或backendMsgChan读取消息并通过p.SendMessage(client, msg)发送到客户端 ,消息写入client.Writer。

消费逻辑

(1)consumer将会从 nsqlookup 服务器节点上发现所有包含事件 topic的 nsqd节点。每个consumer向每个 nsqd主机进行订阅操作。

(2)根据获取到的机器信息,通过 TCPsubscribe 自己需要的channel。如果 topic 或者 channel没有创建,则会创建

(3)多个 consumer对应一个 channel, 每个消息将被传递到一个随机的 consumer中。

消费特点:

(1)支持延时消息。

(2)channel在consumer退出后并不会删除。

消息消费失败

这个担保是作为协议和工作流的一部分,工作原理如下(假设客户端成功连接并订阅一个话题):

1)客户表示已经准备好接收消息

2)NSQ 发送一条消息,并暂时将数据存储在本地(在 re-queue 或 timeout,采用大小堆【超时时间排序】和map存储)

3)客户端回复 FIN(结束)或 REQ(重新排队)分别指示成功或失败。如果客户端没有回复, NSQ 会在设定的时间超时,自动重新排队消息 (有个协程定时查看,根据当前时间跟最大堆的顶元素比较)。

消费者限流

就是客户端连接上nsqd之后,会告诉nsqd它的可接受的消息数量是多少,每当nsqd给客户端推送一条消息这个RDY就会减一,而客户端消费完毕并且发送一个FIN之后,这个RDY又会加一(其实这个设计有点类似tcp中的用来控制流量的窗口机制)。

客户端库的被设计成在 RDY 数达到配置 max-in-flight 的 25% 发送一个命令来更新 RDY 计数(并适当考虑连接到多个 nsqd 情况下,适当地分配)。

本地初始化consumer时配置 maxInFlight, 在服务端也配置一个 max_in_flight。每个连接默认:2500

客户端的职责:

  1. 引导并均匀地将max_in_flight配置分配给所有连接。

  2. 绝不允许所有连接的RDY计数总和(total_rdy_count)超过所配置的max_in_flight。

  3. 永远不要超过nsqd配置的每个连接的max_rdy_count。

  4. 公开API方法以可靠地指示消息流的不足(message flow starvation)。

客户端库应始终尝试在所有连接之间平均分配RDY计数。通常,此实现为max_in_flight / num_conns。

特性:

1.采用push机制,保证至少一次推送

性能:

单个节点性能

声明:请牢记 NSQ 设计的初衷是分布式。单个节点的性能非常重要,但这并不是我们所追求的。

  • 2012 MacBook Air i7 2ghz

  • go1.2

  • NSQ v0.2.24

  • 200 byte messages

GOMAXPROCS=1 (单个生产者,单个消费者)

$ ./bench.sh results... PUB: 2014/01/12 22:09:08 duration: 2.311925588s - 82.500mb/s - 432539.873ops/s - 2.312us/op SUB: 2014/01/12 22:09:19 duration: 6.009749983s - 31.738mb/s - 166396.273ops/s - 6.010us/op

GOMAXPROCS=4 (4 publishers, 4 consumers)

$ ./bench.sh results... PUB: 2014/01/13 16:58:05 duration: 1.411492441s - 135.130mb/s - 708469.965ops/s - 1.411us/op SUB: 2014/01/13 16:58:16 duration: 5.251380583s - 36.321mb/s - 190426.114ops/s - 5.251us/op

引用:

分布式实时消息平台NSQ - 知乎

https://juejin.cn/post/6932865148784902158

http://nsqio.cn/design.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/3119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【漏洞复现】号卡极团管理系统 index.php SQL注入漏洞

0x01 产品简介 号卡极团管理系统是一款专为号卡行业打造的管理系统&#xff0c;它具备一系列强大的功能&#xff0c;能够满足号卡行业推广人员在业务运营中的各类需求。 0x02 漏洞概述 号卡极团管理系统存在SQL注入漏洞&#xff0c;未授权的攻击者可以通过该漏洞获取数据库敏…

数据库关系模式分解 - 无损连接和保持函数依赖性

文章目录 1 概述1.1 关系模式分解的好坏标准 2 无损连接验证算法 1 概述 1.1 关系模式分解的好坏标准 书上的算法太抽象了&#xff0c;咱不好理解&#xff0c;以下举例说明。一个关系可以有很多种分解方法&#xff0c;如何判断分解的好与坏呢&#xff1f; ① 查询时的连接操作…

类的六个构造函数相关干货

构造函数 特点 1.名字与类名相同 2.无返回值 3.对象实例化的时候编译器自动调用这个函数 4.构造函数可以重载&#xff08;无参构造函数&#xff0c;拷贝构造等&#xff09; 5.如果类中没有显式定义构造函数&#xff08;深拷贝&#xff09;&#xff0c;则编译器会自动生成一个…

抖音阳哥:选品师项目究竟能不能算蓝海项目?

在当今这个信息爆炸的时代&#xff0c;短视频平台如抖音已经成为了人们获取信息、娱乐休闲的重要渠道。抖音上涌现出许多具有影响力的网红&#xff0c;他们不仅分享自己的生活点滴&#xff0c;还常常推荐一些创业项目或商业模式。其中&#xff0c;阳哥分享的选品师项目引起了广…

STM32H750片外QSPI下载算法文件(stldr)生成

STM32H750片外QSPI下载算法文件&#xff08;stldr&#xff09;生成 &#x1f33f;相关篇《STM32H750片外QSPI启动配置简要》&#x1f4cc;参考实现资料&#xff1a; https://github.com/lchnu/STM32H750XBH_ARTPIQSPI_W25Q64JV https://gitee.com/wangchief/H750_W25QXX ✨利…

风格迁移adaIN 和iT的adaLN

文章目录 BN、LN、IN、GN的区别![](https://img-blog.csdnimg.cn/direct/d38c005616f145cba2aa1c4c2e046be0.png)图像风格迁移adaINDiT adaLN BN、LN、IN、GN的区别 BatchNorm&#xff1a;batch方向做归一化&#xff0c;算NxHxW的均值&#xff0c;对小batchsize效果不好&#x…

「Kafka」Kafka基础知识入门介绍(三)

「Kafka」Kafka基础知识入门介绍&#xff08;三&#xff09; 一、消息主题1. 创建主题 二、生产数据1. 命令行模式2. Java代码模式 三、消费数据1. 命令行模式2. Java代码模式 「Kafka」Kafka理论知识解读&#xff08;一&#xff09; 「Kafka」Kafka安装和启动&#xff08;二&a…

【kotlin】利用by关键字更加方便地实现装饰器模式

关于kotlin中的by关键字的用法&#xff0c;kotlin官方文档属性委托这一节讲得很清楚。 简单来说就是这样的&#xff0c;假设存在一个接口Component如下&#xff1a; interface Component {fun method1(): IntArrayfun method2(a: Int)fun method3(a: Int, str: String) }那么对…

React-性能优化的手段

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;React篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来React篇专栏内容:React-性能优化的手段 目录 React 性能优化的手段有哪些&#xff1f; 一、是什么 二、如何做…

【汇编语言】流程转移和子程序

【汇编语言】流程转移和子程序 文章目录 【汇编语言】流程转移和子程序前言一、“转移”综述二、操作符offset三、jmp指令jmp指令——无条件转移jmp指令&#xff1a;依据位移进行转移两种段内转移远转移&#xff1a;jmp far ptr 标号转移地址在寄存器中的jmp指令转移地址在内存…

Vue3种常用插槽的使用

插槽总结 &#xff1a; 插槽的作用&#xff1a;让父组件可以向子组件指定位置插入html结构&#xff0c;也是一种组件间通信的方式&#xff0c;适用于 父组件 > 子组件 。分类&#xff1a;默认插槽、具名插槽、作用域插槽 1、默认插槽 父组件中&#xff1a; <Category>…

鸿蒙HarmonyOS应用 - ArkUI组件

ArkUI组件 基础组件 Image 声明Image组件并设置图片源 网络权限&#xff1a;ohos.permission.INTERNET Image(scr: string | PixelMap | Resource)// 1. string&#xff1a;用于加载网络图片&#xff0c;需要申请网络权限 Image("https://xxx.png")// 2. PixelMap…

一线实战,一次底层超融合故障导致的Oracle异常恢复

背景概述 某客户数据由于底层超融合故障导致数据库产生有大量的坏块&#xff0c;最终导致数据库宕机&#xff0c;通过数据抢救&#xff0c;恢复了全部的数据。下面是详细的故障分析诊断过程&#xff0c;以及详细的解决方案描述&#xff1a; 故障现象 数据库宕机之后&#xff0c…

粤嵌—2024/4/24—删除有序数组中的重复项 ||

代码实现&#xff1a; 方法一&#xff1a;双指针 int removeDuplicates(int *nums, int numsSize) {int l 0, r 0;while (r < numsSize) {if (r > 1 && nums[r] nums[l - 1] && nums[r] nums[l - 2]) {r;} else {nums[l] nums[r];l;r;}}return l; }…

ONES 功能上新|ONES Wiki 新功能一览

支持在 ONES Wiki 页面中使用分栏进行横向排版&#xff0c;丰富排版方式&#xff0c;帮助用户以更丰富的版式展示内容。 应用场景&#xff1a; 页面的布局对内容的阅读有很大的影响。当页面中有图文混排的需求时&#xff0c;可以通过分栏来组织页面结构&#xff0c;以更清晰、更…

Docker容器概念介绍与基本管理

前言 在软件开发和部署环境中&#xff0c;使用 Docker 等容器技术可以帮助团队实现快速、一致、可靠的应用程序部署&#xff0c;提高开发效率和应用程序的可移植性。 目录 一、虚拟化产品介绍 1. 云服务模型 1.1 IaaS 1.2 PaaS 1.3 SaaS 1.4 DaaS 2. 产品介绍 2.1 虚…

14 JavaScript学习:条件语句

JavaScript条件语句 JavaScript中的条件语句主要用于根据条件执行不同的代码块。以下是对JavaScript条件语句概念的详细解释和分类&#xff1a; if语句&#xff1a; 单个if语句&#xff1a;最简单的条件语句&#xff0c;根据条件判断是否执行特定的代码块。if…else语句&#x…

【机器学习与实现】机器学习概述

目录 一、机器学习的基本概念和方法&#xff08;一&#xff09;基本概念&#xff08;二&#xff09;机器学习的一般过程举例&#xff08;三&#xff09;样本和参数估计 二、机器学习的步骤总结&#xff08;一&#xff09;机器学习的主要步骤&#xff08;二&#xff09;样本及样…

C++并发编程

基本介绍 线程 C98标准没有直接提供原生的多线程支持 在C98中&#xff0c;并没有像后来的C11标准中那样的<thread>库或其他直接的多线程工具 然而&#xff0c;这并不意味着在C98中无法实现多线程。开发者通常会使用平台特定的API&#xff08;如Windows的线程API或POSI…

vue3中的ref、isRef、shallowRef、triggerRef和customRef

1.ref 接受一个参数值并返回一个响应式且可改变的 ref 对象。 ref 对象拥有一个指向内部值的单一属性 .value property &#xff0c;指向内部值。 例&#xff1a;此时&#xff0c;页面上的 str1 也跟着变化 <template><div><button click"handleClick&quo…