一个成熟的系统,并不是一开始就做到方方面面都完美,也不会去考虑什么高并发,高可用问题,但随着时间的推移,现有架构的问题就会慢慢的显现。比如用户激增,访问量不断增大,在这过程中 ,会不断的出现新的问题,而为了解决这些问题,软件技术架构都会发生重大变化,而针对不同业务特征的系统会有各自的侧重点,像淘宝这类网站要解决的事海量商品搜索 下单支付等问题。像腾讯 要解决数亿级别用户的实施消息传输等。每种业务都有自己不同的系统架构。

以Java Web 为例 搭建简单的电商系统这个电商系统有多个业务模块,假设现在有:用户模块、商品模块、支付模块

阶段一、 单体架构

在网站初期, 经常在单机上跑所有的程序,所有的功能都在一个jar里,数据库和应用在一台服务器上,初期讲究的事效率,在互联网初期,用户量不多的时候,单体架构也能支撑使用。

阶段二、应用服务器和数据库服务器分离

随着网站的上线,访问量的增加,对服务器的性能要求也在向上增加,web服务器主要是用来处理网络连接和资源请求的,因此要求就是高带宽,高并发,对CPU的要求其实不高,对内存的要求高,然而为web服务器所做的优化显然不适合数据库服务器。数据库服务器的主要职责是处理SQL语句,管理磁盘上存储的数据,要求大量的磁盘IO,对缓冲池要求极高,总之,web服务器和数据库服务器定位不同,优化点也不同,强行放一起会严重影响两者的性能,于是,慢慢的,服务器和数据库,选择分开部署。

阶段三 应用服务器集群,应用服务器负载吃紧

随着时间推移,网站访问量继续增加,单台服务器的性能已经无法满足需求,假如数据库服务器没有达到瓶颈,我们可以增加应用服务器,通过应用服务器集群将用户的请求分流到各个服务器上,从而提高负载能力,我们可以使用Nignx的反向代理,负载均衡,去使用户的请求到达各个集群服务器。此时服务器间没有直接交互,都是通过数据库各自对外交互。

阶段四,数据库压力变大, 数据库实行读写分离

架构演变到这里并不是终点。我们通过上面的方式把应用层的性能提升了,但是数据库的负载过大,为了提高数据的库性能 有了前面的思路 我们照猫画虎。我们开始考虑把数据库也部署集群,然后对于数据库请求,分别负载到多台机子上。但数据库做集群后,还需要解决比如数据同步、读写分离、分库分表等问题。

阶段五 使用搜索引擎环节度数据库的压力

数据库做读库的话,尝试对模糊查询效率并不好,像电商类的网站搜索是非常核心的功能,几遍做了读写分离这个问题也不能有效解决,那么这个时候就需要引入搜索引擎,使用搜索引擎能大大提高查询效率,但同时也有问题,比如索引的维护

阶段六 引入缓存机制环节数据库压力(比如热点数据 )

随着访问量的持续增加,逐渐出现许多用户访问同一部分数据的情况,对这些热点数据没必要每次都查询数据库,我们可以使用缓存技术比如 memcache redis 来作为应用层缓存,另外某些场景下 我们对用户的某些ip的访问频率做限制,那么放在内存中又不合适,放在数据库总太麻烦,这时候可以使用NoSql的方式比如 mongDB来代替传统数据库

阶段七, 数据库的水平和垂直拆分

网站演进的过程中, 用户 商品 交易的数据还在同一个数据库中,尽管采取了 缓存 读写分离的方式,但是数据库的压力持续增加,数据库的瓶颈仍是一个很大的问题,因此我们考虑对数据垂直拆分和水平拆分

垂直拆分: 把数据库中不同业务数据拆分到不同的数据库中
水平拆分:把同一个表的数据拆分到不同的数据库。

阶段八 微服务拆分

随着业务的发展,越来多应用压力大。工程规模 随着业务的发展,越来多应用导致服务器的压力越来越大,如果把所有的功能都写在了一个服务,有很多不便的地方,比如工程只要修改了一行代码,就需要对整个系统进行重新的构建、测试,然后将整个系统进行部署或者是比如商品描述的业务访问量太多导致服务挂掉,其他所有服务也跟着挂,于是,满满的,微服务架构开始流行。
根据系统业务拆分,把每个业务独立为一个工程,可以各自运行,在组合在一起为一个整体的系统,每个微服务基本上都是各自独立的项目,而对应各自独立项目的研发团队基本上也是独立对应,这样的结构保证了微服务的并行研发,并且各自快速迭代,不会因为所有研发都投入一个近乎单点的项目,从而造成开发阶段的瓶颈。开发阶段的独立,保证了微服务的研发可以高效进行。就算是其中一个服务出问题了,也不会影响其他服务的运行。

当然这知识简单的介绍,随着系统业务的不断深入,系统还可能引入更多的组件,比如说MQ,HABS等等。并不只有redis,和es。
当然互联网的发展还在继续,微服务架构并不是终点,架构的优化和演变还在不断进行着。