奶爸程序员的“育儿”心得

来自:往边界

自我介绍一下,本人以前是.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都是第三方的,虽然有技术支持,还是踩了很多坑。

坑到处都有,我们要做的就是踩到坑了不摔倒!

推荐↓↓↓
Java编程
上一篇:2017 物联网编程语言趋势:C、Java 各具优势 ! 下一篇:Eclipse 4.7 Oxygen 正式发布!带来大量更新