GoodBye 2016,Welcome 2017服务器学习程序员

一个技术宅的2016工作总结

2017-01-05  本文已影响588人  hongyang
003iBMr5gy70gij31codc&690.jpeg

(背景:我目前所在一家互联网公司,负责技术方面的事情。为了让大家看懂此文,有必要介绍一下我们公司的背景。我们公司的主要产品,是一个汽车电商相关产品,涉及到C端用户,B端经销商,集团,ToB销售等多个角色。订单状态众多,业务流程复杂。我们的产品规模,忙时:DAU 20K,Mysql CRUD 2000W q/d)

[TOC] <---- 为嘛简书不支持这个……

人们总是这样,到了年底的时候,才会想起时间。

回想这一年,虽忙的琐碎,却也充满收获,这真让人感到欣慰。

自打接手公司技术坑之日起,“保障服务可用,梳理研发流程,提升团队技术栈”,便是给自己制定的一个小目标。于是这一年尤其是后半年,“坚持,亢奋,努力”便是整个团队工作状态的真实写照。

就像所有技术团队一样,没有什么努力,会被白白浪费。回头看,那些经历,那些挑战,都值得被纪念。

持续集成(Topka-CI)

说起我们的产品线,客户端有“TopDeals”、“TopSales”、“AK47”,三款App。每款App分别有iOS和Android两个版本。当时客户端这边有10名同学,每月每款App大约迭代1至2个版本,这样的迭代速度不可谓慢。而就在这样的速度之下,app打包的工作还要人工完成,发布时,Android十几个渠道包一打就是大半天。即便在测试过程中,daily build也要工程师们手动完成。这极大影响了工作效率。而且手工打包,往往还会出现更多意想不到的问题——手滑弄错了配置项之类……

在这样的背景下,TopkaCI应运而生。

TopkaCI 主要完成以下实现以下功能:

TopkaCI在开发过程中,遇到了很多坑——几乎每一个环节都有技术问题需要解决。这些困难主要包括了以下几个方面:

虽然TopkaCI遇到了一些困难,但在TopkaCI在上线之后,大家用起来还是很爽的。持续集成极大提高了团队的研发效率,现在研发团队各项目的打包过程完全自动化,“原打包架构师就此转岗,去承担更为重要和艰巨的任务”。哈哈。

ci-1.png

MySQL 高可用改造

话说有一天,收到这样一封报警邮件,顿时惊呆了。

db-1.png

其实,我们并不是第一次收到这样的邮件。而对云服务的可用性来说,9999的概念是,每1万天,这样的邮件至多只能收到一次。但是很显然,他们并没有做到。

尽管可以向服务商提工单,但我还是不相信这样的问题会得到妥善解决。我也不想陷入无休止的拉锯战中,于是我们决定自己解决。

对MySQL的高可用,我们有如下需求:

好了,既然有了需求,就来分析一下怎么实现。

高可用的核心需求,是故障迁移——即当系统出现故障时,能够自动将服务切换至可用服务。遗憾的是,MySQL本身并没有提供这样的failover方案,不过像这样的轮子肯定是有人造过的了,但是如何选择轮子,还需要费一番功夫。除了满足上述需求以外,我们还希望框架尽可能的做到:

MySQL的高可用,目前来看主要基于以下几种技术:

最终根据自身情况,我们选择了相对成熟的MHA方案做为我们的高可用方案。MHA能实现之前提到的除了读写分离之外的大部分需求,并可以保证数据的一致性。而读写分离,我们使用keepalived来解决。目前上线几个月,效果令人满意。

微服务

微服务这个事,近年挺火,但很遗憾,我们微不起来。

这里既有历史原因,又有历史原因。说来说去,都是历史原因。但是,任何一家互联网公司,经过这么多年产品的成长与迭代,除非具备了推倒重来的勇气,否则各种“历史原因”都会存在。

但让我决定要做这样一件事的原因,是因为这样一张图。

tm1.png

