系统架构演进历史

1,990 阅读9分钟

项目演进历史

本篇小编主要介绍架构演进的历史,现在是互联网时代,互联网时代架构具有高并发,高可用,大数据,迭代周期短,用户量大,可持续发展,安全级别高,架构可弹性伸缩等特点。从而为了适应互联网发展,架构选型也发生了不断更迭变化。

初始化单机架构

网站、系统应用最初,应用数量和用户数量比较少,我们可以将应用和数据库部署到同一台服务器。

但是:用户增长后,应用服务和数据库之间会竞争资源,单机性能就不会不足以支撑系统网站运行。

tomcat服务与数据库分离部署

将数据库和tomcat服务分开部署到两台服务器上,两者分别独占服务器资源,可以显著提高两者各自性能

但是:当用户量继续增长,对数据库并发读写的增多,是单节点的数据库成为瓶颈。

引入分布式缓存处理

引入分布式缓存的概念,可以缓存热门的信息和页面,通过分布式缓存,将绝大部分请求拦截到访问数据库之前,从而降低数据库的访问压力。

技术点:使用memcached作为本地缓存,redis作为分布式缓存,但同样也增加了缓存一致性,缓存穿透,缓存雪崩,及热点数据的集中失效的问题。

虽然利用缓存抗住了对数据库的访问请求,降低了数据库的压力,但是随着用户的增长,并发压力在tomcat服务器上的响应就会变慢。

反向代理实现负载均衡

我们在多台服务器上部署tomcat节点服务,使用反向代理软件nginx,HAproxy,将请求分发到每个tomcat,此处假设tomcat最多支持100个并发,但NGINX可以支持5000个并发,理论上NGINX可以将并发请求分发到50个tomcat节点上,这样就能抗住高并发。

技术点:NGINX,HAproxy两者都是工作在网络第七层的反向代理软件,主要支持http协议,但是需要解决session共享,文件上传下载的问题。

虽然:服务器可支持的并发量大大增加,但是并发增加也就意味着有更多请求会同时请求数据库,此时单节点的数据库就会成为制约瓶颈。

数据库读写分离

将数据库分为读库和写库,读库可以为多个,通过mysql的数据同步机制将写入的数据同步到多个读库上,查询的数据分为最新数据可从缓存中读取,历史大数据量从读库中进行读取

引入技术点:mycat为数据库中间件,可以有效组织多个数据库的读写,进而实现数据在垂直层面的切分,或在客户端层面引入sharding-jdbc进行客户端层面的读写分离。

缺陷:对于业务比较简单的架构体系,至此已能完成绝大部分业务,但是如果业务复杂,具有多个业务会出现同时竞争数据库从而导致相互影响性能。

按业务分库

将不同的业务数据保存到不同的数据库中,实现数据存储读写的各自业务分离,从而解决业务之间资源竞争的压力过大,通过部署更多的服务器来支撑不同业务。但是同样多个业务直接调用分析就需要通过其他途径来进行解决。

缺陷:随着系统数据量的激增,单机环境下的写库操作就会达到性能瓶颈。

表数据拆分

随着数据量的激增,单表写库操作会很难应对大数据量的写入,这个时候我们就要引入分区分表的概念,对数据库做横向和纵向的数据切分,针对具体业务,按照日期,hash进行切分建表,将一个大表数据拆分成多个小表数据,通过id或者hash路由进行数据写入的寻址,只要实时操作的表数据量足够小,就能够将数据平均分发到多台服务器上,这样数据库就可以在水平方向实现扩展,从而提高数据写性能。

缺陷:数据库和tomcat服务的水平扩展,使并发量得到大幅度提升,但是用户量的继续猛增,单机的NGINX又会成为制约用户访问的瓶颈。

使用LVS或F5使多个NGINX负载均衡

上文中提到NGINX又成了制约系统访问的瓶颈,因此无法通过两层的NGINX实现多个NGINX的负载均衡,因此出现了LVS和F5工作在网络第四层上负载均衡来降低NGINX的压力,其中LVS为软件运行在操作系统的内核,可以对TCP请求或者更高层级的网络协议进行转发,因此支持的协议更加丰富,性能也比NGINX要高,可以达到单机几十万的并发请求,而F5为硬件的负载均衡,功能实现与LVS类似,但是性能要比LVS高,同时价格也要更高。而工作在第七层的NGINX通过keepalived实现高可用。

