nsq php,Nsq从入门到实践
当nsq跑起来之后, 我们可能会遇到以下问题
分布式部署
处理错误(何时requeue)
如何使用golang lib
抱着不应该只停留在入门的态度, 笔者粗浅的研究了一下这几个问题, 希望也对有同样疑问的人有帮助.
部署
由于NSQ的分布式网络结构, NSQD必须广播(到lookup)自己的地址并让消费者连接, 那么多个NSQD无法做透明负载均衡.
就必须为每一个NSQD分配单独的IP(或host)以保证消费者(在lookup找到NSQ节点)能够正确的连接. 这样部署起来可能会麻烦一些 但问题不大, 注意一下就好.
ps: 如果有更好的方法请告诉我, 小弟感激不尽.
NSQ Requeue And Backoff
建议结合官方文档来看
requeue(重试)
用于当错误发生, 需要重试时.
backoff(避退)
backoff能降低消费者吞吐量以让消费者从错误中恢复.
当消费者在backoff状态时, 这个消费者将不再处理任何消息, 直到backoff超时
当触发backoff时控制台将打印:
// 进入backoff状态, RDY设置为0代表准备接收0条消息(不接收消息) (协议详情看 https://nsq.io/clients/tcp_protocol_spec.html)
WRN 1 [test/test] backing off for 1m4s (backoff level 6), setting all to RDY 0
// 时间到了将设置RDY为1接收1条消息以测试状态, 官方将这个状态称为`tests the waters`
WRN 1 [test/test] (DESKTOP-HELJ7V4:4150) backoff timeout expired, sending RDY 1
当有多个消费者竞争时, 出错的消费者应当主动backoff不再处理消息(以让出更多的机会给其他消费者).
如果只有一个消费者, 则消费者会等到backoff超时后才开始处理消息(空出时间让消费者恢复).
避退是存在于整个消费者上的, 所以消费者每当一个消息处理失败了之后都会增加这个消费者的backoff level. 这会影响这个消费者的处理能力.
到底需不需要用backoff, 就要看业务了:
消息是用来更新数据库订单状态的, 这是一个不容易出错的逻辑, 如果需要requeue则需要backoff让出优先级, 让其他消费者来做, 尽量以挽救这个订单.
消息是用来通知第三方(如支付宝支付成功的http回调)的, 一般requeue是发生在第三方端响应不满足预期的响应, 这不是我方消费者的错误, 应当不使用backoff, 避免阻塞消息消费.
参考:
golang lib
nsq提供golang的client lib. 支持全部特性.
本着不重复造轮子原则, 我也想尽大可能的使用nsq lib里的代码逻辑来实现需求, 但有些需求它实现不了, 我也只好自己写代码了.
先看看它原有的几个逻辑
消息自动重试
// Handler is the message processing interface for Consumer
//
// Implement this interface for handlers that return whether or not message
// processing completed successfully.
//
// When the return value is nil Consumer will automatically handle FINishing.
//
// When the returned value is non-nil Consumer will automatically handle REQueing.
type Handler interface {
HandleMessage(message *Message) error
}
消息自动重试与判断失败
func (r *Consumer) handlerLoop(handler Handler) {
r.log(LogLevelDebug, "starting Handler")
for {
message, ok :=
if !ok {
goto exit
}
if r.shouldFailMessage(message, handler) {
message.Finish()
continue
}
err := handler.HandleMessage(message)
if err != nil {
r.log(LogLevelError, "Handler returned error (%s) for msg %s", err, message.ID)
if !message.IsAutoResponseDisabled() {
message.Requeue(-1)
}
continue
}
if !message.IsAutoResponseDisabled() {
message.Finish()
}
}
exit:
r.log(LogLevelDebug, "stopping Handler")
if atomic.AddInt32(&r.runningHandlers, -1) == 0 {
r.exit()
}
}
判断失败
func (r *Consumer) shouldFailMessage(message *Message, handler interface{}) bool {
// message passed the max number of attempts
if r.config.MaxAttempts > 0 && message.Attempts > r.config.MaxAttempts {
r.log(LogLevelWarning, "msg %s attempted %d times, giving up",
message.ID, message.Attempts)
logger, ok := handler.(FailedMessageLogger)
if ok {
logger.LogFailedMessage(message)
}
return true
}
return false
}
requeue
可以看到当handler返回的error不为空时, nsq将自动requeue, 这种重试是很方便但是
使用这个重试机制的坏处是:
不能自定义requeue的等待时间(默认等待时间=config.DefaultRequeueDelay*Attempts)
会在控制台打印一个ERR(不能自定义格式, 而且有一些err不应该打印到控制台), 这点可能有洁癖的开发者受不了.
一些错误不应该重试, 如入参不合法, 再怎么重试也是徒劳. 这时候应该直接失败.
所以我建议不要使用这个err机制, 而应当手动使用msg.Requeue(-1)或者msg.RequeueWithoutBackoff(-1) 来显示指定requeue.
shouldFailMessage
我们可以使用 FailedMessageLogger interface自定义当消息失败时的处理方式.
但它的shouldFailMessage又有什么需求满足不了呢?
在失败的时候拿到最后一次错误信息
shouldFailMessage只能判断处理重试次数过多的失败, 不能处理直接失败的消息.
所以又只有自己实现啦:
我们直接在Handler中判断Attempts来实现错误处理.
但为了保证我们的消息不被shouldFailMessage处理, 需要配置MaxAttempts为0或者一个比较大的数.
相关文章:

