异步任务与消息队列
同步任务:一定要等任务执行完了,得到结果,才执行下一个任务。
异步任务:不用等任务执行完,直接执行下一个任务。
异步任务最简单可以用异步线程实现,golang 中可以用goroutine实现,但受时间和不确定因素限制,进程有可能超时、退出或者被杀死,消息队列可以定义任何时间的延迟,几天都可以。异步线程、goroutine只是单机的实现,消息队列是分布式的,可以跨语言夸系统。消息队列是独立的,跨线程概念的,实现跨主机的分布式并发。
消息队列实现分布式的异步任务,利用分布式架构,实现可扩展性,高性能等,解决异构系统通信,实现服务间的解耦。
消息系统类型
- Streaming的适合log日志批量写入,强调性能。
- Queque队列强调可靠性,保证消息的正确传达与处理,强调task概念。
NSQ学习
NSQ是消息队列的一种实现,采用producer/consumer基于订阅的模式,开源、设计简单、架构容易理解,从而debug问题变得简单明确,
因为NSQ简单,可以通过NSQ了解和入门消息队列,知道什么是消息队列,消息队列的基本概念和基本实现。
通过学习NSQ源代码,可以深入对go语言的理解。NSQ实际基于goroutine管道模式,传出过程:将goroutine chan 中传递message对象根据NSQ传输协议转换成http tcp流中的frame二级制形式,传入过程:通过http tcp 管道scream流读写解析消息,转换到内部go routine chan 消息,
,这样就实现跨机器的网络传输,从而实现分布式队列。
t.memoryMsgChan = make(chan *Message, ctx.nsqd.getOpts().MemQueueSize)
NSQ可以定义内存队列的大小(通过golang chan 方式 ),超过了直接落盘,为了可靠性可以将内存队列长度定义为零,让所有消息直接落盘。
NSQ队列实现通俗理解
领导负责布置任务,把一个个任务放入队列中,个人负责完成任务,从队列中取出任务,任务完成后,给领导一个反馈(ACK)任务就被从队列中删除。重试过程相当于,一次任务搞不定(出错了)会被重新放进任务队列,但是会给你一个缓冲时间,等间隔预定义规则的时间再把任务发给你。
NSQ分布式设计
NSQ分布式实现简单,不依赖第三方组件,不依赖于复杂算法。
具体实现:consumer动态订阅全部的nsqd,可以从任何nsqd接收指定topic指定channal的消息,这样不管从哪个nsqd发的消息都能收到,某个nsqd挂了不影响使用(可用性,producer前可以挂loadblancer,或者通过主机池库(如:随机选择主机ip),均匀向不同主机的不同nsqd发布消息,实现负载均衡,简单理解就是一个反过来的多http server加loadblancer的模型。
NSQ特性
NSQ支持消息的压缩
NSQ消息本身没有顺序
NSQ可以实现topic channel暂停
NSQ提供了简单的web ui,实现了可视化。
消息队列分两种一种push 一种pull。
NSQ采用推的方式,通过ready inflight状态来限流。
NSQ使用扩展
通过nsq_to_file,用某个channel通过文件备份消息,可以配置类似log的Rotation周期。
通过nsq_to_nsq 把一个nsq群集的消息同步转发到另一个nsq群集中,实现扩展。
网友评论