新工作第九周

今天是12月份的第一天,天气很不错,是一个好的开始。 第一个事情
是周一发现有些后台任务没有运行,突然意识到后台那么多任务,如果没有运行成功,会有什么后果?
所以再一次强调下后台任务(cron定时任务和队列任务,队列任务是处理队列数据的,和队列存储引擎不是一回事,当然队列引擎也会提供一些队列任务的功能,比如延时处理;队列任务用于消费存储引擎数据,需要有一个队列任务框架)的重要性,它们没有前台任务那么耀眼,但实际上非常关键,想寻找一个好的后台任务框架(队列任务框架)。
队列任务框架包含的功能?并发运行机制(根据队列容量自动启动多个任务,且任务之间不会处理同一个数据),单例运行机制(某个时间只能运行一个任务),运行结果跟踪,任务日志报表,纠错机制(比如强行杀死任务不会丢失数据),事务性(一个任务包含很多子任务,要么全部成功,要么全部失败),当然还有很多其它功能。在开发消息未读数功能的时候,简单写过一个,但还是希望找到一个开源的解决方案。

第二个事情还是和后台任务有关,管理后台和后台任务很多功能之间有共同性,我们业务是一个重运营的产品,很多功能可能都要发Push,每个Push还会有不同的路由功能。由于缺乏 框架
规则
,来了一个新需求,就会拷贝一大段代码去执行相同的任务(比如发送Push),从而导致越来越不可控,这涉及到几点。
首先基础代码库很重要,比如Push发送和Push路由应该封装好,方便调用,能做到这个,基本上就解决了大部分问题;其次就是技术理念的问题,尤其要大量使用队列机制,比如很多功能要发送Push,它就丢给Push队列处理,有专门的队列处理Push发送,类似于管道,连横合纵;然后就是规则,后台任务的业务模型是什么?要梳理出来,形成层级关系,简单来说就是知道有那些后台任务,并文档化,编写方式也要遵守一定的规则。

第三个事情还是和前面两个事情有些关系,是关于队列的,本周有个要做个活动,活动的完成条件就是发文、发评论、加关注,这些条件如果由前台API去完成,影响性能不说,还要修改很多API,那么应该怎么做呢?
以前要开发一个功能,比如和发文有关,就在API上丢个队列出来,这样累计下来发文API可能有m个队列,这里面就一个全局性的问题,因为大家时间有限,不愿意自己开发的代码影响其他代码,所以就又投递出个队列。
为了解决这个问题,和大家简单讨论了下,应该有个队列控制器的概念,就是所有的入队/出队应该统一封装下,有专门的管道处理。未来发文只会投递一个队列,然后由这个中心发文队列再投递出m个子队列(毕竟如果所有的子业务全部由中心队列处理,耦合度就太高了)。本次活动我们就采用了这种机制,先有个模型,然后再慢慢迁移。
说到活动开发,包括后台任务开发,大家可能觉得没有技术含量,其实想开发好也并不容易,另外我周记说的很多东西其实和“高深技术”无关,只是想着尽力去做好它,带来的可能是经验,而不是技能,这些东西在面试的时候好像也说不出来,那怎么办呢?做每件事情的态度决定了个人的工作方式,当然更重要的是要有自己的技术学习方法,在接触一门新技术的时候,有自己专门的一套方法。

第四个事情还是和开发理念有关,很多东西并不完全要由代码实现,比如为了实现热门话题、热门文章等等,完全可以由后台任务将需要的数据通过算法生成,不仅快还更容易调整。如果由前台实现,则要使用大量的数组函数,比如排重、排序、算分,数据量少发现不了问题,数据量大了呢?后台任务生成数据可能只要100行代码,而前台实现也许就要1000行,本次开发热门街区文章就采用了这种方式,甚至热门话题文章同样可以这样实现。

第五个事情,上几周说了mongodb的问题,本周也梳理了下,首先明确mongodb存储什么数据,那些地方在更新和查询。我们的Feed流就是基于mongodb运算的,这是我在以前公司没有用过的,真的不能太依赖Mysql,眼界应该更广阔点,等我将Mongodb运维搞得再明白一点,将来可以大量使用,在NoSql中,Reids和Mongodb好像是混的最好的。

第六个事情,我们一直说要改造和优化,应该怎么做?先做些调研,将每天所有表的新增记录条数统计了下,增长量太大的表就是优化的重点, 容量
决定了风险和性能;将每天mysql表的CURD数量统计了下,查询量最多的表就是优化的重点,并发性是决定性能很重要的条件;统计每天redis的操作数量(现在还无法根据key和指令进行细颗粒的统计);统计mysql和redis的响应时间,如果出现慢就要分析原因(索引?),很惊讶的是redis的操作时间居然比mysql select操作的时间要慢;统计所有API接口的响应时间,查询慢的接口和访问量大的接口是要优先处理的(很多人说花20%的时间解决80%的问题,其实某种意义上我更希望整体去解决,如果只是针对某个问题解决,只是表面好看而已);安装了xhprof(php7环境安装要注意,后面会专门写一篇)用于分析PHP性能,其实最主要的是了解一个接口或代码到底做了些什么。
有了这些数据,再细颗粒去分析,就可能会发现一些问题,比如说一个接口要查询20次redis,难道不是设计上有问题吗?一个接口客户端调用了无数次,但这个接口设计之初是要缓存的,是不是有问题?一个mysql查询次数太多了,是不是可以缓存?redis用于存储、队列、缓存,队列已经有了统一的管理器(只是雏形),接下去是攻坚哪一个?
我媳妇说发这些会不会不合适?我四年前就决定写一些总结,而总结如果写给自己看,就会很敷衍,写给其他人看会思考的更多;而且就算丢人的事情我也会写,其实并没有什么;如果没有这样的周记,过几年我就全忘记了,多年以后再看看这些记录,我会想起很多事情;写作是一门软技能,技术学习有三个阶段,阅读、构建、写下来,写下来才算是真正理解,否则只会自己觉得是理解的;很多人可能觉得我写的啥啊,其实如果每篇都看,我想会有一些收获的。
关于工作心得的问题,今天太匆忙了,我再整理下思路,下周再分享,唯一要提醒的就是淡定和微笑,最后说下我闺女,很喜欢画画和剪纸,表达能力也强了很多,每天早上能送她上幼儿园,每天回家看看她的大脸和小眼睛。