UNION系统的运营与运维

作者: | 更新日期:

随着UNION系统越来越复杂,接入的业务越来越多,运营成本与运维成本也无限膨胀了.

本文首发于公众号:天空的代码世界,微信号:tiankonguse

零、系统之痛

随着系统的进化, 很多不起眼的问题都会成为不得不去解决的问题,如果不去解决,系统最终将崩溃.

随着业务的发展, UNION系统的接入来源越来越多, 系统的访问量越来越大, 很多问题都逐渐暴露出来.
每天这些问题都占据着一群人大量的时间与精力, 于是我想着怎么做一些工具来解放生产力.
但是制造工具的优先级总是最低的, 于是形成了恶性循环, 生活变得暗无天日.

终于有一天我忍不住了, 看看过去, 每天有一半的时间在处理这些问题, 然后一半时间在开会, 只剩四分之一的时间来开发了.
我琢磨着要打破这种局面, 于是宣布每周五不进行开发, 只进行运营和运维的工具开发与优化.
后来世界终于慢慢静了下来.

这里记录一下相关的工具与优化, 供自己思考人生.

一、接入文档

一个系统的门户是很重要的, 但是开发和老板往往不重视服务的门户.

以前有一个简单的接入文档, 但是很多人看不懂, 导致接入的业务都不规范: 比如没带APPID, 比如我们要打电话一步一步告诉他们怎么接入.
于是完善了接入文档, 然后业务可以按着文档步骤一路走下去, 就可以得到UNION的接口了.

二、字段与值的含义

对于一个名字, 只有创造它的人才清楚是什么含义, 其他人只是使用这个名字.

UNION作为一个数据输出层, 实际上是不识别输出数据的含义的.

比如视频2001表有个设置(setting)字段, UNION会有一张配置表配置这个表的字段该去哪个数据源拉数据.
但是对于setting的含义是什么的, 什么场景下使用等, UNION其实是不知道的.

但是业务接入时, 经常会有产品, 开发, 老板等人来问题是否有某个字段, 字段的类型是什么, 字段的含义是什么, ID字段的值是什么含义等等.
于是从我接手UNION那天起, 有很长一段, 每天都在重复着这样的场景:

0. 这个字段的值是什么类型

之前说过UNION的值类型丰富起来, 字符串, 整数, 小数, 数组, 对象等等.
使用者不知道字段的类型确实合理, 于是我就加上了对于的字典表文档.

1. 是否有字段

某开发: UNION的2001有XXX字段吗?
我: 你去字段表页面搜索一下就知道了.
某开发: 怎么搜索?
我: ctrl + f

当然, 有时候也会遇到确实搜索不到.
于是我拉上媒资的同事咨询, 一般有两个结果: 确实没有这个字段或者这个字段有另外一个名字.

如果问我怎么搜索的是其他人也就算了, 开发也一大堆.

后来在另外一些小事上得到启发: 有同事反馈某网站点击按钮没反应,不知道出什么问题了, 我说抓个包呗. 那位同事惊讶的说这个也能抓包?
平常他开发自己的系统时都经常抓包看自己的按钮为什么没反应的, 使用其他人的就不知道怎么做了.后来在其他同事身上也遇到了几次.

于是我的世界观也逐渐的变化了: UNION系统就是我的一个产品, 我的用户没有自己想的那么聪明,不断用户是谁.
于是我增加了搜索功能.而且心里梳理着都需要为我的用户实现那些功能.

2. 字段的含义

某开发: UNION中2001表的XX字段是什么意思?
我查看之后: 这个字段我也不知道, 我拉上媒资的同事看看 媒资的同事回答有两种: 这个字段是XX意思, 有时候也会回答不知道,说只能去看源码了.

很大一部分字段都是只有一个英文名字, 具体含义都没有标注.
当然大部分没有字段含义也是历史遗留问题,毕竟是接手过来的.

3. 字段的值的含义

某开发: UNION中2001表的XX字段的值分别是什么意思?
我: 我也不知道, 我拉媒资的同事进来吧
媒资的同事: ….

面对这样的问题, 接手之前他们曾讨论过一些方案: 媒资提供wiki地址,UNION录入wiki地址 或者 UNION开发完善对应字段的含义.
但是有上千个字段, 操作了几个后就没有下文了.

我接手后每天上演着这样的事情, 于是想了两个方案一起进行.

  1. 每当有人问一个问题时, 就完善对应的文档(其实接手之前也这样尝试过多次, 但是后来都是没下文了, 毕竟都很忙)
  2. 媒资提供一个接口, 提供每个字段的含义. UNION每天同步一次数据.

