面试题:高并发场景/接口被刷怎么办?

【1】架构和细节

首先参考上篇博文:聊聊高并发应用中秒杀场景的方案实现,其中限流,缓存等思想是一致的。
在这里插入图片描述

这里需要注意的是,如果在现有集群环境下,负载压力仍然很大怎么办?观察上图最后一步—容器化技术。使用Docker+K8s(Kubernetes)构建Docker集群环境。当QPS超过阈值后,自动扩容。比如扩容两个虚拟机,将登录子系统从四节点扩容到6节点,然后修改nginx配置文件。在流量高峰期过后,再触发自动收缩技术,减少虚拟机,减少资源的消耗。

关于Docker和K8s系列文章可以参考博文:
Docker基础入门
k8s docker集群搭建
Kubernetes集群实战

上面从架构层面简要描述了一下流程,下面再来看看具体细节。
在这里插入图片描述

【2】常见的限流手段

① 手动实现负载均衡

如下图红色框选中的地方,让你选择一下,再下载。
在这里插入图片描述

② 图形验证码

12306故意把验证码弄得模糊不清,影响消费者下单,从而限流。但是BATJ在主页均未使用。
在这里插入图片描述

③ 容器限流

常见的web容器其实也具备限流的功能,以Tomcat容器为例,其Connector其中一种配置有如下几个参数:

  • acceptCount:如果Tomcat的线程都忙于响应,新来的连接会进入队列排队。如果超出排队大小,则拒绝连接。
  • maxConnection:瞬时最大连接数,超出的会排队等待。
  • maxThreads:Tomcat能用来处理请求的最大线程数,如果请求处理量一直远远大于最大线程数则可能会僵死。

参考博文:浅谈Tomcat服务器优化方法


④ 限流总资源数

如果有的资源是稀缺资源(如数据库连接、线程),而且可能多个系统都在使用它,那么需要限制使用。可以使用池化技术来限制总资源数:连接池、线程池。比如分配给每个应用的数据库连接是100,那么本应用最多可以使用100个资源,超出了可以等待或者抛异常。

⑤ 从代码级限流某个接口的总并发/请求数

如果接口可能会有突发访问情况,但又担心访问量太大造成崩溃,如抢购业务。这个时候就需要限制这个接口的总并发请求数了。因为粒度比较细,可以为每个接口都设置相应的阈值。

可以使用Java中的AtomicLong进行限流:

try{
	if(atomic.incrementAndGet()>限流数){
		//拒绝请求
	}
	//处理请求
}finally{
	atomic.decrementAndGet();
}

⑥ Nginx限流

Nginx提供了一个叫ngx_http_limit_req_module的模块进行流量控制,Nginx是基于漏桶算法实现。

在这里插入图片描述

⑦ 消息队列

通过RabbitMQ、RocketMQ、ActiveMQ、ZeroMQ、Kafka把流量做匀,限制高流量涌入。

在这里插入图片描述

参考博文:聊聊分布式应用中的消息中间件

在这里插入图片描述

【3】Hystrix服务熔断与降级

在这里插入图片描述
其相关术语解释如下:
在这里插入图片描述

线程隔离
在这里插入图片描述
信号量隔离
在这里插入图片描述
线程隔离和信号量隔离对比

-线程隔离信号量隔离
线程与调用线程非相同线程与调用线程相同(容器线程)
开销排队、调度、上下文开销等无线程切换,开销低
异步支持不支持
并发支持支持(最大线程池大小)支持(最大信号量大小)

在这里插入图片描述
Hystrix执行流程图
在这里插入图片描述
熔断
一般是指软件系统中,由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采取的一种保护机制,所以很多地方把熔断亦称为过载保护。很多时候刚开始可能只是系统出现了局部的、小规模的故障。然而由于种种原因,故障影响的范围越来越大,最终导致了全局性的后果。

如果某个目标服务调用慢或者有大量超时,此时熔断该服务的调用,对于后续调用请求,不再继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好则恢复调用。


请求缓存

在这里插入图片描述

更多Hystrix具体使用参考博文:SpringCloud - Hystrix断路器-服务熔断与降级和HystrixDashboard

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