2015 年 5 月 30日,广受开发者们欢迎的又拍云 Open Talk 技术沙龙再次登陆帝都北京——以《 移动应用技术架构的解读 》为主题的第八期活动,邀请到三位资深技术专家为我们解读移动应用技术架构背后的秘密:初页 CTO 丁乐;风云直播 技术总监 杜川;汽车之家技术架构师莫松,先后登场为开发者们解答技术架构难题。初页 CTO 丁乐在活动上作了题为《那些年我们踩过的坑》的分享,以下是演讲实录:

image.png

很高兴能和大家分享这样一个话题。我希望通过分享初页在发展历程中踩过的这些“坑”,也就是技术陷阱,能够帮助大家少走一些弯路,面对一些困难时做出正确的选择,从而避免挫折,节约时间、金钱等成本,加速产品和团队的成长。

关于初页

首先介绍一下初页。它是去年 11 月份上线的一个产品,基于 H5 的技术,让用户能够在手机上制作一些能够分享到朋友圈中飞来飞去很炫的页面。初页现在的场景应用比较多,包括节目预告、邀请函、数据报告、画展、情书、旅行日记等等种类。

我们的初衷,其实是给商业用户做基于移动端的广告宣传,或者一些会议邀请函。但上线之后,我们发现这个东西魔力很大,比如有一些 95 后的年轻人直接用它来做表白情书。因此,初页的应用场景就逐渐多样化起来。

image.png

根据统计,初页上线 150 天左右时,下载总量已经接近 160 万。同时作品数已经超过 300 万,总访问量超过 7 亿次。在这期间我们完全没有做推广,所有下载都产生自朋友圈的自传播。

到现在总访问量我还没有细看,日志服务器前段时间每天要接受近 8000 万条左右的数据。但完成这些,我们加起来只用了不到 6 个月的时间。而我们 iOS 开发大概从上线、测试到发布到 APPSTORE 更是只用了一个月时间,其中还包括服务端开发。另外,我们安卓开发也是仅用了一个半月时间。

在这么短的时间内,让产品获得上述这么大的成长,你是不能踩特别大的“坑”的。那么,都有哪些坑?如何避免“被坑”?这就是我今天要和大家分享的话题。

产品设计:精巧设计前,审视它是不是你杜撰的

什么是坑?很多时候你不是被别人坑了,这个坑其实是自己挖的,到头来需要我们偿还。有时候你几分钟就能搞定,有时候你可能就像携程那样,需要巨量的时间和成本,搞不好整个业务线都要垮掉。

用户急速增长和产品快速迭代的要求,让我们不可能像传统开发软件那样,花一两个月的时间先做需求,再做调研等等一系列的准备工作,最后才做成一个产品。

产品现在的架构都是一步步演进过来的,事先设计一个非常完善、结构非常精巧的产品是不可能的。如果从一开始就把所有问题整个梳理一遍,比如每天支撑多少访问,这个产品受多少人喜爱,结果必然是最后发现根本不现实,需求都是自己空想,老板要求你重做,之前这一、两个月的时间全白费。

因此,我们做产品时,应该思考它是否会被用户马上需要,是否和市场足够贴近。想法不要过于超前。架构和产品是演进而来,不要再贸然花费更多的时间去提前做设计。实现精巧设计前,一定要审视它是不是你杜撰出来的。

技术选型:选择 & 使用云服务需慎重

以下是我今天分享的三个主要方面:技术选型、迭代时、上线后。创业企业在这三个阶段可能会遇到一些比较严重的问题,这是根据我们亲自踩过的坑所得的经验教训。

一、一些主要云服务商的优缺点

从阿里云到 UCloud 这些厂商的服务,我们都亲身体验,了解它们的优缺点各在哪里。我们 80% 的计算服务都在 UCloud 上面,阿里云和 WindowsAzure 也会用到一些。

image.png

UCloud 不足点就是它的后台体验其差无比。但是它的优点是服务真的很好,他的性能和 IO 稳定性也是首屈一指。他们的业务主要针对游戏厂商,我们知道,做游戏对 IO 和稳定性要求比较高,因此 Ucloud 的投入都在这两项上了。它的价格可能比阿里云价格贵一些。

二、选用无害的Paas服务

