看透Spring MVC:源代码分析与实践
上QQ阅读APP看书,第一时间看更新

1.5 高并发的解决方案

除了数据量大,另一个常见的问题就是并发量高,很多架构就是针对这个问题设计出来的,下面分别介绍。

1.5.1 应用和静态资源分离

刚开始的时候应用和静态资源是保存在一起的,当并发量达到一定程度时就需要将静态资源保存到专门的服务器中,静态资源主要包括图片、视频、js、css和一些资源文件等,这些文件因为没有状态,所以分离比较简单,直接存放到相应的服务器就可以了,一般会使用专门的域名去访问,比如,新浪的图片保存在sinaimg.cn域名对应的服务器中,而百度的图片则是通过imgsrc.baidu.com二级域名访问的,通过不同的域名可以让浏览器直接访问资源服务器而不需要再访问应用服务器了,这时的架构如图1-8所示。

图1-8 应用和静态资源分离架构图

1.5.2 页面缓存

页面缓存是将应用生成的页面缓存起来,这样就不需要每次都重新生成页面了,从而可以节省大量CPU资源,如果将缓存的页面放到内存中速度就更快了。如果使用了Nginx服务器就可以使用它自带的缓存功能,当然也可以使用专门的Squid服务器。页面缓存的默认失效机制一般是按缓存时间处理的,当然也可以在修改数据之后手动让相应缓存失效。

多知道点

有部分经常变化的数据的页面怎么使用页面缓存

页面缓存主要是使用在数据很少发生变化的页面中,但是有很多页面是大部分数据都很少发生变化,而其中有很少一部分数据变化的频率却非常高,比如,一个显示文章的页面正常来说是完全可以静态化的,但是如果在文章后面有“顶”和“踩”的功能而且显示的有相应的数量,这个数据的变化频率就比较高了,这就会影响静态化,在电商系统中显示商品详情的页面中的销售数量也是这种情况,对于这个问题可以先生成静态页面然后使用Ajax来读取并修改相应的数据,这样就可以一举两得了,既可以使用页面缓存也可以实时显示一些变化频率高的数据了。

1.5.3 集群与分布式

集群和分布式处理都是使用多台服务器进行处理的,集群是每台服务器都具有相同的功能,处理请求时调用哪台服务器都可以,主要起分流的作用,分布式是将不同的业务放到不同的服务器中,处理一个请求可能需要用到多台服务器,这样就可以提高一个请求的处理速度,而且集群和分布式也可以同时使用,结构图如图1-9所示。

集群有两个方式:一种是静态资源集群。另一种是应用程序集群。静态资源集群比较简单,而应用程序集群就有点复杂了。因为应用程序在处理过程中可能会使用到一些缓存的数据,如果集群就需要同步这些数据,其中最重要的就是Session,Session同步也是应用程序集群中非常核心的一个问题。Session同步有两种处理方式:一种是在Session发生变化后自动同步到其他服务器,另外一种方式是用一个程序统一管理Session。所有集群的服务器都使用同一个Session,Tomcat默认使用的就是第一种方式,通过简单的配置就可以实现,第二种方式可以使用专门的服务器安装Memcached等高效的缓存程序来统一管理Session,然后在应用程序中通过重写Request并覆盖getSession方法来获取指定服务器中的Session。对于集群来说还有一个核心的问题就是负载均衡,也就是接收到一个请求后具体分配到哪个服务器去处理的问题,这个问题可以通过软件处理也可以使用专门的硬件(如F5)解决。

图1-9 应用程序分布式集群结构图

另外笔者还想到了一种思路可以简单地解决Session同步的问题,Session需要同步的本质原因就是要使用不同的服务器给同一个用户提供服务,如果负载均衡在分配请求时可以将同一个用户(如按IP)分配到同一台服务器进行处理也就不需要Session同步了,而且这种方法一般也不会对负载均衡带来太大的问题,如果考虑到稳定性,为了防止有机器宕机后丢失数据还可以将集群的服务器分成多个组,然后在小范围的组(如2、3台服务器)内同步Session。

架设分布式应用程序是一件非常复杂的事情,Session同步肯定是需要的,分布式事务处理和各个节点之间复杂的依赖关系也是分布式中非常复杂的问题,如果要使用分布式一定要做好足够的准备。

1.5.4 反向代理

反向代理指的是客户端直接访问的服务器并不真正提供服务,它从别的服务器获取资源然后将结果返回给用户的,如图1-10所示。

图1-10 反向代理服务器

多知道点

反向代理服务器和代理服务器的区别

代理服务器的作用是代我们获取想要的资源然后将结果返回给我们,所要获取的资源是我们主动告诉代理服务器的,比如,我们想访问Facebook,但是直接访问不了,这时就可以让代理服务器访问,然后将结果返回给我们。

反向代理服务器是我们正常访问一台服务器的时候,服务器自己调用了别的服务器的资源并将结果返回给我们,我们自己并不知道。

代理服务器是我们主动使用的,是为我们服务的,它不需要有自己的域名;反向代理服务器是服务器自己使用的,我们并不知道,它有自己的域名,我们访问它跟访问正常的网址没有任何区别。

反向代理服务器可以和实际处理请求的服务器在同一台主机上,而且一台反向代理服务器也可以访问多台实际处理请求的服务器。反向代理服务器主要有三个作用:①可以作为前端服务器跟实际处理请求的服务器(如Tomcat)集成;②可以用做负载均衡;③转发请求,比如,可以将不同类型的资源请求转发到不同的服务器去处理,可以将动态资源转发到Tomcat、Php等动态程序而将图片等静态资源的请求转发到静态资源的服务器,另外也可以在url地址结构发生变化后将新地址转发到原来的旧地址上。

1.5.5 CDN

CDN其实是一种特殊的集群页面缓存服务器,它和普通集群的多台页面缓存服务器比主要是它存放的位置和分配请求的方式有点特殊。CDN的服务器是分布在全国各地的,当接收到用户的请求后会将请求分配到最合适的CDN服务器节点获取数据,比如,联通的用户会分配到联通的节点,电信的用户会分配到电信的节点;另外还会按照地理位置进行分配,北京的用户会分配到北京的节点,上海的用户会分配到上海的节点。CDN的每个节点其实就是一个页面缓存服务器,如果没有请求资源的缓存就会从主服务器获取,否则直接返回缓存的页面。CDN分配请求的方式比较特殊,它并不是使用普通的负载均衡服务器来分配的,而是用专门的CDN域名解析服务器在解析域名的时候就分配好的,一般的做法是在ISP那里使用CNAME将域名解析到一个特定的域名,然后再将解析到的那个域名用专门的CDN服务器解析到相应的CDN节点,结构图如图1-11所示。

图1-11 CDN结构图

第二步访问CDN的DNS服务器是因为CNAME记录的目标域名使用NS记录指向了CDN的DNS服务器。CDN的每个节点可能也是集群了多台服务器。CDN的原理并不复杂,不过如果要自己去架设则需要投入大量的资金,现在有专门的CDN服务商,可以直接购买它们的服务。