应用服务器性能优化
应用服务器是处理网站业务的服务器,网站的业务代码都部署在这里,是网站开发最复杂,变化最多的地方,优化手段主要有缓存、集群和异步等方式。
1、缓存
对于提高网站的性能来说,第一个想到的解决方案应该就是使用缓存。缓存用来提高网站的“读”速度。在整个网站的应用中,缓存几乎无处不在,既存在于浏览器,也存在于应用服务器和数据库服务器;既可以对数据缓存,也可以对文件进行缓存,还可以对页面片段镜像缓存。合理的使用缓存,对网站性能优化意义重大。
1.1、缓存原理介绍
缓存是将数据存储在相对较高访问速度的存储介质中,以供系统处理。一方面缓存访问速度快,可以减少数据的访问时间,另一方面如果缓存的是处理过的数据,可以节省计算时间。缓存本质是一个内存型的Hash表,数据缓存以Key、Value的形式存储在Hash表中。
计算KV中的Key的HashCode对应的Hash表索引,可快速访问Hash表中数据。Java语言中的Hashcode方法包含在根对象Object中,其返回值是int。然后通过Hashcode计算Hash表的索引下标,最简单就是余数法,使用Hash表数组长度对Hashcode求余,得到的余数即是Hash表的索引,使用该索引可直接访问Hash表中存储的KV对。如下图:
1.2、使用缓存
缓存主要用来存放读写比很高、很少变化的数据。应用程序读取数据时,先读取缓存,如果读不到或数据已失效,在访问数据库,并将数据写入缓存。网站数据访问通常遵循二八定律,即80%的访问落在20%的数据上,使用缓存将这20%的数据缓存起来,可以很好的改善系统性能,降低数据库的访问压力。
合理使用缓存可以提高系统的读效率,但是不合理的使用缓存会成为系统的累赘,甚至风险。在实践中,缓存滥用的情况屡见不鲜。
频繁修改的数据:缓存中存放的是频繁修改的数据,应用来不及读取,数据就已经失效。
没有热点的访问:如果应用系统访问数据没有热点,不遵循二八定律。
数据不一致与脏读:一般使用时,会对缓存的数据设置失效时间,一旦超时,数据就需要从数据库重新加载。应用需要能够容忍一定时间的不一致。
缓存可用性:缓存数据的丢失或者缓存本身不可用,不应该影响应用程序。
缓存预热:在系统启动时,把热点数据加载到缓存。
缓存穿透:业务请求的数据,在缓存中不存在,并且这种请求持续高并发访问,这时所有的数据都落到数据库上,对数据库造成很大的压力。
1.3、分布式缓存
分布式缓存指缓存部署在讴歌服务器组成的集群中,以集群的方式提供缓存服务。架构方式有两种,一种是JBoss Cache为代表的,数据更新时,需要同步数据,另一种是以Memcached为代表的不互相通信的分布式缓存。下图是JBoss Cache的架构图:
当某台服务器有缓存数据更新时,会通知集群中的其他机器更新或清除缓存数据。存在的问题也很明显,缓存数据的数量受限于单一服务器的内存空间,而且当缓存较大时,同步缓存的开销也很大。下图是Memcached的架构图:
Memcached采用互不通信的分布式架构,缓存与应用分离部署,缓存部署在专门的一组服务器上,应用程序通过一致性Hash等路由算法选择缓存服务器并访问缓存数据,缓存服务器之间不通信,缓存集群的规模可以很容易的扩容,具有良好的可伸缩性。
2、消息队列
使用消息队列将调用异步化, 可改善网站的“写性能”。不使用消息队列的请求过程,如下图:
用户的请求数据直接写入数据库,在高并发的情况下会对数据库造成巨大的压力,同时也使得响应延迟加剧。使用消息队列的请求过程,如下图:
使用消息队列后,用户的请求数据发送给消息队列后立即返回,再有消息队列的消费者进程从消息队列中获取数据,处理入库。用户的响应延迟得到有效的改善。
2.1、消息队列架构
点对点模型: 消息生产者向消息队列中发送一个消息之后,只能被一个消费者消费一次。如下图:
发布订阅模型:消息生产者向频道发送一个消息之后,多个消费者可以从该频道订阅到这条消息并消费。如图:
2.2、消息队列的好处
异步处理,提高处理性能
更好的伸缩性
削峰填谷
失败隔离和自我修复
解耦
2.3、常见的消息队列产品
3、集群
在网站高并发访问的场景下,使用负载均衡技术为一个应用构建服务器集群,将并发访问请求分发到多台服务器上处理,避免单一服务器因为负载压力过大而响应过慢。如下图:
三台服务器共同处理来自用户浏览器的访问请求,这样每台web服务器处理的请求只有总并发请求数的1/3。
3.1、http重定向负载均衡
用户请求先到负载均衡服务器,负载均衡服务器根据算法,选择集群中的一台应用服务器,并构造一个包含该实际物理服务器地址的重定向响应返回给用户浏览器,用户浏览器自动重新请求实际物理服务器,完成访问。这种方式的确定很明显,每次需要两次请求才能完成一次访问,性能较差;重定向服务器自身的处理能力有限。该方案在实际中很少见。
3.2、DNS域名解析负载均衡
每次域名解析请求都会根据负载均衡算法获取一个实际的ip地址返回。浏览器根据该ip地址访问实际的应用服务器。缺点是,当某台服务器宕机下线后,既是修改了DNS的配置,但是生效需要较长时间,这段时间用户访问的还是早期已经宕机的服务器,导致用户访问失败。
实际中,大型的网站都使用了DNS域名解析,但解析出的ip实际是内部负载均衡的地址,而不是物理服务器的地址。也就是说,使用了两级负载均衡。
3.3、反向代理负载均衡
实际使用的反向代理服务器,大多都提供了负载均衡算法,如NGINX。根据算法将请求转发到不同的应用服务器上。反向代理服务器的缺点:工作在http协议层,本身作为请求和响应的中转站,其性能可能成为瓶颈。实践中,一般代理10多台服务器, 再多性能就明显有问题。
3.4、IP负载均衡
当用户请求到达负载均衡服务器后,负载均衡服务器根据负载均衡算法获取一台真实的服务器地址,并将数据包的目的ip地址修改成上面获取的ip地址,然后访问对应的服务器。响应数据包回到负载均衡服务器后,再次修改数据包的源地址,并返回给用户。缺点是,对于大数据量传输的网站而言,负载均衡服务器受限于网卡的带宽。
3.5、数据链路层负载均衡
这种传输方式又称为三角传输模式,负载均衡数据分发过程中不修改ip地址,只修改目的的mac地址,通过配置真实物理服务器几圈所有机器虚拟ip和负载均衡ip一致,从而达到不死股数据包的源地址和目的地址就可以实现分发的目的。数据链路层负载均衡是目前大型网站使用最广泛的手段。最常见的产品是LVS(Linux Virtual Server)。
评论