标签:java rip 资源分配 节点 相对 无法 大致 基础 最大
架构设计的演进过程业务驱动技术的发展是亘古不变的道理。最开始的时候,业务量少,业务复杂度低,采取的技术也相对简单,基本满足用户对功能的需求。随着IT信息化的普及,更多的交易放到了网络上,信息量增加和访问次数频繁就是要解决的问题了。因此,逐渐加入了缓存、集群等技术手段。同时对业务的扩展性和伸缩性的要求也越来越高。高并发、高可用、可伸缩、可扩展、够安全的软件架构一直是架构设计追求的目标。今天我们来看一下架构设计经历了哪些阶段,每个阶段都解决了哪些问题,又引出了哪些新问题。主要是引起大家的思考,在不同的业务发展阶段采取合适技术手段,用变化拥抱变化是IT人追求的目标。
最早的业务应用以网站、OA等为主,访问的人数有限,单台服务器就能够应付。通常,将应用程序和数据库部署到一台服务器上面,如图1-1所示。在这一阶段,我们利用LAMP(Linux Apache MySQL PHP)技术就可以迅速搞定,并且这些工具都是开源的。很长一段时间内,有各种针对这种应用模式的开源代码可以使用。这种模式基本上没有高并发的要求,可用性也很差。有的服务器采用托管模式,上面就安装了不同的业务应用,一旦服务器出现问题,所有的应用就罢工了。不过其开发和部署成本相对较低,适合刚刚起步的应用服务。图1 就描述了单个应用和数据库运行在单台服务器的模式,我们称这种模式为应用与数据一体模式。
图 1 应用与数据一体模式
随着业务的发展,用户数和请求数逐渐上升,服务器的性能出现了问题。其中比较简单的解决方案就是增加资源,将业务应用和数据存储分开,其架构图如图2所示。其中,应用服务器需要处理大量的业务请求,对CPU和内存有一定要求;而数据库服务器需要对数据进行存储和索引等IO操作,对磁盘的转速和内存会考虑更多。这样的分离解决了性能的问题,我们需要扩展更多的硬件资源让其各司其职,使系统可以处理更多的用户请求。虽然业务上依旧存在耦和,但硬件层面的分离在可用性上比一体式设计要好很多。
图2 应用与数据分离模式
随着信息化系统的发展和使用互联网人数的增多,业务量、用户量、数据量都在增长。我们同时发现,用户会对某些数据的请求量特别大,例如新闻、商品信息和热门消息。之前这些信息的获取方式是依靠数据库,因此受到数据库IO性能的影响。此时数据库成为了整个系统的瓶颈。如果再增加服务器的数量,恐怕也很难解决,于是缓存技术就登场了,其架构图如图3所示。这里提到的缓存技术分为客户端浏览器缓存、应用服务器本地缓存和缓存服务器缓存。
经过前面三个阶段的演进,系统对用户的请求量有了很好的支持。实际上,这都是在解决高性能和可用性的问题,这一核心问题会一直贯穿整个系统架构的演进过程中。随着用户请求量的增加,另外一个问题又出现了,那就是并发。把这两个字拆开了来看:并,理解为“一起并行“,有同时的意思;发,理解为“发出调用”,也就是请求的意思。合起来就是多个用户同时请求应用服务器。如果说原来的系统面对的仅仅只是大数据量的话,那么现在就需要面对多用户同时请求。如果还是按照上一个阶段的架构图推导,单个应用服务器已经无法满足高并发的要求了。此时,服务器集群就加入战场了,其架构图如图4所示。服务器集群也就是多台服务器扎堆的意思,用更多的服务器来分担单台服务器的负载压力,提高性能和可用性。再说白一点,就是提高单位时间内服务处理请求的数量。原来是一个服务器处理,现在是一堆服务器来处理。就好像银行柜台一样,增加柜员的人数来服务更多的人。
图4服务器集群的加入
这次架构演进与上次相比,增加了应用服务器的个数,用多台应用服务器形成集群。应用服务器中所部署的应用服务没有改变,在用户请求与服务器之间加入了负载均衡器,帮助用户请求路由到对应的服务器中。增加服务器的举动表明,系统的瓶颈是在处理用户并发请求上。针对数据库和缓存都没有做更改,这样仅仅通过增加服务器数量就能够缓解请求的压力。服务器集群会通过多台服务器来分担原来一台服务器需要处理的请求,在多台服务器上同时运行一套系统,因此可以同时处理大量并发的用户请求。有点三个臭皮匠顶个诸葛亮的意思,因此对集群中单个服务器的硬件要求也会降低。此时需要注意负载均衡均衡的算法,例如轮询和加权轮询。我们要保证用户请求能够均匀分布到服务器上面,同一个会话的请求保证在同一个服务器上面处理,针对不同服务器资源的优劣动态调整流量。负载均衡器加入之后,由于其位于互联网与应用服务器之间,负责用户流量的接入,因此可以对用户流量进行监控,同时对访问用户的身份和权限进行验证。
加入缓存可以解决部分热点数据的读取,但缓存数据的容量有限,那些非热点的数据依旧会从数据库中读取。数据库对于写入和读取的性能是不一样的。在写入数据的时候,会造成锁行或者锁表,此时如果有其他写入操作并发执行,会存在排队现象。而读取操作比写入操作更加快捷,并且可以通过索引、数据库缓存等方式实现。因此,推出了数据库读写分离的方案,其架构图如图5所示。此时设置了主从数据库,主库(master)主要用来写入数据,然后通过同步binlog的方式,将更新的数据同步到从库(slave)中。对于应用服务器而言,在写数据的时候只需要访问主库,在读数据的时候只用访问从库就好了。
图5 数据库读写分离
利用数据库读写分离的方式,将数据库的读/写职责分离。利用读数据效率较高的优势,扩展更多的从库,从而服务于读取操作的用户请求。毕竟在现实场景中,大多数操作都是读取操作。此外,从数据同步技术的角度来说,又可以分为同步复制技术、异步复制技术和半同步复制技术。在数据库读写分离带来益处的同时,架构也需要考虑可靠性的问题。例如,主库如果挂掉,从库如何接替主库进行工作。主库在恢复以后,是成为从库还是继续担当主库,以及如何同步数据的问题。
随着互联网的逐渐普及,人们对网络安全和用户体验的要求也越来越高。之前用户都是通过客户端直接访问应用服务器获取服务,应用服务器会暴露在互联网中,容易遭到***。如果在应用服务器与互联网之间加上一个反向代理服务器,它接收用户的请求,然后再转发到内网的应用服务器,充当外网与内网之间的缓冲。反向代理服务器只是做请求的转发,在它上面没有运行任何应用,因此当有人***它的时候,是不会影响到内网的应用服务器的。这无形中保护了应用服务器,提高了安全性。同时,它也在互联网与内网之间起到适配和网速转换的作用。例如,应用服务器需要服务公网和教育网,但是两个网络的网速不同,可以在应用服务器与互联网之间放上两台反向代理服务器,一台连接公网,另一台连接教育网,屏蔽网络差异,服务于更多的用户群体。如图6 公网客户端和校园网客户端分别来自公网与校园网两个不同的网络,由于两个网络访问速度不同,因此会针对两个网络分别设置共网代理服务器和校园网代理服务器,通过这种方式将位于不通网络的用户请求接入到系统中。
图6加入反向代理服务器
聊完反向代理,再来说说CDN,它的全称是Content Delivery Network,也就是内容分发网络。如果把互联网想象成一张大网的话,每个服务器或者客户端就是分布式在网中的一个节点。节点之间的距离有远有近,用户请求会从一个节点跳转到另外一个节点,最终跳转到应用服务器获取信息。如果跳转的次数越少,就能够更快地获取信息,因此可以在离客户端近的节点存放信息。这样用户通过客户端,只需要较少的跳转次数就能够触达信息。由于这部分信息更新频率不高,推荐存放一些静态数据,例如JavaScript文件、静态的HTML、图片文件等。这样客户端就可以从离自己最近的网络节点获取资源,大大提高了用户体验和传输效率。加入CDN后的架构图如图7所示。
图7 加入CDN
CDN的加入明显加快了用户访问应用服务器的速度,同时也减轻了应用服务器的压力,原来必须直接访问应用服务器的请求,不用经过层层网络,而只用找到最近的网络节点就可以获取资源。但从请求资源的角度上来看,这种方式也有局限性,它只能对静态资源起作用,需要定时对CDN服务器进行资源更新。反向代理和CDN的加入解决了安全性、可用性和高性能的问题。
经历前面几个阶段以后,软件的系统架构相对趋于稳定。随着系统运行时间的增加,数据库中累积的数据越来越多,同时系统还会记录一些过程数据,例如操作数据和日志数据,这些数据也会加重数据库的负担。即便数据库设置了索引和缓存,但在海量数据查询的时候还会捉襟见肘。如果说读写分离,是将数据库从读写层面进行资源分配,那么分布式数据库就需要从业务和数据层面对资源进行分配。
当解决大数据量存储问题以后,系统就能够存储更多的数据,这意味着能够处理更多的业务。业务量的增加,访问数的上升,是任何一个软件系统在任何时期都要面临的严峻考验。通过前面几个阶段的学习,我们知道系统提升基本依靠空间换取时间,使用更多的资源和空间处理更多的用户请求。随着业务的复杂度越来越高,以及高并发的来临,一些大厂开始将业务系统进行切分,分开部署,此时的架构图如图10所示。如果说前面的服务器集群模式是将同一个应用复制到不同的服务器上,那么业务拆分就是将一个应用拆成多个部署到不同的服务器中。此外,还可以对核心应用进行水平扩展,将其部署到多台服务器上。应用虽然做了拆分,但应用之间仍旧有关联,存在应用之间的调用、通信和协调问题。由此也会引入队列、服务注册发现、消息中心等中间件,它们可以协助系统管理分布到不同服务器、网络节点上的应用。
图9业务拆分
业务拆分以后会形成一个个应用服务,既有基于业务的服务,例如商品服务、订单服务,也有基础服务,例如消息推送和权限验证。这些应用服务连同数据库服务器分布在不同的容器、服务器、网络节点中,对它们的通信、协调、管理和监控都是我们需要解决的问题。
近几年,微服务是比较火的架构方式,它将业务应用进行更加精细化的切割,使之成为更加小的业务模块。做到模块的高内聚低耦合,每个模块可以独立存在,由独立的团队维护。每个模块内部可以采取特有的技术,而不用关心其他模块的技术实现。模块通过容器的部署运行,模块之间通过接口和协议进行调用。任何一个模块都可以将自己公开给其他的模块调用。同时可以将热点模块进行水平扩展,增强系统的性能。当其中某一个模块出现问题时,又可以由其他相同的模块代替其工作,增强了可用性。
大致总结下来,微服务拥有以下特点,业务精细化拆分、自治性、技术异构性、高性能、高可用。它像极了分布式架构,下面来看看它们的区别,如图10所示。
从概念上理解,它们都做了“拆”的动作,但在下面这几个方面存在区别。
本文按照技术跟随业务变化的思路,描述从单体架构到集群,再到分布式架构以及微服务的发展阶段。讲述了每个软件架构阶段变化的特点,前后架构更替的原因和关系,说明了软件架构发展会一直随着业务发展的方向变化。遵循高性能,高可用,伸缩性,扩展性,安全性的架构目的。
标签:java rip 资源分配 节点 相对 无法 大致 基础 最大
原文地址:https://blog.51cto.com/14279308/2476567