奶爸程序员的“育儿”心得
自我介绍一下,本人以前是.net程序员,去年下半年负责把项目从.net转到java,并且有跨机房迁移,亿级访问量,app服务端项目。
自我吐槽一下,工作了8年了,没有成为架构师,也没有进入管理层,没有成为技术大师,也没能成为分享大师。一直在做业务,并在这条路上越走越远。有的时候觉得很尴尬,但又有的时候觉得还蛮适合自己。
过年之前,老婆生了一个小公举。宝宝饿了,“老婆快来喂奶!”,宝宝又饿了,“老婆快来喂奶!”,宝宝睡醒了又饿了,“老婆快来喂奶!”……老婆说:“我感觉我就是头奶牛”!作为一名“奶爸”,感触颇为深刻!
自己负责的项目就像自己的孩子,孩子出事了,大家首先想到的就是这个奶爸。奶爸上阵(常常半夜爬起来),该换尿布换尿布(服务器故障),该喂奶就喂奶(bug)。如果生病了,就喂喂药,吃药不管用,就外面请大夫(疑难杂症,搞不定,请别人搞定也是搞定)。宝宝的奶粉如果出了问题,恨不得拿刀宰了那个奸商(调用了别人的服务,服务挂了,影响到了自己)。宝宝吃饱喝足,安静睡了,奶爸也可以安心睡了!
-------------------------------------------------------------------------------
下面开始干货,记录一下自己的“育儿”心得:
一. 技术选型
开发语言:java,go,php,nodejs
如开头所说,本人之前是C#程序员,C#的语法精妙,逆天的ide,.net版本更新较快,快到我都不记得最新的版本号了。那么多新特性,如果服务器上安装的始终都是.net3.5 对我们来说又有什么用呢。
开始是很抵触java的,断断续续学了好多次也没投入使用,这次必须要上了。不得不说,这么多年了,java一直在增长,稳定,成熟,几乎能解决所有问题,而且性能也不差。这大半年下来,java的水真的好深,异步、并行等等,还没接触过的好多好多。
go的好处就不说了,在学习,如果喜欢又觉得能拿捏的住,就上吧(哈,肯定不会像说的那么轻松)。
nodejs做前端太方便,也有人用来做服务端接口层。
php做前端页面,就像服务端用java一样,万金油,成熟,稳定,用的人多,资料也多。
总之一句话,没有最好的,只有最适合的!
选java是因为 我们后端的很多微服务也是用java开发的,方便调用。还有就是,不用java还能用啥。
存储:mysql, mongodb, redis
当分库都不能解决问题的时候,分表就格外重要,有一种无限扩展的感觉。之前用的oracle,只分库,没有分表,hold不住了。
存储的类型还是尽量越少越好,redis做缓存一般是绕不过去,都要用的。
团队里有很多人排斥mongodb,就不说具体原因了,redis能搞定的事情,就不要用mongodb了。
还是那句话,没有最好,只有适合,把相应的数据放到最适合的存储里。
mq: rabbitmq,activemq
你肯定会用到mq的,即使现在不会,以后肯定会的。
java框架:spring mvc
用的人多,成熟,坑都被大家踩过了,遇到问题好查资料好解决。
ibatis和struts在我们的项目中没有用到。
二. 源代码管理工具
语言选好了,框架选好了,要开始写代码了,问题来了,写好的代码用什么管理?
Git! SVN!
Git的分支真的可以解决太多问题,很强大!
SVN的tag也不错,用来做发布不错。
不管用什么工具,一定要做好规范,比如git的分支命名。时间长了分支越来越多,如果不规范一下,会乱的一团糟。
再比如分支的合并,应该怎么合并,不应该怎么合并。
分支的流程,去哪个分支提交测试,去哪个分支发布等等。
分支合并的冲突解决,一定要事先沟通好,不然代码丢失,找都不好找。
三. 开工
1. 搭架子
这里最好能把监控做起来,监控太重要了,一开始就要考虑清楚,不然后面加会痛苦万分。
如果打算用hystrix之类的框架,一开始也要搞清楚实现方式,后期实现太痛苦。
2. 代码规范
架构师一开始都会想的很完美,如果不做规范,来来回回人多了,里面就乱了。
当然,即使你做了规范,也会乱的,只是会乱的小点。
3. 一些基础代码
比如:打日志,http请求,怎么加监控,怎么rpc调用,接口在线查询文档等。
4. 调试
代码写完了怎么运行,怎么调试,本地是用jetty还是tomcat,怎么发布测试服务器,这些都要根据实际情况调整了。
5. 开发工具
现在说好像有点晚了,对于java,有的人喜欢eclipse,有的人喜欢idea。再比如git的管理工具,有人喜欢sourcetree, 有人喜欢敲命令,就比较难统一了。
6. 代码审查
没事看看同事写的代码,代码放的位置对不对,有没有重复代码,不要把你的架子搞乱了。
Findbugs,这个插件实在太有用了,可以发现很多低级、没有预料到的问题,比如可能存在的空引用,String.format格式化问题等等。
7. 团队沟通
人多事情就会来,肯定会有人遇到奇奇怪怪的问题,这个时候就要一起沟通解决了。
底层框架的问题,要赶快修复优化。
流程问题,优化流程规范并通知团队。
如果能有个wiki,论坛之类的把大家踩过的坑记一下就更好了。
定期开例会同步进步,同步问题。
四. 测试
代码写完了,需要有个强大的测试团队来测试功能了。
我们的项目是接口,对外输出json数据,如果没有自动化比对工具,全靠肉眼真的要疯掉。
字段缺失,大小写问题,格式问题,各种问题都会一一暴漏,是时候再优化规范了。
1. 自动化测试
这个看测试实力了,本人也不太懂,有个测试大牛是多么的重要。
2. 接口文档
开发在做接口的时候就要把文档更新好,修改代码及时更新文档。
当然写文档太烦了,java里的注解可以搞这些,然后自动生成在线文档。
3. 压力测试,并发测试等
做的接口能否支撑起业务,怎么评估,就要看压测结果。不达标?优化!
五. 上线
这个时候要想好怎么规范发布流程了,如果公司有团队帮你做自动化集成发布就太赞了,如果没有就只能自己撸了。
什么jenkins,打包脚本,就自己搞起来吧。
什么,代码服务器和上线服务器不在一个机房里? 没关系,svn,git帮你搞定。tomcat也有上传war包的功能。
1. 申请服务器
根据访问量评估服务器数量。
要不要拆分接口,比如abc接口只访问A服务器,def接口只访问B服务器,nginx接入层搞起来。
2. 发布
发布流程,发布系统。
是否需要灰度发布?
能否快速回滚。
配置管理系统搞起来。
3. 监控
奶爸程序员最重要的工作之一,就是看监控。
什么调用量,高峰调用量,成功率,失败率,超时率,平均耗时等等。
最好能在线查看接口调用返回的code,可以快速定位问题。
除了app调用你的服务的监控,还有你调用别人服务的监控。一个是发现自己的问题,一个是发现别人的问题,撕逼和被撕逼,都要拿出证据。
失败率,超时率,平均耗时这些很有必要,也是奶爸程序员的kpi。
如果能有cpu,内存,网卡使用率等的监控更好了。
再进一步,如果有jvm的监控那就更棒了!
监控都做了,报警必须有,短信、邮件,你懂的!
4. 日志
奶爸程序员最重要的工作之二,甚至比看监控还重要。
监控有延时,有时候并不能及时发现问题,这个时候看错误日志就很重要。
系统是否正常运行,就是通过日志来判断。
错误日志会帮你发现问题,甚至早于用户发现问题解决问题。
奶爸程序员还要看日志是不是打多了,打少了,打错地方了,重要业务日志有没有。这是个长期的过程,根据情况逐步调整。
观察线上服务器的日志,是奶爸的重中之重,先于用户发现问题,先于客服事件解决问题,保驾护航,简直就是爹妈不容易啊!
所以,辣么多服务器,你最好有个日志收纳系统,在线查看筛选系统。
5. 稳定保障
nginx接入层,在tomcat前面用nginx做接入层,用nginx做分发,对服务器做分组,周边服务挂了,不能影响核心业务。
nginx还有个好处还是做转发,比如,你有个a.site.com站点要改版,老版本的a.site.com域名不能动,新版本的在别的服务器上,a.site.com域名也必须用,那么nginx接入层的作用就显现了,把新改版的页面全部指向新站,其他的回老站,搞定。
还有就是在你的后方有众多微服务,各个微服务也可能会相互依赖,如果其中一个挂了,那么对你来说可能就是灾难,怎么避免这种情况?
这个也是最近在做的事情,搜了一圈,都是在谈Netflix的Hystrix,这个应该是比较成熟的方案了。
熔断和降级只能保证微服务不会星火燎原,但不能保证前端出现错误,所以前端一起配合,提供一些柔软、体验好的错误提示会更好。
最后
奶爸的工作当然不止这些了,为人父母当然没那么简单了,杂七杂八超乎你的想象。
和产品谈需求,客服事件排查,和同事讨论技术方案,和测试沟通改bug,和领导汇报,什么?app又打不开了?什么?机房有故障?什么?有人在刷接口?永无止境。。。
------------------------------------------------------
说几个自己踩过的坑:
1. 网卡被打满
当第一次遇到网卡被打满的时候,觉得很神奇,有一种介于牛A和牛C之间的感觉。时日至今,网卡被打满真不是什么新鲜事了。
测试在压力测试的时候,qps老是上不去,后来发现是压测机的网卡被打满了。
服务崩了,缓存服务器网卡被打满了,单key存储的东西太大。
总结:网卡被打满是不得不考虑的事情,尤其是你来来回回传输的东西既大调用量又高。解决办法就是单key的值不宜太大,而且不论是什么缓存,随着值大小的增加,性能是急剧下降的,所以能拆就拆,现在都是分布式缓存,key越多,各个服务器就越平均,key的增加对性能的影响微乎其微。
2. tomcat老是被重启
一到高峰期,tomcat就噼里啪啦的自动重启,找不到原因啊,奶爸遇到挑战了。
就像前面说的,孩子生病了,你有的药吃不好,那就请大夫开方子,请别人治好也是康复啊。
后来在tomcat重启的时候做了dump和tcp监控,后来发现tomcat在重启的时候time wait过多,推断出某个服务的调用出现了性能问题,积压太多,累积到一定程度就爆炸了。
后来是增加某服务的rpc调用的连接数搞定了。
还有一点就是synchronized关键词的使用要小心,小心出现性能问题,会堵塞。
3. 监控曲线突然没了
曲线突然没了,掉成0了,顿时吓尿了,赶快排查日志,发现在上报监控的时候报错了,上报的线程的挂了。
改呗,上报错了就错了,不能制造惊魂啊!
-----------------------------------------------------------------
总结:
以上都是本人的一些经验心得,可能对你来说没什么特别,也只能说鄙人才疏学浅,跟不上技术发展的脚步。如果你有更好的,请不吝赐教,大家一起成长!
以上的所有东西,对于小公司小团队,或者从无到有的项目还是很庞大的。监控系统,日志系统,运维,发布,到处都有坑让你踩。我们目前所用的rpc调用方案、缓存、mq都是第三方的,虽然有技术支持,还是踩了很多坑。
坑到处都有,我们要做的就是踩到坑了不摔倒!
祝大家新年快乐!