对于第一个方案, 我一直进行中, 由于常用的字段其实只占少数部分, 所以效果很明显.
对于第二个方案, 我和媒资的产品和开发都聊过这个事情, 他们愉快的答应了, 然后就没下文了.

茫茫然的等待了几个月后, 我想自己动手丰衣足食.
毕竟曾经我也是媒资的一员, 媒资重组时比我更了解媒资的人没几个吧.
于是我自己写了一个脚本, 去媒资的DB分析字段的含义, 然后每天同步过来一份.

UNION部分字段, 我的脚本可以去媒资得到对应的名字, 如果值是ID的话, 还会拉出ID的字典表(当然,只显示五个,其他的让找媒资的同事).
由于UNION只有我一个人, 对于媒资后面则是十几个人, 所以把ID字典表的问题抛给媒资也是最优方案啦.
当然, 这个只能拉取那些属性字段的含义, 因为属性在媒资是配置化的, 所以可以找到对应的含义和字典表.
对于其他字段我就无能为力了, 只能靠人力来逐渐完善了.

如果是接入UNION的业务方, 我会让大家自助去查询这个值.
当是老板的话还是需要走那么一番特殊的流程的, 因为吃过一次教训.

有次某个老板说想在XX位置显示一张图片, 问该使用UNION的哪个字段.
那时年轻的我直接回答了UNION只是透传字段,现在有十几个字段都是图片, UNION测也不清楚, 可能需要拉上媒资的同事看看.
然后老板特别不高兴了, 原来在老板的眼里, 作为UNION的开发, 输出的几千个字段的含义应该一清二楚.
现在想想当时应该这样回答: 稍等我去查一下. 然后私底下去问问媒资的同事, 然后再把结论告诉老板.

三、数据不对

UNION只是数据的搬运工, 有问题请找媒资的同事.
by tiankonguse

业务接入UNION测试时, 偶尔会遇到另外一个问题: 数据不对.

这个时候就要经过下面的一些列步骤:

缓存层: 1. 登陆服务器 2. 查询缓存层数据 3. 查询聚合层数据
聚合层: 1. 登陆服务器 2. 查询聚合层数据 3. 查DB配置数据源配置(涉及多个步骤) 4. 查询数据源数据 5. 登陆媒资DB 6. 查询媒资数据
媒资层: 1. 登陆DB 2. 查询数据 3. 查找原因,拉其他同事

是的, 每天都在重复做这样的事情.
我为了节约一步, 专门开了一个窗口用于查询数据.

后来发现聚合层同事在做移动端的统一cache, 于是就想着如果我能独立查询的就不去打扰他了.
于是我这边确认是媒资的问题后就直接拉上媒资的同事了, 把聚合层同事彻底解放出来了.
当然有时偶尔确实比较忙了,我也会把问题抛给聚合层的同事.

就这样半年过去了, 我忍受不了了.
宣布做工具后第一个做的就是这个.

如果全部做完这个工具, 实际上就是把UNION从下到上的逻辑重新实现了一边.
由于工作量比较大, 目前数据源那一层和DB那一层还在进行中.

这里主要实现了三类功能极大的解放了生产力:

  1. 汇总数据 - 快速判断哪一层出问题了
  2. 具体层全部数据 - 快速判断是不是所有机器都存在这个问题还是部分机器存在这个问题
  3. 测试环境 - 让接入UNION系统的开发与测试可以自助查询值, 确认是不是自己的程序或者传参有问题.

后续如果有时间了, 会支持聚合层的所有数据源和DB层.

四、错误码

错误码应该是唯一的, 见其值知其含义.

业务接入的时候还会遇到说拉数据失败.

业务: 你好, 我拉UNION失败了.
我: 测试环境正式环境
业务: 正式环境
我: 错误码多少?
业务: 我没打印出来, 稍等, 我打印一下 …. 是-100007
我: 传的KEY太多了, 你传了多少了?
业务: 哦, 我传了1万个, 最大限制多少?
我: …

业务各种错误都有, 于是我把错误码也放到了门户上.

五、策略配置的是什么?

一个系统必定向配置化进化.

UNION的大部分策略都配置化了, 于是就会有很多业务来了解具体的配置值.
如我这个APPID是否配置成不走缓存, 那个字段缓存时间多长.

于是我把对应的配置数据都展现了出来供大家自助查询.

