架构师训练营第 1 期 - 第四周课后练习
一个典型的大型互联网应用系统使用了哪些技术方案和手段,主要解决什么问题?请列举描述。
答:
会用到以下技术
分布式缓存
为降低频繁的查询数据库带来的负载压力,可以使用缓存,同时,因为直接使用缓存而不是每次都请求数据库,也提高了系统处理速度。比较常见的缓存有Redis。
比如系统需要给每一个人发送同一个短信内容,而待发送的内容又保存在数据库中,如果不使用缓存,那么每发送一个人的时候,都需要去数据库查询待发送的内容,因为发送的内容都一样,其实没有必要每次都去数据库查询。这种情况下,就可以使用缓存,可以先去缓存里面查到待发送的内容,如果找不到,再去查询数据库并更新到缓存,这样其他人发送短信的时候,就可以从缓存里面直接拿到了。
这里介绍2中更新缓存的策略:
Read/Write Through
查询缓存数据的时候,如果缓存中存在,就直接返回。如果缓存中不存在,就去数据库查询并把结果写入缓存,然后返回。
更新缓存数据的时候,先更新数据库的数据,更新成功后,再更新缓存,然后再返回。
但是,在并发的情况下,还是会有概率出现脏数据,缓存中可能被错误的更新了旧数据。比如下面图中的3个线程,线程1发现缓存不存在,查询到旧数据并更新到缓存,线程2写入新数据到数据库,并在线程1写入缓存之后更新了缓存,线程3也是发现缓存不存在,查询到旧数据,并覆盖了线程2写入的新数据。
Cache Aside
Cache Aside和Read/Write Through非常像,不同的地方在于Cache Aside写入数据到数据库之后,是直接删掉缓存,而不是更新缓存。在某些情况下,Cache Aside也会有脏数据问题。比如线程1写入新数据到缓存中,再删除缓存,线程2发现缓存不存在,查询到旧数据并在线程1删除缓存之后写入旧数据到缓存中。
使用分布式缓存的时候,当遇到缓存雪崩,就是大量缓存同时失效,用户的请求就会穿透缓存直接命中数据库,当有大量的请求直接访问数据库,会导致数据库的负载过高,有可能会导致数据库崩溃。为避免用户请求穿透缓存,可以把不同数据的缓存的失效时间错开,这样就不会同一时间缓存都失效。也可以缓存所有的数据,前台线程只读取数据,后台定时更新数据等。需要针对不同的业务场景选择合适的解决方案。
负载均衡技术
多台服务器形成一个集群对外提供统一服务的时候,当外部需要访问集群的时候,需要通过负载均衡设备,把请求发送到集群中的节点去处理。借助负载均衡技术,集群提高了并发处理能力和可靠性。先讲讲可靠性,应用服务器只有一台的时候,如果服务器碰到故障,那么整个应用就不能对外提供服务了。因此,提供多台服务器形成集群,当某台服务器故障,那么通过负载均衡技术,把用户请求发送到存活的节点上,可以继续对外服务。当故障服务器恢复时,可以把节点再加回集群中。
当系统的性能瓶颈在于应用服务器集群无法满足大量用户请求的时候,通过水平伸缩的方式,增加服务器节点,可以提高系统并发处理的能力。
有以下几种负载均衡技术:
Http重定向负载均衡
利用Http重定向实现负载均衡。浏览器请求负载均衡服务器的IP,负载均衡服务器往响应中写入302状态码,并把真实的集群中的节点的IP放到重定向url中,浏览器再访问到具体的服务器。这种方案浏览器需要请求2次才能完成一次访问,用户访问时间增加;而且重定向本身也是处理请求,负载均衡服务器可能成为瓶颈;而且使用302重定向状态码,搜索引擎可能判断为SEO作弊,降低搜索排名。因为实践中很少使用。
DNS域名解析负载均衡
利用DNS解析域名实现负载均衡。
浏览器访问域名时,需要请求DNS服务器,域名解析服务器根据域名对应的多个服务器IP,利用负载均衡算法,返回其中的一个IP给浏览器,浏览器再请求具体的应用服务器。域名解析负载均衡的优点是把负载均衡的工作交给了DNS,省去了自己维护的麻烦。但是也有缺点,当某台服务器下线时,需要通知域名服务商去更新记录,比较耗时。
反向代理负载均衡
利用反向代理服务器进行负载均衡。
反向代理服务器提供负载均衡的功能,管理一组Web服务器,根据负载均衡算法把请求转发到具体的应用服务器,待应用服务器返回时,再把响应返回给用户。
负载均衡服务器维护着集群的服务器地址列表,当请求发送到负载均衡服务器时,它会根据负载均衡算法,转发请求到集群中的一个节点。
有以下几种负载均衡算法:
轮询
所有请求被依次发送到每台节点上,每台节点上的请求数目是相同的。该算法实现简单,适用服务器硬件差不多和请求无状态的场景。
加权轮询
加权轮询就是给集群中每台节点赋予一个权重,权重大的服务器会接收更多的请求。Nginx默认的负载均衡策略就是加权轮询策略。加权轮询策略适合服务器节点异构的情况,服务器配置高的节点会获取更多的情景。
随机策略
利用随机函数,请求被随机的分配到集群中的一个节点。该算法实现简单,适用于服务器硬件差不多和请求无状态的场景。
最少连接
负载均衡器记录着发送给每台服务器的连接数,当有新的请求来的时候,总是转发给连接数最少的节点。
哈希算法
根据哈希算法,对请求计算哈希值,哈希值对应到集群中服务器的编号。请求总是被发送到同一个节点上,适用于请求有状态的场景。缺点就是,当某台节点故障时,请求被发送到不同的服务器上,如果请求是有状态的,可能会导致请求失败,或者重新去获取状态,实现复杂。
分布式消息队列
分布式消息队列作为中间件技术,适用以下几种场景:
异步处理
为了更快的响应客户,可以把比较耗时,或者不影响用户体验的步骤放到消息队列里面去做,当完成必要的操作之后,先返回结果给客户,剩余的操作由消息队列异步去实现。比如有一个功能就是可以通过文件的形式导入名单到数据库,文件大的话,就比较耗时。为了提升用户体验,可以先把文件上传到服务器临时目录,然后先给用户返回文件正在处理,后端可以把文件路径发送到消息队列里面,待后端消费者处理,处理的过程和结果可以保存到日志表里面,用户在前端可以查看。
流量控制
当有大量请求需要处理的时候,已经超出系统处理能力的上限,为防止系统被压垮,可以先将请求缓冲在消息队列中,系统以适当的速度从消息队列中消费数据,处理请求。比如我们需要给几百万的用户发送营销短信,会调用短信息服务提供商的外部短信接口,发送短信到用户手机上。外部短信接口的并发处理速度有限制,不能同时处理太多请求。我们可以先把几百万的短信内容先缓冲在消息队列里面,消费者从队列中获取短信内容,然后调用外部短信接口。如果外部短信接口的并发能力提高了,那么可以增加消费者的数量,如果外部短信接口的并发能力降低了,那么可以减少消费者的数量,通过调整消费者的数量来控制消费的速度,达到削峰填谷的作用。
服务解耦
当服务之间需要通信时,一个服务可以把数据发送到消息队列中,另一个服务可以从消息队列中消费,这样服务之间就完成了数据交换。当有新的服务也需要这部分数据的时候,它只需要订阅消息队列中的主题就可以了。相较于服务之间通过接口调用的方式,当任何一方服务的需求发生变化时,双方都不得不花费大量时间来调试。通过消息队列的方式,服务之间的耦合大大降低,上游服务只需要把数据发送到消息队列中,下游服务消费主题自己过滤和加工数据。比如当我们购买一款理财产品的时候,交易数据可以发送到消息队列中,风控系统订阅主题判断交易是否合法,营销系统订阅主题推荐更多产品,分析系统订阅主题收集用户购买行为等等,当有其它的系统需要获取交易数据时,只需要订阅主题就可以了。
CDN加速
CDN(Conent Distributed Network)叫做内容分发网络,本质上就是一种缓存。互联网请求第一步往往是电信服务商的机房,通过把网站的静态资源比如Javascript、图片、CSS,HTML、视频等放在机房的服务器上,可以直接把这些资源返回给客户端,不需要再继续请求应用服务器了,加快了系统响应速度,提升了用户打开页面的时间。
反向代理
反向代理是指在用户请求到达web服务器之前,通过配置反向代理服务器,分发用户的请求到不同的服务器,还可以根据请求的路径分发到不同的子系统。相较于传统的正向代理,一般需要安装代理服务器软件到用户的电脑上,用户需要自己设置代理服务器地址,而反向代理对于用来说是透明,用户感觉不到,反向代理服务器属于整个互联网应用架构的一部分,而且还可以设置一些规则去屏蔽一些非法请求。还可以在反向代理服务器上缓存静态资源,比如Javascript、图片、CSS、HTML、视频等,当用户请求静态资源的时候,如果CDN中没有访问到,在请求到达反向代理服务器时再返回这些资源,可以不用发送到应用端去处理,提升了网站处理速度。反向代理服务器,一般也支持负载均衡的作用,负载均衡可以提高系统的可靠性和并发处理能力。
评论