好的架构是进化来的,不是设计来的

好的架构不是设计出来的而是演进出来的前端

  对不少创业公司而言,在初期的时候,咱们很难在初期就预估到流量十倍之后、百倍之后、一千倍之后网站的架构会变成什么样。固然,若是在最初的时期,就设计一个千万级并发的流量架构,那样的话,成本是也是很是之高的,估计很难有公司会这样作。git

  因此,咱们主要来说架构是如何进行演化的。咱们在每一个阶段,找到对应该阶段网站架构所面临的问题,而后在不断解决这些问题的过程当中,整个战略的架构就是在不断的演进了。github

  其实,在 58 同城创建之初,站点的流量很是小,可能也就是是十万级别,这也就意味着,平均每秒钟也就是几回的访问。此时网站架构的特色:请求量是比较低,数据量比较小,代码量也比较小。可能找几个工程师,很容易就作一个这样的站点,根本没什么「架构」可言。数据库

  其实,这也是不少创业公司初期面临的问题,最开始58同城的站点架构用一个词归纳就是「ALL IN ONE」,以下图所示:后端

  就像一个单机系统,全部的东西都部署在一台机器上,包括站点、数据库、文件等等。而工程师天天的核心工做就是 CURD,前端传过来一些数据,而后业务逻辑层拼装成一些 CURD 访问数据库,数据库返回数据,数据拼装成页面,最终返回到浏览器。相信不少创业团队,初期作的工做也是相似,天天写代码,写 SQL、接口参数、访问数据等等。浏览器

  这里须要说明一个问题,你们都知道目前 58 同城使用的是 Windows、IIS、SQL-Sever、C# 这条路。如今不少创业公司可能就不会这么作。58 同城为何当时选择了这条路?缘由是公司招聘的第一个工程师和第二个工程师只会这个,因此只能走这条路。缓存

  若是能够重来?那么会选择LAMP服务器

  不少创业的同窗可能会想,若是咱们初期但愿作一个产品的话,咱们应该使用什么架构? 若是让咱们重来,可能咱们如今会选 LAMP,为何?首先是无须编译,并且快速发布功能强大,从前端到后端、数据库访问、业务逻辑处理等等所有能够搞定,最重要的是由于开源产品,是彻底免 费的。若是使用 LAMP 搭建一个论坛,两天的时间就很足够了。因此,若是在创业初期,就尽可能不要再使用 Windows 的技术体系了。架构

  在这个阶段 58 同城面临的主要问题是什么?其实就是招人。不少工程师可能都是在培训学校里培训了3月就过来上班,因此他们写 CURD 的话很容易出错。当时,咱们引进了 DAO 和 ORM。虽然那些培训了几个月的工程师可能写 CURD 不是特别的擅长,可是他们写面向对象的一些程序引入了 DAO 和 ORM,让他们再也不直接面对 CURD 语句,这样就会相对容易一些。由于工程师比较擅长的是面向对象的数据,不是 CURD,因此咱们当时引入了 ORM,总的来讲,若是你们如今的项目处于一个初期孵化的阶段,DAO 和 ORM 可以极大的提升效率,并且能够下降出错的几率。并发

  中等规模:流量跨过十万的阶段,数据库成为瓶颈

  随着 58 同城的高速增加,咱们很快跨越了十万流量的阶段。主要需求是什么?网站可以正常访问,固然速度更快点就行了。而此时系统面临问题包括:在流量的高峰期容易 宕机,由于大量的请求会压到数据库上,因此数据库成为新的瓶颈,并且人多的时候,访问速度会很慢。这时,咱们的机器数量也从一台变成了多台。如今的架构就 采用了分布式,以下图所示:

  首先,咱们使用了一些很是常见的技术,一方面是动静分离,动态的页面经过 Web Server 访问,静态的像图片等就单独放到了一些服务器上。另一点就是读写分离。其实,对 58 同城或者说绝大部分的站点而言,通常来讲都是读多写少。对 58 同城来讲,绝大部分用户是访问信息,只有不多的用户过来发贴。那么如何扩展整个站点架构的读请求呢?经常使用的是主从同步,读写分离。咱们原来只有一个数据 库,如今使用多个不一样的数据库提供服务,这样的话,就扩展了读写,很快就解决了中等规模下数据访问的问题。

  在这个阶段,系统的主要矛盾就是「站点耦合+读写延时」,58 同城是如何进行解耦,如何缓解延时呢?

  对 58 同城而言,典型业务场景是主页,发布信息有发布页,信息聚合、标题聚合有列表页,点开一个标题有详细页,而这些站点都是耦合在一个程序中的,或者说耦合在一个站点中的,当咱们有一个站点出现问题的时候,整个站点就会由于耦合一块儿出问题。

  第二个问题,你们都知道作数据库读请求和写请求,分布在不一样的数据库上,这个时候若是再读取可能读到的是旧数据,由于读写有一个延时。若是有用 户发帖子,立刻去找的话确定找不到,极可能带来的后果就是陆续在发布两条信息,这就是一个很大的问题。尤为是在请求量愈来愈大的时候,这个问题就更加突 出。

  在解决这些问题是,最早想到的是针对原来站点的核心业务作切分,而后工程师根据本身的站点和业务场景进行细分。首先,业务拆分是 58 同城最早尝试的优化。咱们将业务垂直拆分红了首页和发布页。另外,在数据库层面,咱们也随之进行了拆分,将大数据量拆分红一个个小的数据量。这样,读写延 时就立刻获得了缓解。尤为是在代码拆分红了不一样的层面以后,站点耦合也获得了缓解,数据量加载速度也提高了不少。

  当时,还使用了一些技术,前面也提到了对动态资源和静态资源进行拆分。其中,咱们对静态资源使用了 CDN 服务,便于数据缓存和就近访问,访问速度获得很明显的提高。除此以外,咱们还使用了 MVC 模式,擅长前端的去作展现层,擅长协做逻辑的工程师就作 Controller,擅长数据的人就负责数据,效率就会逐步的提升,最后就是负载均衡技术。

  大流量:将整个 Windows 技术体系转向了 Java 体系

  流量愈来愈大,当流量超过一千多万时,58 同城面对最大的问题就是性能和成本。此前,我提到58同城最初的技术选型是 Windows,应该是在 2006 年的时候,整个网站的性能变得很是之低。即便进行了业务拆分和一些优化,可是依然解决不了这个问题,因此咱们当时作了一个很是艰难的决定,就是转型:将整 个 Windows 技术体系转向了 Java 体系,这涵盖了操做系统、数据库等多个维度。

  其实,如今不少大的互联网公司在流量从小到大的过程当中都经历过转型,包括京东、淘宝等等。对技术的要求愈来愈高,任何一个站点都不能挂,对站点的可用性要求也是愈来愈高。

  就在这个时候,58同城业务量也出现一个爆发期。因而咱们招聘了不少的工程师,你们一块儿写愈来愈多的站点,可是发现效率很低,常常作一些重复性 的工做,好比参数解析等等。同时,业务之间相互依赖,不管是分类的子系统仍是信息的子系统,二手车业务、房产业务都要访问用户和信息等一些底层数据,代码 之间频繁的沟通,效率也不可能很高。

  问题随之而来,站点数愈来愈多,数据量愈来愈大,机器数从最开始的几台上升到几百台的级别。那么如何提供整个架构的可用性呢?首先,在上层咱们进行了一些改进和优化,再作进一步的垂直拆分,同时咱们引入了 Cache,以下图所示:

  在架构的改进上,咱们构建了一个相对独立的服务层,这个服务层作的每一个业务线都会写对应的代码。若是用户发出请求,就由这个服务层统一来管理, 全部的上游业务线就像调用本地函数同样,经过 IDC 的框架来调用这个服务。整个用户登陆先访问 Cache,若是 Cache 命中了就直接返回,若是 Cache 不命中,就会访问数据库,这样把数据库的数据拿到本地再放回 Cache,再打回上一轮。如此一来,业务逻辑所有封装在这个服务的上游管理,该业务逻辑只有服务层可以编写代码,而后由这个服务层集中管理、集中优化, 这样就提升了效率。

  除此以外,为了保证站点的高可用,咱们主要使用了反向代理技术。由于用户而言,他主要为了使用58同城的服务,他不关注访问是58同城或者有十 台首页的服务器。58同城经过反向代理技术,经过 DNS 群,经过 LVS 技术,来保证接入层的高可用性,同时还保证了服务层、站点层、数据层的高可用。另外,为了保证高可用咱们常用冗余的方法,不管是站点服务和数据服务都 可使用这种方式进行解决,一个站点不可用,咱们就换一个站点,一个数据库不够用,咱们就多加几个。固然,数据冗余也会带来一些反作用,若是数据量更新的 话,那就须要将全部的“冗余”都要进行更新。

  58同城也作了一个图片存储系统,开始都是存储在操做系统之上,随着新增站点、新增服务,压力就变得愈来愈大。因而,58同城就自建了站点框架和服务框架,如今这两个框架也已经开源(如何下降站点开发成本?https://github.com/58code/Argo 如何下降服务开发成本? https://github.com/58code/Gaea )只须要修改一些基本的配置就可使用了。

  当架构变成「蜘蛛网」,人肉已很难搞定!

  随着用户量、数据量并发量进一步的增加,58同城也拓展了不少的新业务,那么对产品迭代速度要求就很是高,总体的架构对自动化的要求愈来愈高。

  为了支撑业务的发展,技术团队对架构作了进一步的解耦,另外就是引入了配置中心,若是要访问任何一个服务,不会直接在本地的配置中留下一个服 务,配置中心告诉这个服务的特色,若是扩展的话,配置中心自动下达消息,若是有机器要下线的话,配置中心会反向经过发邮件的方式进行通知。

  而柔性服务是指当流量增长的时候,自动的新增服务。能够看到进一步解耦以后,有垂直业务、无线业务、集成业务等等,这些子系统之间都是经过配置中心相应之间发生关系的。

  另外一点就是关于数据库,当某一点成为一个业务线重点的时候,咱们就会集中解决这个点的问题。最初期的时候每一个业务线都要访问数据库,访问缓存, 访问用户数据,因而咱们把代码集中的放到了服务层。如今数据量愈来愈大,你们都要作数据切分,每一个业务线都作切分,这个时候58同城的每一个页面都面对这样 的痛点,因而把这个痛点拿到集中的层面来解决。

  最后一点就是效率矛盾,此时不少问题,靠「人肉」已经很难进行搞定了。这就须要自动化,包括回归、测试、运维、监控等等都要回归到自动化。

  这里须要补充一点,就是在产品层面,咱们引入了智能化,好比说智能推荐,主动推荐一些相关的话题;智能广告,经过一些智能的策略,让用户对广告 的点击更多,增长对58同城的收入;智能搜索,在搜索的过程当中加入一些搜索的策略,能够提升搜索的权重,也能够增长58同城的 PV。固然,全部的自动化的产品背后都是由技术在驱动。

  将来的挑战

  如今,58同城的流量已经突破的10亿的量级,那么架构上将来面临哪些挑战呢?一方面是无线化、移动化。另外一方面就是需求的变化,咱们必须加快 迭代一些东西。若是拥有10亿的流量,却跑在一亿的架构上确定是不行的。将来,咱们会使用更多的并行计算、实时计算,若是能作到实时推荐,效果确定很是 好,这也是咱们的挑战。最后一点,58同城如今的服务器大概在3000台左右,将来将拓展到1万台,这就是运维的挑战了。

  总结:

  最后作一个小的总结,网站在不一样的阶段遇到的问题不同,而解决这些问题使用的技术也不同,流量小的时候,咱们主要目的是提升开发效率,在早 期要引入 ORM,DAO 这些技术。随着流量变大,使用动静分离、读写分离、主从同步、垂直拆分、CDN、MVC 等方式不断提高网站的稳定性。面对更大的流量时,经过垂直拆分、服务化、反向代理、开发框架(站点/服务)等等,不断提高高可用。在面对上亿级的更大流量 时,经过中心化、柔性服务、消息总线、自动化(回归,测试,运维,监控)来迎接新的挑战。将来的就是继续实现移动化,大数据实时计算,平台化…

相关文章
相关标签/搜索