架构师训练营 - 第四章 - 学习总结
第四章的课程主要讲解关于系统架构的设计思路。
之前在公司一直也在接触这块,一部分内容还是比较熟悉的,学起来也算轻松。
系统结构的发展基本是伴随着公司发展走的。
一般系统结构能满足公司业务当前以及未来一到两年的需求已经足够,再多的设计就可能是工程师自己的臆想,对公司起不到积极作用,有些时候还可能拖累业务发展。
初创期
一般公司初创的时候特征,业务量很小、用户少、数据少、访问量也少。这个阶段基本是没有什么性能压力的,就拿我们公司早期举例,四年前平台基本一天只有10W不到的交易额。这个阶段基本就是最简单的结构,一个应用服务器,一个数据库服务器。
应用快速开发迭代,快速试错。
发展初期
公司再发展一定的阶段,业务找到了突破口,用户也积累也突破了10W大关,日活的用户可能已经突破了1W。访问量上来了,数据量也到达了新的量级。
一开始的性能压力,往往可以通过简单的增加机器性能解决。
这也是最快解决性能问题的办法,一般初创期的公司面对性能问题,直接增加硬件是个不错的选择,在业务还不明朗,机器性能潜力还很大的时候没必要搞很复杂的系统结构。
当然,如果增加硬件已经不足以解决性能问题,可以考虑以下几个方案:
数据缓存,数据库读写分离和文件静态化。
大部分的网站都是读多写少。比如电商网站,用户可能浏览上百次才会有一次下单。
以上几种都是读多写少的性能优化方式:
1·数据库读写分离,主要是通过增加数据从库的方式分担用户的读取压力。
2·数据缓存,是通过将热点数据装入高性能缓存的方式来减少数据库的访问。
3·文件静态化,则是将动态页面直接静态化,从而减少对数据库的访问。
这些手段,基本都集中在减轻数据库的压力层面。因为系统的最底层都是基于关系型数据库。关系型数据库在面对大量访问请求时,往往力不从心,数据库的负载过高的话,又会导致数据无法写入等一系列问题,从而影响整个网站的使用,导致用户流失。
拿到第一笔融资
之后一段时间,公司业务进一步发展,系统的负载也越来越大,可能经常出现服务器挂机的情况,用户可能经常抱怨系统无法使用。
面对对系统可用性的要求,可以考虑引入负载均衡,将流量分配到后端多个应用服务器上,结合负载均衡的可用性检测和容量规划,及时剔除出现问题的应用服务器,增加系统的可用性。
数据库一般结合副本备份的方式来提高可用性,数据从主实例数据时时同步到副本实例,如果主实例出现问题,及时切换到副本实例。
数据库从库可以使用一个数据库代理,类似应用服务器的负载均衡,提高数据库从库的可用性。
当然,关于数据库的可用性问题,在当前云计算的时代,直接使用云提供商的高可用数据库实例是一个很不错的选择。
有一笔融资进账,公司进入新阶段
公司继续发展到下一个阶段。用户的范围越来越大,很多用户开始抱怨网站访问速度慢。
静态资源
这个时候要分辨下,一般第一次遇到用户反馈访问比较慢,很大可能是用户端需要加载的静态资源过多,比如电商网站的商品图、店铺图,网站基本的素材图片,前端使用的大js文件等。
遇到这类问题,第一件事应该先考虑文件压缩。
将前端的js文件压缩成无格式,图片在保证效果的前提下压缩体积,这些手段能减轻不少的流量压力。
同时可以考虑开启nginx的gzip压缩,当然这会引起nginx服务器的cpu升高,使用的时候需要注意服务器的性能表现。
如果上述手段已经做过了,那么进一步提升用户访问速度,可以考虑将静态资源做cdn。
cdn可以将静态资源分配到网络中的各个节点,让用户访问离他最近的节点。一方面减轻了服务网关本身的流量压力,另一方面提高了系统的访问速度。
动态数据
针对后端数据的访问压力,要进一步提高后端的性能。
一方面可以考虑增加缓存的性能,采用集群化缓存服务,增加数据缓存规模。
数据库方面采用分片、分库、分表等手段,将数据分摊到多个数据节点上。
业务上可以引入消息队列,将一些请求中不需要同步响应的动作异步化,从而加快接口响应。
这个时候,个人体会比较深的是,因为前期业务的快速开发,系统的数据库拆分面对比较麻烦的问题,因为系统往往不止给前端用户提供服务,还给后端运营人员、boss等提供服务,运营人员看到的页面往往是聚合页面,可能是聚合了很多维度数据的统计报表。
技术人员为了加快速度,希望分库分表,但是对于聚合查询页面,分库分表后就是个大麻烦。
面对这种问题,我们的处理方式是将之前的聚合页面重构,一部分报表交由bi部门,一部分单独开发一个数据聚合服务。将多个维度的数据,根据查询需求聚合到一个共同的数据中心,这个数据中心可以采用mongodb等海量存储服务。
聚合查询列表单独走数据聚合服务,不需要再分别查询各个服务的数据做聚合。一方面提高了数据聚合查询的体验,更重要的是解放了业务开发。
业务开发可以按照实际的业务线,划分出不同的服务,每个服务采用独立的数据库,将数据库压力分摊,也走出了服务化拆分的一步。
多机房
如果面对分布区域很广泛的用户群体。
可以考虑采用智能dns的方式,将用户的请求分流到离自己比较近的机房。由最近的机房访问,可以降低用户请求在网络上延迟,提高用户体验。
同时提高系统的可用性,防止出现系统性的灾难,比如地震火灾,造成一个地区的机房毁灭性的不可用。
独角兽或者巨头
这个规模的公司,我还没有经历过,只能算是臆想吧。
到了这个阶段,公司的发展需要从业务和分工上做进一步的拆分。
根据业务将系统拆分成多个独立的服务,服务由独立的部门负责,独立发展。
同时在分工上,将基础开发和业务开发分离,基础开发深入系统的基础结构研发,比如服务通信,数据同步等,业务开发则专注于需求的承接和推进。
其他
当业务体量巨大,业务链路越来越长,分支越来越多。可以考虑引入消息服务,基于事件驱动的逻辑,在系统中引入事件机制,各个服务响应事件来完成业务。
这样做可以实现服务的逻辑解耦,加快业务开发速度。
如果网站需要搜索服务,可以考虑引入搜索引擎。
一般非专业搜索系统可以考虑基于es或者solr开发搜索服务。
评论