俗话说得好,鱼和熊掌不可兼得。
GitBook说,便利和网速不可兼得。
技术同学笑笑说,小孩子才做选择,我们全都要。
新鲜也就三两天
为了让用户更容易操作和理解方舟产品,我们采用在线文档的方式生成了全面的产品使用手册。手册里通俗易懂地讲述了功能的意义以及如何实操,方便用户随时查阅。用户的一些基础疑问,包括如何用SDK采集数据,如果建立分析模型等,都可以在这里找到答案。
最初在挑选的时候,我们看中了GitBook的内容搜索能力和便捷的修改操作,因此选择了它作为在线文档的生成和内容托管的工具。
采用GitBook的方舟在线文档界面
起初,它的便利性深受产品同学们的喜爱,但当使用逐渐深入,许多问题也随之浮出水面。
大家万万没想到,由于海外服务器的速度跟不上,页面加载缓慢、超长时间等待居然成了使用过程中最大的拦路虎。
每当这只狗狗出现,大家的内心几乎都是崩溃的
缝缝补补又一年
为了解决海外网速慢这一“硬伤”,我们技术团队决定采用内容抓取策略,通过搭建国内的服务器爬取GitBook内容,然后存储到服务器,供国内客户读取。
在这一方案下,国内服务器相当于中转站,专为国内客户提供云服务。但随着内容产出量的持续增加,客户使用量越来越大,我们发现国内服务器中转也有些吃力,内容更新不及时、爬虫抓取内容失败等新的问题接二连三。为应对上述问题,技术同学们只能不断更新爬取策略,甚至手动触发内容抓取。每当新的问题出现,就要经过一个客户或前方销售反馈-PM上报-技术修复的维护链条。
在近一年的时间里,我们不断维护更新策略,但随着问题不断暴露,旧有的方案还是严重影响了内部内容生产的积极性,和外部客户使用的便利性。如果网络问题始终得不到彻底解决的话,技术、产品、售前等人都将牵涉其中,因为需要持续跟进问题,向客户解释情况,安抚客户。一旦情况持续恶化下去,甚至会导致客户怀疑我们的技术实力或者选型的成熟度。
在这种情况下,我们一合计:不行,不能再拖下去了,必须拿出一套从根本上解决问题的方案!
于是热火朝天的GitBook终极改造计划就这样开始了。
“终极改造计划”
2020年9月28日,技术攻坚小组光荣成立。其中,除了我负责实操之外,还有一名了解整个过程的产品经理梅问提和一名后端同学盆哥在全力支持,以及我们的朝阳哥,主要负责拿个棒子跟屁股后面追进度。
时间紧,任务重,还必须保证外部客户对线上文档的访问,“开着车换轮子”在此时便体现得淋漓尽致。那么,究竟怎样才能做到实时更新内容,同时不受到海外源影响?
盆哥和我讨论了几套方案,其中包括直接推倒重来。我们设想摒弃GitBook命令工具部署,采用如confluence的策略部署一套新的方案。即使这需要把所有内容从GitBook导出后,再在confluence中重写一份。
梅问提一下把我们拉回现实:“新的方案能不能保障GitBook后台的强大丰富的组件以及编写的便利性? 这是底线”。
推倒重来的想法就此作罢;那么,我们只能从GitBook本身入手了。
通过分析代码我们发现,如果使用代理服务,GitBook是浏览器内js动态生成内容的,并且js、css、img等资源都是第三方域名,这导致代理服务只能解决一小部分问题。而之前的爬虫逻辑之所以不OK,是因为左侧导航栏都是动态生成的,这样总会有内容是抓不到的,还有GitBook的反扒策略等。
这就是为什么一直持续出现问题。既然问题分析清楚了,那么技术方案我们采用了 nginx+nodejs+nedb+cheerio+imagemin的组合策略。
具体差异如图
(左侧为GitBook服务,右侧为我们的技术方案)
开发过程正好遇到了国庆节,严重挤压了我们的剩余时间。此时我们面临的问题有:
· 浏览器内如何将多个域名的请求收敛起来;
· js动态插入的内容资源如<img><link>等如何也管控住;
· 如何将自己的js注入进去;
在代理服务抓取到页面内容后,我们首先使用cheerio将js内容append到body里。此外,多亏我们的浏览器完善了兼容性和增加了新功能,这里采用了 MutationObserver,可以很nice地被动触发监测。这样,我们就优雅地解决了浏览器端监测时效和性能问题。
解决了浏览器端的问题,接下来我们解决服务端问题。最高效的吞吐当然是内存,其次才是数据库读取和文件读取。考虑到:
· 尽量不需要数据库独立服务
· 内容存储量不大
于是我们采用了 neDB作为数据库,直接require后使用即可,而且是load到内存的,性能极佳,并且是非关系型存储,完全不用care后期的更新问题。至此,新的方案基本上完成了。
棍棒出奇迹
在功能开发完成的地方,就会有朝阳哥,还有根棍子。当时已是十月中旬,朝阳哥要求我们,必须在下旬的一个重要会议之前上线。几天后,虽然完成开发后还没测试几轮,在会议的前一晚,我们还是咬咬牙,硬着头皮把在线文档方案切了过去。
当晚线上有两个文档域名在生效,docs.analysys.cn和arkdocs.analysys.cn,而后者还cname到了GitBook,为了直接nginx代理arkdocs.analysys.cn这个域名,梅问提和技术同事亮哥把cname关系去掉了。
当觉得一切都很完美的时候,新的问题又对我们重拳出击。我们发现,之前爬取的GitBook内容,全部返回了502。情急之下,又一通电话把梅问提从通往家里的2路汽车上拉了回来,同时亮哥又紧急重新加上cname逻辑。幸好,这一问题得以顺利解决,我们有惊无险地度过了会议前夜的这一风波。
第二天,大会正式召开。在现场,我们突然发现测试用的香港代理机块到期了。正焦头烂额之际,亮哥手下大将土豆手一挥,给了我们一台正式的香港机器。当时把我们感动得,真的是雪中送炭啊。
一番折腾之后,我们终于切到了新的服务上。配置完成,一重启... 哦豁完蛋,内存爆了。
台上老板在讲,台下手动启动服务在撑(不然谁敢关?!)。我们只能各种尝试如何扩nodejs运行内存。forever天然的对-max-old-space-size支持不好。后来转战PM2,一切调通后,重启服务,好了。看了一眼群里,历时4个小时紧锣密鼓,真正的「开着车修发动机」,用户没发现,出了几身汗。
第三天发现有用户报访问缓慢,但按理说是不应该的。后来发现,原来是腾讯云的香港机器其实分配到了新加坡... 事件的最后,还是不二、土豆找到了一台硅谷的机器。一测试,起飞了。2兆/秒的下载速度,很爽。
修改前后对比
看到这张图,累也就有价值了。虽然在这之后,图片完整性校验,图片压缩,网络攻击等事件依旧发生着,但就是这样一个紧密合作的团队,还是把一个行将就木的系统盘活了。
从一个人开始,到后面梅问提,盆哥,亮哥,不二,土豆,大家陆续地都参与了进来;即使中间踩到了各式各样的“坑”,但可以说,我们的爆改计划大体上已经完成了。只要能提供稳健的服务,大家都是各尽所能提供了支持。何尝不是走了一条别人没走的路,但人一多,路也就走得通了。
你以为这就结束了?
是的,确实快结束了。
文档服务抽离一下属于典型GitBook海外源国内加速服务,解决了多源的收敛,做到了国内服务的页面内容存储,托管了js,css,img资源的文件化存储。同时还解决了GitBook的内容搜索快速跳转问题。
GitBook的服务麻雀虽小但五脏俱全,因此它在国内的使用规模着实不小。这意味着很多使用者都或多或少面临过和我们类似的问题,推而广之解决大家的问题也算是新的需求。
于是这时候,朝阳哥又出现了。他看着我们,意味深长。
“既然改造计划结束了,那我们就开源吧。”
就这样,这个事故... 不对,是这个故事,还得继续。
红包封面派送中!
看都看完了,还不点点在看?