本文主要介绍如何在nodeJs中使用nsq,其他实现会在后续文章中输出。原因前段时间做了一个网页生成pdf的节点服务。由于puppteer和canvas在生成过程中内存消耗比较大,内容较大的网页生成时间过长,有时会出现第三方组件的问题。引入nsq使项目实现负载均衡,消除单点故障。但是在网上搜索后发现node中引入nsq的解决方案非常少。经过软硬发泡,最终将nsq引入node。我希望我能与你分享我的收获。认识nsqNSQ是一个基于Go语言的分布式实时消息平台。具有分布式去中心化拓扑结构,支持无限水平扩展。无单点故障,容错,高可用,能够保证消息的可靠传递。此外,NSQ非常易于配置和部署,支持多种消息协议。支持多种客户端,协议简单。nsq的设计很简单,你需要了解以下几个核心概念。1.nsqd:负责接收、排队和转发消息给客户端的守护进程。2.nsqlookupd:一个守护进程,管理拓扑信息,收集nsqd上报的主题和通道,提供最终一致性发现服务。3.主题:主题是程序发布消息的逻辑键。当程序第一次发布消息时,会创建一个主题。4.Channel:Channel组与消费者相关,是消费者之间的负载均衡。从某种意义上说,一个通道就是一个“队列”。每当发布者向主题发送消息时,消息都会被复制到所有消费者都连接到的通道。消费者通过这个特殊的通道来读取消息。实际上,它是在消费者第一次订阅时创建的。渠道。一个主题只能有一个频道,也可以有多个。不同的通道用于分配不同的任务。下面是经典nsq的示意图:安装过程中遇到的问题。在使用过程中,发现gcc版本太低,报错。因为node.js4升级了v8引擎,所以gcc版本需要在4.8以上。这个项目真正开始是基于eggjs的。首先需要在项目中安装nsqjs$npminstallnsqjs--save来控制根文件app.js中的nsq。nsq的配置非常简单,nsq分为写和读两个独立的进程。constnsq=require('nsqjs')module.exports=app=>{app.beforeStart(async()=>{//实例化nsq的写操作//在config中配置nsq的主机和端口,这里是你的配置好的nsq地址constwriterNsq=newnsq.Writer(app.config.nsq.nsqHostWriter,app.config.nsq.writePort)//连接nsq写函数writerNsq.connect()//写操作连接成功后,把它分配给全局app写入信息writerNsq.on('ready',()=>{app.writerNsq=writerNsq})当nsq写入功能实现后,我们就可以通过publish方法将信息ctx写入nsq队列.app.writerNsq.publish(config.nsq.topic,{//需要传递的参数})当服务器空闲时,nsq会随机分配到空闲线程来实现读操作,我们的核心业务是enablethereadfunction是在后面实现的,读写的初始化过程是在项目启动的时候执行的,在项目运行过程中,我们只是不停地读写。//实例化nsq的读操作//参数是要读的topic和channel对应的地址和对应的nsqreadconstclient=newnsq.Reader(app.config.nsq.topic,app.config.nsq.message是我在写入过程中传入的信息client.onmethod('message',asyncmsg=>{//格式化写入的信息letdata=JSON.parse(msg.body.toString())try{//为了保持连接状态,处理超时条件consttouch=()=>{if(!msg.hasResponded){msg.touch()//在下一次超时前一秒再次触摸消息setTimeout(touch,msg.timeUntilTimeout()-1000)}}让timeTouch=setTimeout(touch,msg.timeUntilTimeout()-1000)让timeFinish=setTimeout(msg.finish.bind(msg),msg.timeUntilTimeout()*3+1000)//这里是项目的核心处理部分。具体内容将在文章后面进行说明。这里返回的url是生成pdf的网络地址leturl=awaitctx.service.pdf.index.generate(data)clearTimeout(timeTouch)clearTimeout(timeFinish)//意思是队列末尾告诉nsq,有兄弟可以进来msg.finish()}catch(error){//如果出现错误则不阻塞,nsq会在失败后重新入队msg.finish()//这里可以添加网络日志console.log(error)}});client.on('error',function(err){//这里是监听读操作时发生错误处理的地方//可以在这里做一些错误处理,添加错误日志console.log(err)});});};刚开始讲到用nsq的时候有点慌,毕竟作为一个前端工程师看的一头雾水,但是仔细研究和咨询了后端大佬后发现nsq其实是一个高效的队列,简单而且使用方便,上手比较简单。后续文章还将对puppteer生成pdf服务的核心业务进行详细介绍,即上面ctx.service.pdf.index.generate(data)的具体实现过程。项目地址:https://github.com/XIEJUNXIRU...以上只是我的学习总结。如果您有任何问题,请告诉我。
