返回 登录
0

初页CTO丁乐:分布式以后还能敏捷吗?

阅读14346

初页现有架构

首先介绍一下初页目前的架构。它主要由计算服务和后面的运维与运营系统组成。

图片描述

计算服务由passport、works(作品服务)、social、message、counter组成,每一个服务集群都是一个域名,自己管理缓存,存储,计算等。类似这样的服务初页还有若干。运营系统主要是Boss系统,里面涵盖了各种大大小小的报表。同时,还具有数据上的运营能力。运维则是由日志,监控,部署和分析审计这些系统组成。

遇到过的坑

这些系统如何是如何工作的呢?请往下看。

图片描述

这个是一个用户主页,顶上是用户信息的那一块,中间绿的是我们计数提供的服务,底下是作品列表。看似很简单的一个页面,但是到服务端可能一个请求过来了,需要一次性把需要的数据的吐出去。

而在服务拆分后,随便一个服务都需要多个其他服务的支持。比如顶部的用户数据,除去用户信息之外还有他的粉丝和关注信息。想获取顶部的用户信息,调用一次接口可能内网转了好几层,最后拼装成了一个界面需要的数据。

起初,技术团队做了一个冗余,方便业务端自己做类似排序和筛选的需求,到最后发现太痛苦了,因为服务越来越多,同步数据工作量比较大,最后干脆做成一个内部调用。典型的是底下的作品数,作品列表中还有浏览跟分享,点赞评论等各种各样的计数。一段时间的发展后,又提出各种维度的排序需求。

图片描述

开发跟调试会变得很麻烦,因为服务化了就会造成等待。什么意思呢?今天程序员A开发一个功能,我们依赖他的数据接口,他不开发完成,流程肯定跑不通。陷入这样的循环后,会造成很大的矛盾。正是因为服务化了,所以在并行开发时都要求先Mock接口不影响其他同学开发,上线后的接口都要做到向后兼容。

图片描述

找BUG困难,难明确问题。A 调到 B ,调到 C ,反复调来调去,只要有一方有问题了就会造成找BUG很困难。比如说登录,最开始找服务端,为什么会登录失败呢?服务端说这是谁调用的,他的调用方法有问题,去找他吧。这种状况显然是有问题的。

总结一下之前遇到的问题,第一个沟通成本很高,开发与调试变的非常麻烦,因为要占用大量的时间来做无效的沟通。另一个是找 BUG 很困难,很难明确问题到底出在谁头上?因为一个服务经过很多次调用,反映到前端,再报出一个错误信息,基本上是很难挖到底的。

接下来我们做了什么?

图片描述

第一,服务集群化。初页的架构基本和其他互联网公司的一致。根据业务切成服务集群,每个服务集群里又提供若干数量的微服务。调用之间记录RequestID方便查找和跟踪调用链条。与过去混乱提供的微服务方式相比,切完系统之后解除了耦合,便于监控与审计。但服务多了之后我们部署起来就有压力了,慌乱之间还可能出现低级错误。

图片描述

第二,搭建快速部署的平台。解决了前端跟后端的交付压力问题。里面的功能比较多,比如截图中的发布列表,回滚等,会有发布流程的配置。

比如后端发布的交付流程是这样的:首先把代码pull下来,然后开始进行编译,把正式环境的配置拉下来,如果需要发布的是一个测试版,这个时候会把测试服务器的配置拉下来打包,下一步开始往服务器上推一个伪生产环境。什么意思呢?先把 A下掉再对A进行一下验证,跑完自动的验证程序后然后再跑一下预热和测试的脚本等。跑完之后,觉得这个服务 OK 了就行了。

如果觉得还存在问题,可以设成手动上线,一台一台的上。比如有十台服务器,前面两台手动,后面八台就自动了,一个开关可以直接设置。后面演变成了关键业务需要审核,怎么办呢?在发布的时候可以做一个审核流程,每一个项目可以订制自己审核的标准,完成审核之后再到线上去。

图片描述

前端交付跟后端交付非常像,也是先拉代码,压缩指定脚本,合并静态资源,最后的生成mapconfig来做资源坐标对应。每个步骤都经过了精心的优化,比如png会根据颜色自动做 8 位或者 24 位的判断压缩。