比如负载均衡、分布式缓存、消息队列、服务器监控、Blob 存储。这个东西的一个好处是你可以随心所欲地把它替换或者停用掉,因为它跟你的数据没有关系。这个可以节省你 30% - 40% 的精力。

三、使用云存储服务需要尤其注意的点

首先,不得不提一下又拍云 。我们在几个月前开始使用又拍云,效果还是比较好的。它无论是速度还是服务都很靠谱,而且可以直接提供一些很有效的压缩技术。

(1)跨域和防盗链

在对这点进行设置的时候一定要先仔细过一遍,因为设置提交后会在 CDN 中产生缓存,如果设置存在错误,你想再清除它的缓存是极其耗时耗力的。而且大部分 CDN 厂商没有从根域名清除缓存的功能,所以在设置时一定要非常的小心,不能随便搞,出错了想去补,你可能几天几夜都不用睡觉了。

image.png

(2)路径的持久化

在这方面,最开始我们犯一个非常严重的错误,就是直接把云厂商的 url 存到数据库里去了。当时也是偷懒不想做域名映射,先存起来,因此根本没有试。上图中前面这一串东西是我们自己的域名。

很多年前,我根本不理解为什么云厂商要搞自己的一个域名映射,不直接用他们的 url 。它的根本原因,就是万一需要进行迁移,你就得把数据库里的 url 都改一遍,这是无法估计的工作量。结果就是:我们当时单单干这个事情就花了一周。而且不只这一项困难,改了之后它在服务器上还有缓存,最后我们只能判断一下这个 url 是不是某某云厂商的,然后把它弄到另外一个地方去。因此,这个错误千万不要犯,一旦犯,你就只能整天搞这个了。

(3)记录错误日志

在上传的时候需要尤其注意。因为云厂商这个环境特别的复杂,有的是在地铁里面,有的是在某地区。之前我们遇到过很奇葩的问题:使用的 CDN 厂商在河南加节点,当时扫描基调网络的结果是我们不存在问题,肯定是对方网络出了问题。向厂商反馈后,对方回答说在河南加节点会导致停机,让我无力吐槽。

所以在这种时候,要记录日志,出问题要快速响应。以便出问题后明确知道是云厂商的责任,跟自己没关系,这非常重要。有时候大家很忙,你反馈说出问题了,但没有日志证明,事情就只能拖着。因此你需要证据来让对方明白是自己的责任。

(4)容灾

最后,上传一定要容灾,就算这个厂商是牛逼的厂商也要做容灾。因为再好的厂商也架不住网络不好。所以一定要做容灾,上传失败之后重试一次,不行的话,切换一个再上传。

迭代:专人应急 & 严把接口关

产品迭代是遇到的问题会很多,老板还会随时在耳边催你。此外可能遇到奇葩问题,比如某些服务使用保留字段作为字段名称,这种情况非常要命:由于安卓和 iOS 的保留字段不一样,我们又是先上的 iOS ,但 Java 没有提供绕过编译器的能力,因此后来安卓开发被迫只能自己写一次序列化,这样的问题可能比较多。

一、上线紧迫时,出现临时问题一定要抽出专人解决

我们之前遇到过这种情况:产品功能简单时,开发人员每人负责一套服务,可以做到快速上线。随着功能越来越多,就可能会乱,导致迭代缓慢。

这时老板说明天要上线,开发说不行,要申请重构,我们老板是技术出身,详细了解了一下情况之后发现了解决的好办法——加一个字段就可以了。但问题又来了:当时数据库里面的信息数量早已过亿,加一个字段意味着巨大的工作量,可产品却要立即上线。因此,针对这样一个临时的变动,一定要有一个专人出来做才行。

image.png

二、一定要有专门做架构的人

一定要有专人负责做架构。这个人不一定要有架构师的水平,他可能是既懂业务又懂技术之间的人,不一定技术很强,也可能是对业务有深入理解。这个专人主要负责接口评审及设计。他经手的接口,要没有任何多余的字段,也没有任何异想天开的需求。

有这样一个人协调的话,表面看上去效率很低,甚至加一个字段也要评审。但他带来的好处是现在慢,以后快:会杜绝发生所有程序写完后,发现某个字段出现问题这种自己给自己挖的“坑”。

