一个技术宅的2016工作总结

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 主要完成以下实现以下功能:

  • 支持Android、iOS、ionic等平台项目的自动打包
  • 按照预定规则,从代码库的预定分支自动拉取代码
  • 支持mvn,gradle,npm,cocoapod以及bower的依赖管理,根据依赖定义及源信息来决定是否更新依赖
  • 对Android及iOS代码进行lint检查
  • 编译代码
  • 对编译后的App进行UI层面的自动化测试(使用两个平台的原生测试工具——UIAutomator与UIAutomation)
  • 成果物管理:App编译后,生成安装二维码,实现测试人员用手机扫描二维码自动将App安装到手机的功能
  • 成果物管理:iOS App自动上传到iTunesConnect并发出TestFlight邮件,通知相关人员测试
  • 成果物管理:每次打包结果根据版本自动上传到TopkaRepo,更新资产库

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

  • 对CI服务的扩展开发
  • 对编译过程所涉及到的相关工具的钩子进行开发,让CI过程按照上述流程连通起来
  • 原有项目的配置管理方式过于手工化,需要改造

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

ci-1.png

MySQL 高可用改造

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

db-1.png

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

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

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

  • 集群内的多个数据库实例实现热切换,当有服务失败时,自动切换到另一实例。
  • 迁移过程中保证数据的一致性以及事务的可用性
  • 迁移后,当发现down掉的服务恢复时,自动恢复数据,保证集群同步
  • 读写分离,当集群内的可用实例数量>=2时,自动分配1读1写。
  • 应用无感,无需为对应数据库的高可用需求做任何修改。

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

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

  • 方案成熟
  • 开源,可扩展

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

  • 主从复制技术
  • Galera
  • NDB
  • 中间件及代理
  • 共享存储
  • 主机高可用

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

微服务

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

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

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

tm1.png

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

  • 赶紧翻代码,然而从代码上看,没什么大事
  • 翻慢查询日志,涉及到这个接口的sql全都查一遍,看看慢查询是否存在
  • 优化慢查询sql
  • 优化相关代码的实现逻辑,看看能不能用缓存什么的

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

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

行了,拆吧。

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

m1.png
m2.png

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

ELK

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

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

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

  • 结构化nginx日志,常规的日志字段结构化
  • 结构化通用业务信息,如:访问机型、app版本、token等
  • 保存非文件类型的http response_body
  • nginx日志记录率达到100%,结构化过程中不能出现任何异常导致数据丢失

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

  • 写了一个 nginx lua script 来把response body搞出来
  • 为了分摊压力,我们采用了由3台机器组成的kafka集群做为消息队列,并用一台机器做为logstash客户端去专门消费kafka队列中的数据,而ElasticSearch也使用3台机器实现集群部署(后来证明此架构被过度设计了)
  • 在logstash消费过程中,写了一些ruby script来结构化nginx日志以及通用业务信息
  • 保证记录率,其实是之前踩到的一个坑。ElasticSearch自动映射类型有些不准,偶尔会出现冲突。出现冲突之后,再进来的数据就会exception

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

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

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

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

并发与弹性计算

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

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

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

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

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

  • web服务器无状态化(这个在之前已经基本实现)
  • 通过对web服务器四种核心能力——CPU、内存、磁盘IO、网络负载的使用率监测,决定是否需要减少机器数量或开启新的机器
  • 开启新的机器需要一个初始化代码库、配置文件、服务可用性检测的过程
  • 关闭机器前,开启机器后,需要自动修改负载均衡策略来引导流量
  • 通过云服务商的API进行数据监测及弹性部署
  • 支持根据业务需要自定义弹性策略:如我们每天可能会在同一时间向部分用户发送推送,届时部分服务的流量可能会增大。所以我们需要能自定义弹性策略,做到提前部署

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

生产环境的Docker

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

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

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

Mock与全栈

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

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

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

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

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

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

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

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

  • 开源,免费,协议友好,支持二开
  • 有UI——这一点非常重要
  • 支持LDAP

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

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

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

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

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

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

不是总结的总结

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

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

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • Docker — 云时代的程序分发方式 要说最近一年云计算业界有什么大事件?Google Compute Engi...
    ahohoho阅读 15,418评论 15 147
  • 寻找一种易于理解的一致性算法(扩展版) 摘要 Raft 是一种为了管理复制日志的一致性算法。它提供了和 Paxos...
    枝叶君阅读 2,562评论 0 15
  • 4月下旬开始到5月份受云姐的影响加入了禅绕画群,中间请过一次假后来又补交了作业,休息天我兴致起时也在画,总的来说是...
    Rabbit622阅读 171评论 4 2
  • 目录 从上篇笔记里我们知道英语有五大基本句型,它们是由S(主语)、V(动词)、O(宾语)、C(补语)四种成分组合而...
    清心澜意阅读 2,693评论 1 13