java架构师技术学习方法(Java高级架构师-高并发的常见应对方案)
java架构师技术学习方法(Java高级架构师-高并发的常见应对方案)什么是CDN?【CDN加速】【数据库缓存】为什么是要使用缓存?缓存数据是为了让客户端很少甚至不访问数据库,减少磁盘IO,提高并发量,提高应用数据的响应速度。
欢迎关注头条号:java小野猫一、关于并发我们说的高并发是什么?
在互联网时代,高并发,通常是指,在某个时间点,有很多个访问同时到来。
高并发,通常关心的系统指标与业务指标?
- QPS:每秒钟查询量,广义的,通常指指每秒请求数
- 响应时间:从请求发出到收到响应花费的时间,例如:系统处理一个HTTP请求需要100ms,这个100ms就是系统的响应时间
- 带宽:计算带宽大小需关注两个指标,峰值流量和页面的平均大小
- PV:综合浏览量(Page View),即页面浏览量或者点击量,通常关注在24小时内访问的页面数量,即“日PV”
- UV:独立访问(UniQue Visitor),即去重后的访问用户数,通常关注在24小时内访问的用户,即“日UV”
二、关于三种应对大并发的常见优化方案
【数据库缓存】
为什么是要使用缓存?
缓存数据是为了让客户端很少甚至不访问数据库,减少磁盘IO,提高并发量,提高应用数据的响应速度。
【CDN加速】
什么是CDN?
CDN的全称是Content Delivery Network,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离等综合信息将用户的请求重新导向离用户最近的服务节点上。
使用CDN的优势?
CDN的本质是内存缓存,就近访问,它提高了企业站点(尤其含有大量图片和静态页面站点)的访问速度,跨运营商的网络加速,保证不同网络的用户都得到良好的访问质量。
同时,减少远程访问的带宽,分担网络流量,减轻原站点WEB服务器负载。
常见互联网分布式架构如上,分为:
(1)客户端层:典型调用方是浏览器browser或者手机应用APP
(2)反向代理层:系统入口,反向代理
(3)站点应用层:实现核心应用逻辑,返回html或者json
(4)服务层:如果实现了服务化,就有这一层
(5)数据-缓存层:缓存加速访问存储
(6)数据-数据库层:数据库固化数据存储
整个系统的高可用,又是通过每一层的冗余 自动故障转移来综合实现的。
四、分层高可用架构实践
【客户端层->反向代理层】的高可用
【客户端层】到【反向代理层】的高可用,是通过反向代理层的冗余来实现的。以nginx为例:有两台nginx,一台对线上提供服务,另一台冗余以保证高可用,常见的实践是keepalived存活探测,相同virtual IP提供服务。
自动故障转移:当nginx挂了的时候,keepalived能够探测到,会自动的进行故障转移,将流量自动迁移到shadow-nginx,由于使用的是相同的virtual IP,这个切换过程对调用方是透明的。
【反向代理层->站点层】的高可用
【反向代理层】到【站点层】的高可用,是通过站点层的冗余来实现的。假设反向代理层是nginx,nginx.conf里能够配置多个web后端,并且nginx能够探测到多个后端的存活性。
自动故障转移:当web-server挂了的时候,nginx能够探测到,会自动的进行故障转移,将流量自动迁移到其他的web-server,整个过程由nginx自动完成,对调用方是透明的。
【站点层->服务层】的高可用
【站点层】到【服务层】的高可用,是通过服务层的冗余来实现的。“服务连接池”会建立与下游服务多个连接,每次请求会“随机”选取连接来访问下游服务。
自动故障转移:当service挂了的时候,service-connection-pool能够探测到,会自动的进行故障转移,将流量自动迁移到其他的service,整个过程由连接池自动完成,对调用方是透明的(所以说RPC-client中的服务连接池是很重要的基础组件)。
【服务层>缓存层】的高可用
【服务层】到【缓存层】的高可用,是通过缓存数据的冗余来实现的。
缓存层的数据冗余又有几种方式:第一种是利用客户端的封装,service对cache进行双读或者双写。
缓存层也可以通过支持主从同步的缓存集群来解决缓存层的高可用问题。
以redis为例,redis天然支持主从同步,redis官方也有sentinel哨兵机制,来做redis的存活性检测。
自动故障转移:当redis主挂了的时候,sentinel能够探测到,会通知调用方访问新的redis,整个过程由sentinel和redis集群配合完成,对调用方是透明的。
说完缓存的高可用,这里要多说一句,业务对缓存并不一定有“高可用”要求,更多的对缓存的使用场景,是用来“加速数据访问”:把一部分数据放到缓存里,如果缓存挂了或者缓存没有命中,是可以去后端的数据库中再取数据的。
这类允许“cache miss”的业务场景,缓存架构的建议是:
将kv缓存封装成服务集群,上游设置一个代理(代理可以用集群冗余的方式保证高可用),代理的后端根据缓存访问的key水平切分成若干个实例,每个实例的访问并不做高可用。
缓存实例挂了屏蔽:当有水平切分的实例挂掉时,代理层直接返回cache miss,此时缓存挂掉对调用方也是透明的。key水平切分实例减少,不建议做re-hash,这样容易引发缓存数据的不一致。
【服务层>数据库层】的高可用
大部分互联网技术,数据库层都用了“主从同步,读写分离”架构,所以数据库层的高可用,又分为“读库高可用”与“写库高可用”两类。
【服务层>数据库层“读”】的高可用
【服务层】到【数据库读】的高可用,是通过读库的冗余来实现的。
既然冗余了读库,一般来说就至少有2个从库,“数据库连接池”会建立与读库多个连接,每次请求会路由到这些读库。
自动故障转移:当读库挂了的时候,db-connection-pool能够探测到,会自动的进行故障转移,将流量自动迁移到其他的读库,整个过程由连接池自动完成,对调用方是透明的(所以说DAO中的数据库连接池是很重要的基础组件)。
【服务层>数据库层“写”】的高可用
【服务层】到【数据库写】的高可用,是通过写库的冗余来实现的。
以mysql为例,可以设置两个mysql双主同步,一台对线上提供服务,另一台冗余以保证高可用,常见的实践是keepalived存活探测,相同virtual IP提供服务。
自动故障转移:当写库挂了的时候,keepalived能够探测到,会自动的进行故障转移,将流量自动迁移到shadow-db-master,由于使用的是相同的virtual IP,这个切换过程对调用方是透明的。
五、总结
高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。
方法论上,高可用是通过冗余 自动故障转移来实现的。
整个互联网分层系统架构的高可用,又是通过每一层的冗余 自动故障转移来综合实现的,具体的:
(1)【客户端层】到【反向代理层】的高可用,是通过反向代理层的冗余实现的,常见实践是keepalived virtual IP自动故障转移
(2)【反向代理层】到【站点层】的高可用,是通过站点层的冗余实现的,常见实践是nginx与web-server之间的存活性探测与自动故障转移
(3)【站点层】到【服务层】的高可用,是通过服务层的冗余实现的,常见实践是通过service-connection-pool来保证自动故障转移
(4)【服务层】到【缓存层】的高可用,是通过缓存数据的冗余实现的,常见实践是缓存客户端双读双写,或者利用缓存集群的主从数据同步与sentinel保活与自动故障转移;更多的业务场景,对缓存没有高可用要求,可以使用缓存服务化来对调用方屏蔽底层复杂性
(5)【服务层】到【数据库“读”】的高可用,是通过读库的冗余实现的,常见实践是通过db-connection-pool来保证自动故障转移
(6)【服务层】到【数据库“写”】的高可用,是通过写库的冗余实现的,常见实践是keepalived virtual IP自动故障转移
私信头条号,发送:“资料”,获取更多“秘制” 精品学习资料
如有收获,请帮忙转发,您的鼓励是作者最大的动力,谢谢!