Java单元测试之JUnit4详解
2019独角兽企业重金招聘Python工程师标准>>> Java单元测试之JUnit4详解 与JUnit3不同,JUnit4通过注解的方式来识别测试方法。目前支持的主要注解有: BeforeClass 全局只会执行一次,而且是第一个运行Before 在测试方法运行之前运行…

Java 学习笔记 ------第二章 从JDK到IDE
本章学习目标: 了解与设定PATH了解与指定CLASSPATH了解与指定SOURCEPATH使用package与import管理类别初步认识JDK与IDE的对应关系一、第一个Java程序 工具:使用Windows自带记事本或下载其他编辑器(推荐NotePad和Sublime) //第一个…

Delphi中的容器类(二)
TStrings类 出于效率的考虑,Delphi并没有象C和Java那样将字符串定义为类,因此TList本身不能直接存储字符串,而字符串列表又是使用非常广泛的,为此Borland提供了TStrings类作为存储字符串的基类,应该说是它除了TList…

Java怎么把数组怎么放入set,如何将数组转换为Java中的Set
回答(16)2 years ago我从上面的建议中写下了以下内容 - 偷了它......真好!/*** Handy conversion to set*/public class SetUtil {/*** Convert some items to a set* param items items* param works on any type* return a hash set of the input items*/public s…

vue组件定义、组件的切换、组件的通信、渲染组件的几种方式(标签、路由、render)...
vue中全局的概念是什么?---就是全局定义的功能,所有实例化的vm都可以使用, 全局定义的是挂在构造函数Vue上面的,所以实例化出的对象都可以使用这个功能 1、什么是组件?---从UI的角度把页面拆分成不同的部分࿰…

JS九九乘法表
来一个老生常谈的话题--九九乘法表,哈哈,好久不写了呢 <!DOCTYPE html> <html> <head lang"en"><meta charset"UTF-8"><title></title><style>th{border: #ccc 1px solid;font-weight: n…

Php Fatal error: Allowed memory size of 33554432 bytes exhausted 的解决办法
Php Fatal error: Allowed memory size of 33554432 bytes exhausted 的解决办法 在 php.ini 配置文档里面,默认的memory_limit 属性值为32M ,值设置得太小了而导致这个问题的出现。 解决这个问题,我们一般有三种方式: 1、修改PHP…

php 自加 性能,对于数据库的自增、自减心得
系统研发过程中会有很多地方涉及到自增、自减操作 如:加入版块时,用户版块数自增1,版块用户数自增1;退出版块时,用户版块数要减1,版块用户数也要减1这里推荐:1.自增可以用2.自减不要用ÿ…

Linux rsync目录同步功能实现
实现目标:A 服务器上 /opt/web 目录,与B服务器上 /opt/web目录实现同步。即:B主动与A进行同步。OS: Reaht AS4A Server 192.168.1.2 /opt/webB Server 192.168.1.3 /opt/web一. A Server config1.rsync 系统自带, 需要使用 --deamon 方式进行启动,服务端口是 TCP …

宏定义的布局约束
*自适应向布局约束的转化关闭*/ #define PREPCONSTRAINTS(VIEW) [VIEW setTranslatesAutoresizingMaskIntoConstraints:NO] #define CONSTRAIN(PARENT, VIEW, FORMAT) [PARENT addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:(FORMAT) options:0 metrics:nil…

项目中WebService使用Spring容器的配置
<context:component-scan base-package"com.huawei.support"> <context:include-filter type"annotation" expression"org.aspectj.lang.annotation.Aspect" /> </context:component-scan> 扫描采用注解…

java 静态代码块 多线程,Java多线程编程笔记10:单例模式
立即加载:“饿汉模式”立即加载就是指使用类的时候已经将对象创建完毕,常见的实现方法就是直接new实例化。也就是在调用方法前,实例就被创建了。示例代码如下所示:class MyObject{private static MyObject myObjectnew MyObject()…

创业笔记-Node.js入门之阻塞与非阻塞
阻塞与非阻塞 正如此前所提到的,当在请求处理程序中包括非阻塞操作时就会出问题。但是,在说这之前,我们先来看看什么是阻塞操作。 我不想去解释“阻塞”和“非阻塞”的具体含义,我们直接来看,当在请求处理程序中加入阻…

vs 添加ico图 到资源
有时候想用自己做的ico 文件作为程序的图标来取代VS 程序默认的图标;在VS2005 资源视图中,打开Icon 上右击-->Add resource -->Import -->选择自己的ico 文件会跳出个错误框,说VS不支持32 位彩色图片; 网上搜索说VS不支…

HIVE QL 杂记
最近要处理用户访问日志,需要从HIVE中取数据,写了一些HIVE QL,有一点小感想,记录在此。 1. 临时表 在HIVE中进行多表连接时,可以给一些临时表命名,这样有助于理清查询语句之间的逻辑,格式为&…

java和内存交互,java内存模型-内存间交互操作
前言本文是阅读周志明大佬的《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》第12章,12.3节Java内存模型得来的读书笔记。阅读告警😂😂😂,本文可能会有点枯燥,大部分内容都是对书中内容做一…

文件读写io操作范例
系统io读写,copy int main(int argc, char **argv) { if(argc ! 3) { printf("Usage: %s <src> <dst>\n", argv[0]); exit(0); } int fd1, fd2; fd1 open(argv[1], O_RDONLY); fd2 open(argv[2], O_CREAT | O_TRUNC | O_WRONLY); if(…

一步步教你编写redactor的插件
Redactor是一款JQuery框架下的所见即所得在线HTML编辑器,具有常用的功能如图片/文件上传、表格、格式化等等,不仅轻量级和跨浏览器,还支持各种平台如PC、Mac、iPad, iPhone、Android、Refrigerators,更重要的它能够自动保存、自动…

windows系统杀掉explorer.exe进程后黑屏
使用“Ctrl Shift ESC”打开任务管理器 文件----> 运行新任务---->运行explorer即可 转载于:https://www.cnblogs.com/mrnx2004/p/11065573.html

php 自动返回,PHP实现自动识别Restful API的返回内容类型
如题,PHP如何自动识别第三方Restful API的内容,自动渲染成 json、xml、html、serialize、csv、php等数据?其实这也不难,因为Rest API也是基于http协议的,只要我们按照协议走,就能做到自动化识别 API 的内容…

WebKit、Gecko使用图形库
2008年11月30日 星期日 上午 01:20阅读了之后,觉得作为浏览器内核WebKit、Gecko,为了能高效美观的显示页面的内容,选择适当的图形库非常重要。如果图形库选择不当,往往会导致页面上显示的文字、图片不美观,看起来总让人…
office使用技巧
Word绝招:一、 输入三个“”,回车,得到一条双直线;二、 输入三个“~”,回车,得到一条波浪线;三、 输入三个“*”或 “-”或 “#”,回车,惊喜多多;在单元格内输入now&…

怎样用matlab打开mw文,C# matlab混合编程 MWArray使用笔记
C# matlab混合编程徐凯Email:xukai19871105http://www.doczj.com/doc/1a6e191fff00bed5b9f31dbf.html这几天突然想搞一搞以前没有搞定的MATLABC#混合编程,今天把原来编写的代码拿出来看看,然后结合网上一些正确的和一些错误的代码看看&#x…

【Android OpenGL ES】阅读hello-gl2代码(二)Java代码
AndroidManifest.xml <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"package"com.android.gl2jni"><applicationandroid:label"string/gl2jni_ac…

activiti任务TASK
一、概要 设计TASK的表主要是:ACT_RU_TASK,ACT_HI_TASKINST(见参考-activiti表);任务主要有:人工任务(usertask),服务任务(servicetask)等;候选人…

matlab数值分析拟合实例,数值分析函数拟合matlab代码.doc
数值分析函数拟合matlab代码.doc 第一题MATLAB代码用SPLINE作图XI0204060810YI098092081064038X10012Y1NEWTON3XI,YI,X源代码见M文件Y2SPLINEXI,YI,XPLOTXI,YI, O ,X,Y1, R ,X,Y2, K 用CSAPE作图XI0204060810YI098092081064038X10012Y1NEWTON3XI,YI,X源代码见M文件PPCSAPEXI,YI…

ArrayList Iterator remove java.lang.UnsupportedOperationException
在使用Arrays.asList()后调用add,remove这些method时出现 java.lang.UnsupportedOperationException异常。这是由于Arrays.asList() 返回java.util.Arrays$ArrayList, 而不是ArrayList。Arrays$ArrayList和ArrayList都是继承AbstractList,rem…

android中方法调用super(..)的相关知识
java中的多态有重写 方法被子类重写后 父类的原方法就会被隐藏 当你又需要调用父类所定义的原方法 这个时候就可以用super来调用super调用指向了父类,在一些调用里可以很巧妙的利用,比如监听返回键了在onKeyDown的方法里,如果想让系统对back…

在使用Reference Source调试.Net 源代码时如何取消optimizations(代码优化)-翻译
当你在使用Reference Source functionality in VS 2008 调试.Net 的源代码的时候,你会发现很多变量没法再调试时查看。 这是因为源代码服务器上提供的代码默认是为最终销售优化过的(optimized )。这些值虽然你没法查看,但不会阻断…

java旅游网站毕业论文,基于JAVA技术的旅游网站的开发.doc
摘要: 这次毕设主要是为了实现基于JAVA技术的旅游网站的开发,方便人们近距离的出行游玩。网站的开发过程中用到了很多方法技术,最主要的是JAVA技术,用于编写后台的功能实现代码;框架采用的是Spring MVC,作为轻量级企业…