是的,你没看错,纵轴单位是秒,这着实让人崩溃。看到这张图的第一感觉,是我们的程序有问题,于是:

折腾了半天,No luck!接着我继续看上面这张图,这张图很有意思,7秒、14秒来回蹦,7秒发生在白天,14秒发生在晚上……等等,我似乎搞清楚怎么一回事了。

排查所有定时任务,尤其是晚上执行的。确定这些任务在执行时,整个系统哪里存在压力风险……结果我找到了我们系统中一些非常重要定时任务,这些任务在运行过程中,极大的占用了网络带宽,以及数据库资源。

行了,拆吧。

拆库,拆代码,构建服务。更为重要的是,要让这个新服务的执行过程与线上服务完全分离。也就是说,新服务完全不占用线上环境的资源,我们为它搭建独立的内网环境以及公网IP。而这个服务与线上服务的交互,则通过IPSec隧道来打通。

m1.png m2.png

至此,问题解决。而且所有接口的响应速度都有了极大提高。爽!

ELK

ELK,我们很早就有了。但是ELK如果想真正用起来,其实还是要解决很多问题的。

让我下定决心把ELK用起来的关键事件,是某次参加一个技术会议,听了“小红书”运营总监的一个分享……

先来说需求。我们的ELK目前只打算记录一件事——nginx访问日志。但为了让记录的日志发挥最大的效能,我们需要将日志结构化。具体说来,有以下几个方面的需求:

具体部署方式,其实也都比较简单。我们做了下面几个事情算是比较独特吧:

上线之后,ELK向运营及技术团队开放。大家在kibana中查一查日志、做一些数据可视化什么的,用起来还都比较Happy。不过有一个点,在我心里一直有个疑问。

这套系统,总共开了7台机器。呃呃呃。我们抓4台web服务器的日志要开7台机器呀,这样真的科学么?

观察了一下这七台服务器的负载,我的天啊,低得可怜。那就,合并吧。

于是,我们使用Docker,将以上服务不同的Docker镜像跑在一台机器上,并且将这些服务的数据做为不同的挂载盘挂载到host系统。运行起来一切正常!硬件利用率大增,成本大省,哈哈。

并发与弹性计算

2016,不提到并发与弹性计算都不好意思说自己设计过什么架构。

之前提到,我们在忙时,DAU 20K左右。但任何互联网服务,都有忙闲,忙时与闲时,对服务器的负载压力必然不同。如果说云端计算能力对互联网服务来说是一种资源,那无论何时都开着同样数量的服务器,保持着一成不变的系统架构的做法,就好像家里无论何时都开着自来水一样——这不是钱不钱的问题,而是傻不傻的问题。正因如此,本着smart & geek的作风,我们怎能忍受自家的自来水成天开着。

“用最适当的成本支撑目前的业务,并有能力应对用户暴涨的情形”是这套系统设计的初衷及核心思想。

我们的线上系统按照PaaS层来分,大致可以分为负载均衡、缓存、静态文件、CDN、Web服务、日志服务、流式计算、消息队列,关系型数据库,非关系型数据库等多种服务,其中大部分服务为集群服务,线上系统大约有几十台机器的规模,我们首先需要实现对Web集群服务的弹性计算。

那么,这件事情的需求其实是这样的:

这个项目现在还没有最终完成。而未来,除了Web服务,我们也会考虑实现其他服务的弹性计算方案。届时除了节约成本,对运维团队的自动化运维的能力,也将是很大的提升。

生产环境的Docker

生产环境的Docker,我目前持谨慎态度,尽管京东在这两年618大促在生产环节上大量使用Docker。

Docker目前最大的痛点,在于集群化。生产环境使用Docker,只要牵扯到集群,你就得考虑太多问题:镜像管理、容器管理、编排……虽然现在有mesos,但是个人认为现在docker生态与集群相关的轮子还不足够好,自己造轮子得不偿失,依然得谨慎。

