亿级流量架构怎么做资源隔离?写得太好了!
作者:等不到的口琴
链接:www.cnblogs.com/Courage129/p/14421585.html
为什么要资源隔离
常见的隔离方式有:
线程隔离
Netty主从程模型
主线程负责认证,连接,成功之后交由从线程负责连接的读写操作,大致如下代码:
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup);
public void channelRead(ChannelHandlerContext ctx, Object msg) {
System.out.println("thread name=" + Thread.currentThread().getName() + " server receive msg=" + msg);
}
thread name=nioEventLoopGroup-3-1 server receive msg="..."
可以发现这里使用的线程其实和处理io线程是同一个;
Dubbo线程隔离模型
thread name=DubboServerHandler-192.168.1.115:20880-thread-2,...
all
所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。direct
所有消息都不派发到线程池,全部在 IO 线程上直接执行。message
只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在 IO 线程上执行。execution
只有请求消息派发到线程池,不含响应,响应和其它连接断开事件,心跳等消息,直接在 IO 线程上执行。connection
在 IO 线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。
Tomcat请求线程隔离
NIO模式:同步非阻塞I/O操作,是一个基于缓冲区、并能提供非阻塞I/O操作的API,它拥有比传统I/O操作具有更好的并发性能。
在Tomcat7版本之后,Tomcat把连接介入和业务处理拆分成两个线程池来处理,即:
这样做,独立的业务或资源中如果出现崩溃,不会影响其他的业务线程,从而达到资源隔离和服务降级的效果。
在使用了servlet3之后,系统线程隔离变得更灵活了。可以划分核心业务队列和非核心业务队列:
线程隔离小总结
资源一旦出现问题,虽然是隔离状态,想要让资源重新可用,很难做到不重启jvm。 线程池内部线程如果出现OOM、FullGC、cpu耗尽等问题也是无法控制的 线程隔离,只能保证在分配线程这个资源上进行隔离,并不能保证整体稳定性
进程隔离
集群隔离
如果系统中某个业务模块包含像抢购、秒杀、存储I/O密集度高、网络I/o高、计算I/O高这类需求的时候,很容易在并发量高的时候因为这种功能把整个模块占有的资源全部耗尽,导致响应编码甚至节点不可用。
像上图的的拆分之后,如果某一天购物人数瞬间暴增,电商交易功能模块可能受影响,损坏后导致电商模块其他的浏览查询也无法使用,因此就要建立集群进行隔离,具体来说就是继续拆分模块,将功能微服务化。
解决方案
线程池隔离与信号量隔离对比
隔离方式 | 是否支持超时 | 是否支持熔断 | 隔离原理 | 是否是异步调用 | 资源消耗 |
---|---|---|---|---|---|
线程池隔离 | 支持,可直接返回 | 支持,当线程池到达maxSize后,再请求会触发fallback接口进行熔断 | 每个服务单独用线程池 | 可以是异步,也可以是同步。看调用的方法 | 大,大量线程的上下文切换,容易造成机器负载高 |
信号量隔离 | 不支持,如果阻塞,只能通过调用协议(如:socket超时才能返回) | 支持,当信号量达到maxConcurrentRequests后。再请求会触发fallback | 通过信号量的计数器 | 同步调用,不支持异步 | 小,只是个计数器 |
信号量隔离
官网对信号量隔离的描述建议
HystrixCommand
s is when the call is so high volume (hundreds per second, per instance) that the overhead of separate threads is too high; this typically only applies to non-network calls.机房隔离
机房隔离主要目的有两个,一方面是将不同区域的用户数据隔离到不同的地区,例如湖北的数据放在湖北的服务器,浙江的放在浙江服务器,等等,这样能解决数据容量大,计算密集,i/o(网络)密集度高的问题,相当于将流量分在了各个区域。
另一方面,机房隔离也是为了保证安全性,所有数据都放在一个地方,如果发生自然灾害或者爆炸等灾害时,数据将全都丢失,所以把服务建立整体副本(计算服务、数据存储),在多机房内做异地多活或冷备份、是微服务数据异构的放大版本。
如果机房层面出现问题的时候,可以通过智能dns、httpdns、负载均衡等技术快速切换,让区域用户尽量不收影响。
数据读写隔离
通过主从模式,将mysql、redis等数据存储服务集群化,读写分离,那么在写入数据不可用的时候,也可以通过重试机制 临时通过其他节点读取到数据。
多节点在做子网划分的时候,除了异地多活,还可以做数据中心,所有数据在本地机房crud 异步同步到数据中心,数据中心再去分发数据给其他机房,那么数据临时在本地机房不可用的时候,就可以尝试连接异地机房或数据中心。
静态隔离
主要思路是将一些静态资源分发在边缘服务器中,因为日常访问中有很多资源是不会变的,所以没必要每次都想从主服务器上获取,可以将这些数据保存在边缘服务器上降低主服务器的压力。
爬虫隔离
一是限流,限制访问的频率;
二是将爬虫请求转发到固定地方。
爬虫限流
登录/会话限制 下载限流 访问频率 ip限制,黑白名单
想要分辨出来一个访问是不是爬虫,可以简单的使用nginx来分析ua处理
UA介绍
User Agent 简称UA,就是用户代理。通常我们用浏览器访问网站,在网站的日志中,我们的浏览器就是一种UA。
禁止特定UA访问,例如最近有个网站A抄袭公司主站B的内容,除了域名不同,内容、图片等都完全是我们主站的内容。出现这种情况,有两种可能:
一种是:它用爬虫抓取公司主站B的内容并放到自己服务器上显示;
无论怎样,都要禁止这种行为的继续。有两种方法解决:
nginx不仅可以处理ua来分离流量,还可以通过更强大的openresty来完成更复杂的逻辑,实现一个流量网关,软防火墙。
正文结束
1.不认命,从10年流水线工人,到谷歌上班的程序媛,一位湖南妹子的励志故事
5.37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...
一个人学习、工作很迷茫?
点击「阅读原文」加入我们的小圈子!