这段时间基于yarn写了一个监控告警模块,项目其实不是很难,但也确实花了2个月的时间。
里面用的很多知识不熟悉,单独每块弄懂也算轻松,但是串起来运用就需要大量的经验了,正因如此整个项目我是改了又改。
项目中主要是以Service形式提供的,这在我以往的时候并不是很熟悉,甚至对于Service应该还需要设计recovery目前也没细想。
里面基于的事件的Dispatch开始也没完全弄懂,就直接去用了。加上状态机,ZK框架curator,基于Potocolbuf的RPC等等也都是第一次整合应用。
项目中有很多问题值得去记录,但是由于对项目的掌握信心不足,只能节约出写blog的时间,现在尽量回忆一下做些记录。
项目中耗时最长的一个bug几乎找了一天半,开始是以为Calendar.getInstance()的时候获取的2次毫秒不一直造成的。
我是推了又推了,几次貌似感觉推成功了,最后还是否证了。但是服务器上居然每次都能重现,本机却重现不了。
我检查过jar包冲突,也没发现,都怀疑操作系统问题了。最终无意中发现由于我做版本备份的时候,只是改了一个名字,但是并没有移出lib目录。
由于我采用 java -classpath “.../lib/" 方式启动,2个包冲突了。
我也就是说嘛,从我过往经历来看,如果一个bug我半天时间解决不了,一般都是jar包问题,这次也不例外。
另外一个bug,由于存在多个告警引用jsm,我生成jsm最后去判断如果jsm的referCount为0,我就清除它。
但是我却忘记了我是基于事件的,我将addReferCount()交给了事件去做,由于是异步的,
事件中addReferCount()也许并未处理完,我就判断了jsm的referCount为0清除了,以至于后续程序无法正常运行。
又想起一个bug,我对Queue put的时候判断元素是否存在,但是Queue循环的时候可能刚好拿出去,还没放回,或者其它原因容易造成并发,所以我加了一个互斥锁。
而由于take()的时候是一直等待状态,锁无法释放,而put的之前需要先拿到锁做判断。2者之间造成了死锁,所以初始化的时候我往队列加上一个空元素,这样Queue中永远都会有元素了。
还有一个bug,我有一些static volatile变量。我现在还不能确定应该设置为public的,还是为该static变量加上get方法。貌似看到的很多源码都是final类型。
或者这里volatile并没有起作用?
问题在于我在一个无线循环外部,申请了一个变量 a,通过get方法去给它赋值,此后由于其它线程改了那个static volatile的变量,但是这里的a由于是先取出来的,却永远无法感知到对象的变化。
包括QueueService中代码InstatncesMap初始可能为空,queue.take()一直在等待的时候,
随着时间推移,此时可能take拿到一个新的对象,但是InstatncesMap随之更新的东西,确是拿不到的。
【上面这段话,可能当初描述不够准确,现在并未重现过,我觉得最后一句话描述有误,是因为某个问题,导致的假象】
其它并没有太多印象深刻bug了,如果想起了再回来补充吧。