另外,接口设计一定不能搞一些没用的东西进去,而且慎重开辟新接口,并做好每一个对外借口永久服役的准备。我们的方式,就是大家一块设计接口,之后专门的架构师进行评审。

三、用 SwaggerUI 编写接口文档

image.png

不要用 Word 文本和记事本,直接使用 SwaggerUI 编写接口文档,生成代码。这一套流程下来,我们客户端相对要轻松很多。不需要像从前那样没完没了的核对,挨个接口的改,这样你会非常痛苦。

SwaggerUI 还可以生成客户端代码和服务端代码。不够的话,还可以在这里拓展。它解决了我们大部分关于接口方面沟通的问题。这让开发速度比以前快了好几倍。

上线后:做好日志管理及指标监控

在产品上线之后,也会面临很多棘手的问题。比如说,客服反馈有用户点击预览按纽报错,提示网络有问题,但经过查证该用户本身网络完全正常。因此程序员就要查日志,结果开发说日志每三天上传一次不说,一看又发现日志总共有 30 多亿条,基本没法查,最后是这个程序员想办法开了一个代理服务器,经过很繁琐的步骤查到问题确实在我们,并把它修复了。

image.png

一、多维度日志收集、管理

由此可见收集和处理日志是十分麻烦的,该如何解决?我们选用 ELK( Elasticsearch Logstash Kiban a)+ Redis 处理和查看日志。通过它,我们可以将信息分类。我们的日志还做了一些用户标识,可以借助这个在一秒之内查出用户最近干的任何事情:比如报了什么错,耗时多少,是 3G 还是 2G 还是 Wifi 等等。

image.png

通过 ELK + Redis,我们每次都可以做到提前发现错误,并及时进行修复。

二、实时监控关键指标

ELK 还让我们能够做一些关键指标的监控,像数据库、集群,关键错误产生等等,这些东西特别可怕,一定要提前发现和处理。我们现在就在用 ELK 收集处理日志,并正在开发一个可以对登录失败、报错等等关键指标进行实时监控和报警的系统。一旦发现错误,它可以马上向相关人员发送邮件,并每周做报表。

image.png

我们目前在做 13 个左右的监控点,覆盖我们的服务器日志还有 客户端和前端日志。iOS、安卓,前端,服务端等终端收集只保留 30 天的日志, 30 天之外的我们并不一定需要。所以在系统上线之后,我们会做一个自动的差异备份,下载到我们的本地。什么时候需要,就能拿出来继续用。从成本上讲,算下来只需要三台 8GB 内存的主机就够了。

三、Kibana日志查看

我们用 Kibana 查看日志。现在初页的开发人员会经常在上面刷新一下看看,这样就提高了他们解决问题的效率。

以前客服或者运维反馈问题时,开发人员还需要做很多询问才能得到解决问题所需的详尽信息。这个过程太麻烦,而且会让部门之间气氛闹得很僵:客服会说开发为什么不早告诉我,非要我来问你;开发则会认为前面的人工作没干好。 ELK 的应用消除了大部分问题。

总结:创业团队可能会踩的“坑”

image.png

总结来说,初创团队需要注意的技术陷阱有以下几点:


1)根据自身实际需要来选择云计算厂商:比如我们需要的只有好的 IO 稳定性,你的功能牛、价钱低、产品线长等服务优势跟我没关系。由于每次迁移成本非常大,因此在选择厂商时你要充分考虑实际需要。

2)尽量避免挖大坑的实践:像把云厂商的 url 存到数据库这种事千万别干。哪怕老板要求今晚上线也不行,和他说明具体情况,再加一天时间做域名映射,大部分领导应该都会同意。

3)实现精巧设计前,一定要审视它是不是自己杜撰的:产品和架构都是演进而来,不要指望事先设计一个很完善的产品出来。做设计的时候一定要充分考虑它能不能马上解决用户的实际需求,不能异想天开。

4)应该有人做统一架构,不管这个人算不算得上架构师:有了这个人,至少不会犯一些根本性的错误。

5)上线前要检查好客户端接口的调用时机和数据:关键接口要检查调用顺序,严把接口关。否则发布后一旦出现问题,下架会很麻烦。

6)日志管理和监控一定要先做:这让开发或者运维能够提前发现并解决问题,而不是等着用户出问题后追着你问。这对提高服务质量有非常大的好处。