资源处理完成后,会生成一个 deployid ,发布了以后想先试一下看行不行,只需要在网络环境下做一下手脚,就能使一帮人或者某一个人使用特定的版本,而不用把整个的线上全换掉。这使得初页具备了一定的灰度能力,比如先把一部分的服务给设置成新的版本,在监控系统里面再遛一圈,看有没有什么错误,如果没有错误,整个服务器做一个全面的切换。

这个ID可以把整个前端的所有代码做整个的切换,代码版本跟版本之间是可以同时存在的,所有的接口是相互兼容的。像这种部署任务,初页每天有时候达到七、八次,或者是更多。最后的上线过程跟后端一模一样。

图片描述

开发和测试阶段,团队会用 Docker ,网络方面会用到 VPN ,因为都在云嘛。有时想调试比较麻烦,会通过 VPN 直接连上我们生产环境的内网,如果有必要可以向运维申请一个只读的权限,进去看一些东西。这个时候内网就显得非常必要了,因为调 BUG 的时候会更快一点。

为什么使用 Docker 呢?因为资源利用率高,启动速度非常快,有的时候想做快速验证,用虚拟机的话,只能用快照或者用镜像,想做一次验证成本很大,特别是我们的服务又非常多,每一个服务如果都是一个镜像,随便就是几十个镜像,速度是没有办法提升的。

一台物理机可以做很多 Docker ,初页买了一台物理机放到机位里面,局域网使用这个非常方便,每次做测试用这个启动都是秒级的。开发人员想把这个环境拿回家开发,但是又不想全部再搭建一遍,怎么办呢? Pull 一下,所有的环境都可以搞定。

图片描述

另外,就是搭建日志平台解决找 BUG 的问题。一个服务内部又去调用其他服务的若干接口,查找调用链还是过于麻烦。所以初页搭建日志平台,把所有的日志都收集监控到位。此外还开发了 WebApi 用于客户端和前端。存在这样的一些场景,比如我们想看到用户调用一个接口的整个过程是什么样的,分别跑到哪一些服务器拿什么样的数据,以及在哪一步报了什么样的错误,都可以直接输入查找出来。通过它排错会非常快,定位问题很容易。

图片描述

除此之外,接口审计也是没问题的。比如说做了很多的聚合,有实时接口调用情况, TOP10 , TOP100 等。又比如,看这个接口在某个时段提供了多少流量,并发是多少。 搭建这套系统之前,我们想看数据都是手动写代码拉取各个服务器中的日志分析。

分布式以后还能再敏捷吗?

回头来看都解决了哪些问题呢?沟通成本高,迭代速度变慢,初页通过服务化开发,以及之后的自动部署系统解决。开发与调试变麻烦,必要的时候申请只读权限,进入生产环境调试。还有找 BUG 非常困难,因此搭建了 ELK ,帮助明确问题和解决问题,然后结合zabix 做了各种监控。

做了这么多东西,是不是真的解决了问题?关键是遇到问题解决问题,技术每天都在写程序服务用户,为什么不花点时间服务下自己呢?完善这些基础服务,在未来对于迭代速度是非常有帮助的。所以,分布式以后还能再敏捷吗?在合适的时候完善基础架构,这其实是很有可能的。


分享人:丁乐,初页CTO。他曾就职于微软Bing搜索项目。作为敏捷开发的深度实践者,他擅长基础架构的高效化完善,以快速将创意打造成产品。他曾主导打造了初页、云起轻应用等颇具人气的产品。

架构技术实践系列文章(部分):


本文整理自初页CTO丁乐日前在“UPYUN架构与运维大会·北京站” 上的主题演讲。[UPYUN 架构与运维大会](https://www.upyun.com/archopsconf.html)是国内领先的新一代云CDN服务商UPYUN独家主办的大型技术会议。大会面向全国运维和架构从业者,邀请业内一线的架构师和运维专家进行纯干货分享,旨在推动各项运维技术、产品架构等在互联网和移动互联网的研发和应用。

(责编/钱曙光,关注架构和算法领域,寻求报道或者投稿请发邮件qianshg@csdn.net,交流探讨可加微信qshuguang2008,备注姓名+公司+职位)

「CSDN 高级架构师群」,内有诸多知名互联网公司的大牛架构师,欢迎架构师加微信qshuguang2008入群,备注姓名+公司+职位。

评论