当然, 有时候业务可能不明白这些配置的含义, 于是我会在表格的顶部描述各项配置的具体含义.

六、问题反馈系统

如果琐碎的事情太多, 那就需要流程化.

每天面对那么多的事情, 虽然做了工具让用户自助解决, 但是我还是不断的被打断, 而且用户自助去解决后也没有给予反馈.
所以我想这先让用户去填一个问题流程单, 然后引导他们去自助解决(进行中).

七、扩容文档

扩容能够自动化最好, 如果不能就写一个文档吧.

如果业务比较简单, 程序包安装上去就OK的话, 那还比较好.
对于UNION服务, 依赖七八个东西, 需要配置四五项内容, 如果没有文档那漏一个就有问题了.
比如有个数据通知模块, 漏了测试依然可以拉倒数据, 但是数据更新就会有问题.

写扩容文档为什么要专门提一下呢, 因为曾有多个依赖的模块扩容时, 对应的同事都漏过操作,而且发生多次.
如果扩容漏一些操作实际上也可以理解的, 但是工程的角度来看, 我们为了保证防止遗漏,写个文档完全是有必要的.

其实我这边当初写文档的目的是给运维写的, 当时计划要扩容,后面我要休假,于是写了扩容文档, 运维按我的文档稳定的扩容了.
由于我不喜欢记忆东西, 尤其是文档上可以查询的东西. 所以后面我扩容时都是按照这个文档一步一步操作的.

八、有同步流水吗?

当数据不一致时, 只有流水能够证明自己.

数据从DB到UNION, 中间经过很多层, 任何一层出问题都会导致最终的数据不一致.
而之前的做法要么是打开全量日志, 要么是猜测是哪里出问题了.

后来大家一起做了一件事情: 每一层状态上报.
于是数据不一致时, 就可以看到各层处理的时间点, 然后就可以马上找到为什么不一致了.

九、监控

一个重要的系统一定要有完善的监控.

由于UNION接入的业务方有上百个, 当某一个业务方出现问题时整体的监控上是看不出异常的.
所以需要针对每一个业务单独监控起来.

公司有一个监控系统, 可以针对一个ID上报值, 然后针对这个ID设置最大值,最小值,波动告警.
于是初期就是使用这个系统实现了业务级别的监控, 花了三天时间手动去申请了一千个ID, 然后一个一个配置了一下.
而且后续随着业务的接入, 还需要手动的一个一个配置.

我就想着自己做一个监控系统, 然后可以做很多个性化的监控.
于是就靠零碎的时间做出来这样一个系统.
数据类型上支持多个维度的: appid, 程序名, set, table, ip, 字段等维度(后来由于字段和ip的数据量太大, 下掉了)
时间上支持多种时间, 而且还有各层的命中率数据都可以展现出来.

十、报表

报表才能证明你的成功.

之前一直都是看监控数据来看各种数据的.
很多老板也经常问我访问量秒级别多少, 天级别多少, 命中率如何, 底层访问量如何等等.

之前我都是说需要看看监控计算一下, 现在我可以看一眼报表说出所有数据了.

十一、错误日志

海量服务都是关闭日志的.

有时候业务经常会找过来说拉数据失败, 线上服务, 现在已经找不到原因了.
问UNION测有没有详细的访问流水, 看看服务扩散后每天有2万亿的量, 打日志是不可能了.
于是我想了一个方法: 随机打印日志上报到日志服务, 为了防止日志错误类型分别不均匀, 每种错误类型使用不同的权重随机上报.

十二、书签

当一个系统足够复杂的时候, 每个模块的入口就需要使用某种方式组织起来, 需要时快速进入.

UNION系统随着运维工具与运营工具的完善, 入口多大几十个.
于是我做了一个支持搜索的网站地图, 快速帮助UNION相关人员进入到对应的模块或者系统.

十三、在路上

一个系统足够复杂时, 随着业务发展,不仅旧工具需要持续优化, 新的工具还需要持续的创造, 否则生产力就得不到解放.

现在这些工具只是可以使用,还有很多优化点.
另外还有很多计划要实现的工具要实现, 还有很多问题还没想好怎么使用工具自动化解决.
所以未来的路还是比较漫长的, 我们开发要坚信工具在人就存在, 工具不在时人就和死亡没区别了.


长按图片关注公众号, 接受最新文章消息.

本文首发于公众号:天空的代码世界,微信号:tiankonguse
如果你想留言,可以在微信里面关注公众号进行留言。

关注公众号,接收最新消息

tiankonguse +
穿越