缺陷:随着互联网的发展,上面这个架构作用在统一机房内,如果用户分布在不同地区,与服务器实际距离的远近又会导致访问延迟的增加。

通过DNS实现跨地域机房轮询

在DNS服务器中,通过配置多个IP地址对应一个域名,每个IP地址对应到不同的机房的虚拟IP中,当用户访问域名时,DNS服务器会使用轮询策略,选择其中一个IP地址供用户访问。从而实现机房之间的负载均衡。从而做到机房级别的水平扩展,千万级别乃至亿级的数据并发可以通过增加地域机房的方式来解决。

缺陷:数据分析,检索又制约了用户数据分析能力。

引入NOSQL和搜索引擎

当数据多到一定规模的时候,数据库就不再适用复杂查询,而只能满足普通查询。对于统计分析报表就不一定能跑出结果来,同时对于海量的非结构化数据,存储同样也需要进行检索。怎么办?就引入了分布式文件系统HDFS,以及HBASE和redis,对于全文检索就引入了ELK,对于多维场景分析,引入kylin和druid等多种解决方案。引入的组件越来越多,无形中增加了系统的复杂度,不同的数据保存在不同的场景下,有时又要考虑数据一致性问题。

瓶颈:业务系统维护升级,同时迭代更新也会逐渐增加。

微服务

将系统中的存在的多个模块,单独抽取出来形成一个个单独的服务来进行统一管理。这就是微服务,应用之间通过http、TCP等多种方式来访问微服务,同时单个服务又可以独立部署。同时又可以通过dubbo和springcloud等框架实现服务治理、熔断、降级等功能。

瓶颈:多个微服务的部署,使服务之间调用链变得非常复杂,业务逻辑也会容易变乱。

企业服务总线

通过ESB进行服务协议转换,应用通过ESB访问后端服务,服务与服务之间也通过ESB相互调用,从而降低系统内部各个服务之间的耦合度。从而也梳理了服务调用链。

这种将单个应用拆分为多个应用,公共服务单独抽取管理,使用企业消息总线来降低服务之间耦合度的架构形式我们称之为面向服务架构。

缺陷:多个服务器上的部署,运维负担增加。

容器化实现运行环境隔离和动态服务管理

目前最流行的容器化技术是Docker,容器管理服务是kubernetes(k8s),应用服务通过docker打包成镜像,然后通过K8S实现动态分发和部署。docker可以理解为一个迷你操作系统,运行环境设定好之后,打包成一个镜像,分发到需要部署的相关服务的机器上,直接启动docker就可以将服务启动从而降低部署和运维难度。

瓶颈:容器化需要的服务器需要公司进行自身管理,在大型活动过后量级下来后就会限制大量的服务器从而造成硬件浪费。

云化系统

系统部署到阿里云,这云,那云上,利用公有云的海量硬件资源,解决动态硬件资源的问题,在活动时间段临时申请更多的资源,使用docker和K8S进行快速部署服务,活动结束后释放资源,做到按需付费,从而降低资源利用。这样就延伸出来了laas(基础设施即服务),PaaS(平台即服务),SaaS(软件即服务)

注:架构设计一定遵循适用原则,切记盲目追求技术造成不必要的资源浪费。

如何进行系统架构

既然要遵循适用原则,那么如何进行系统架构呢?

背景调查
  • 系统所用技术栈
  • 团队管理流程
  • 需求开发模式
  • 系统当前所处的架构阶段
  • 业务面临难点
  • 寻找业务复杂点
    • 高性能
    • 高可用
    • 扩展性
    • 成本
    • 安全性
基于问题本身调查
  • 制定方案

    • 时间成本,技术成本,用户需求急迫程度
    • 一定要做备选方案
  • 评估选择

    • 最简派:基于时间
    • 最牛派:炫技,甲方项目
    • 最熟派:从成本考虑
    • 领导派:权衡利弊

接下来小编会对JUC进行一周连载,另外经过长达半年多的准备已对从java基础到单体应用到微服务到ci\cd企业级技术栈已整理完毕,请扫描下图关注个人公众号,第一时间索取相关资料