但Docker我们确实是用了的,没用在生产环境,却用在测试、测试的日志等重要度其次且暂时没有集群需求的环境。在这些场景中,用起来还是很赞的。

Mock与全栈

互联网产品,即便是渡过了从0到1时期的产品,其迭代速度也是惊人的。传统软件工程学所谓的瀑布流的软件开发模式,早已无法适应互联产品的研发迭代速度。且不说瀑布流,哪怕是敏捷,又有多少团队能够真正做到“在对的时间兑现你的承诺”。

“设计等待产品,接口等待产品,客户端等待接口,客户端等待设计……”

这些等待,有太多我不能理解。按照我的想法,产品只要有了概要定义,所有人都可以开始干活。因为软件开发中的任何一项工作,无论是产品定义、界面设计、接口实现、客户端实现,都必然要经历一个“从构建到精化”的过程,这个过程的起点,并不必要有上一环节的非常详细的输入才可以开始。

道理是这个道理,但有些事情一旦成为了习惯,就很难解决。三十来人的研发团队,习惯已经养成,怎么掰,确实是个问题。

想让技术团队有所改变,必须要引入新的技术。于是,我决定引入mock。先把“客户端等待接口”这个事情给掰过来!

mock这个东西,对于客户端团队来说,是欢迎的。因为客户端同学可以更早拿到可以运行的API接口,可以更早的开始开发。对完成kpi更有益处。

而对于服务端团队,就得说服他们能在实现接口之前,先做接口设计,并形成mock文档。这样会增加他们的工作量。但说服他们其实也有足够的理由——有了mock之后,没人催着你“快点出接口”,接口可以和客户端同步开发,最后留几天联调即可,其实跟之前相比不用那么紧张了。

对于mock server的需求,我们有如下几点:

最后,我们选用了阿里的RAP……RAP在阿里据说超多团队在用,但其实它的代码写的非常差,bug很多,更有诸如”太复杂的json结构保存容易出错”这样的恶性bug。但mock server,现在开源项目不太多,选RAP实属无奈。

等到了下半年,产品需求呈发散态势,多条业务线齐头并进。但各个端的研发需求量却不均衡,经常出现某个月App这边需求很少,但后台、经销商平台需求爆棚的情况。于是,我开始组织App团队学习服务端开发,利用培训、技术沙龙及code review等手段,鼓励(bi)(zhe)大家承担一些服务端、前端的开发任务。虽然起初很累,但现在大家已经基本实现自己写自己的接口、app。而为了保险起见,比较深的逻辑及模型的建立,目前还是由资深的服务端同学完成。

结合mock与全栈,对比之前,现在整个团队的研发效率上了一个大台阶。配合更为细化和有针对的敏捷流程,一个充满战斗力和承诺精神的研发团队已经基本建立。

写到这里,我不禁想到一个问题——“究竟什么才是技术领导力?”

“通过智慧的想法和技术的手段,让组织及研发团队都能坚信我们有能力兑现承诺。”在我看来,这就是技术领导力的最好体现吧。

PS:这一年参加了不少技术会议,全部都是开发向。所有跟技术领导力有关的,我一概没有参加。

不是总结的总结

回忆总是让人充满希望。上面说提到的这些项目,每一个其实都有继续做下去的意义。而2016对于我们来说,是打基础的一年,我们希望能够利用这一年,为组织在技术方面构件一套坚实、适用而又充满无限可能的技术栈,来应对可能到来的高流量及业务膨胀。现在看来,这个目标基本算是实现了。

而从个人角度说,在2016工作方面值得纪念的却远不止这些,这里仅记录了一些与业务无关的方面。所以说到收获,也不仅于此吧。

但是,遗憾也还是有的。最遗憾的就是React Native在移动端团队没有应用起来,那么未来的一年,为今年的小遗憾定个小目标:希望能够改组前端团队为“大前端团队”,React Native/JS用起来~

希望新的一年团队能更加给力,自己能成长更多。

上一篇 下一篇

猜你喜欢

热点阅读