阿里面试:5000qps访问一个500ms的接口,如何设计线程池的核心线程数、最大线程数? 需要多少台机器?

本文原文链接

尼恩说在前面

在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题:

如何确定系统的最佳线程数?

5000qps,下游一个接口响应时间 500ms,接口超时时间 1S,一台机器4核8g,如何设计线程池的核心线程数、最大线程数、队列,需要多少台机器

5000qps访问 一个 500ms响应时间接口,如何设计线程池的核心线程数、最大线程数? 需要多少台机器?

最近有小伙伴在面试阿里,又遇到了相关的面试题。小伙伴懵了,因为没有遇到过,所以支支吾吾的说了几句,面试官不满意,面试挂了。

所以,尼恩给大家做一下系统化、体系化的梳理,使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

当然,这道面试题,以及参考答案,也会收入咱们的 《尼恩Java面试宝典PDF》V171版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

最新《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请关注本公众号【技术自由圈】获取,回复:领电子书

本文目录

本文的配套视频, 尼恩的参考答应

详见链接:https://mp.weixin.qq.com/s/JFWjDSQ4HRGbZhj9ei3t6Q

线程使用的两个核心规范

首先看编程规范中, 有两个很重要的,与线程有关的需要强制执行的规范:

规范一:【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。

说明:Java线程的创建非常昂贵,需要JVM和OS(操作系统)配合完成大量的工作:

1)消耗内存资源:必须为线程堆栈分配和初始化大量内存块,其中包含至少1MB的栈内存。

2)消耗CPU资源:需要进行系统调用,以便在OS(操作系统)中创建和注册内核线程,大量内核线程调度会导致CPU上下文过度切换。

所以,Java高并发应用频繁创建和销毁线程的操作将是非常低效的,而且是不被编程规范所允许的。

如何降低Java线程的创建成本?必须使用到线程池。使用线程池的好处是减少在创建和销毁线程上所消耗的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题。

以上的内容,在尼恩的 《Java 高并发核心编程 卷2》 进行了详细介绍。

规范二:【强制】 线程池不允许使用Executors去创建快捷线程池 ,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

说明:Executors返回的线程池对象的弊端如下:

  • FixedThreadPool和SingleThreadPool: 允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。
  • CachedThreadPool和ScheduledThreadPool: 允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。

通过以上规范,说明我们应用中,需要用自定义线程池。然而,由于构造一个线程池竟然有7个参数

图片

7个重要参数中,最为重要的三个是:核心,最大线程数量, BlockingQueue。前两个参数和线程数量有关系, 后一个和内存资源消耗有关。

线程数设置太少或者阻塞队列太小, 会导致大量任务被拒绝,抛出RejectedExecutionException,触发线上的接口降级,用户体验很差。

二线程数设置太多或者阻塞队列太长,会导致资源消费高而有效负荷很小, 特别是阻塞队列设置过长,会导致频繁FullGC,甚至OOM。

如何确定系统的最佳线程数?来一个牛逼轰轰的答案

如何确定系统的最佳线程数,大体上分三步:

第一步,理论预估;

第二步,压测验证;

第三步,监控调整。

图片

这也是尼恩给大家归纳的,最为理想的:可监控/可弹性的 线程池模式

第一步: 完成线程数的理论预估 (设计阶段)

在尼恩的 《Java 高并发核心编程 卷2》 进行了详细介绍。

首先,按照任务类型对线程池进行分类, 分为三类,具体如下图:

图片

具体,请参见在尼恩的 《Java 高并发核心编程 卷2》 1.7.1 小节。

核心线程数的设置

  • CPU 密集型任务:如果应用程序执行的是CPU密集型任务,通常情况下,核心线程数应该设置为等于CPU核心数。这可以充分利用CPU资源。
  • IO 密集型任务:如果应用程序执行的是IO密集型任务(例如,文件读写、网络通信等),通常情况下,核心线程数可以设置为 CPU核心数 2倍,以充分利用等待IO操作时的线程空闲时间。
  • 混合型任务:如果应用程序同时执行CPU密集型和IO密集型任务,核心线程数的 按照 线程等待时间 + 线程 工作时间的占比来计算。

第1类:IO 密集型线程池线程数预估

线程数就是 CPU的核数的2倍。

图片

具体,请参见在尼恩的 《Java 高并发核心编程 卷2》 1.7.2 小节。

第2类:CPU密集线程池线程数预估

CPU密集型任务并行执行的数量应当等于CPU的核心数, 线程数就是 CPU的核数

图片

具体,请参见在尼恩的 《Java 高并发核心编程 卷2》 1.7.3小节。

第3类:混合型线程池线程数预估

混合型线程池线程数预估, 参考下面的的公式:

最佳线程数 = ((线程等待时间 + 线程 CPU 时间) / 线程 CPU 时间 ) * CPU 核数

图片

具体,请参见在尼恩的 《Java 高并发核心编程 卷2》 1.7.4小节。

第二步: 完成线程数的压测验证 (测试阶段)

过少的线程会造成任务拒绝,业务降级。

过多的线程会造成,额外的内存开销CPU开销,甚至会导致OOM。

所以,合理的线程池线程数,才是王道。

在设计阶段完成了step1的线程数的理论预估之后, 那么我们的理论值就出来了。

如何做验证呢?这里需要 压测。

根据公式:

服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量

前面线程等待时间,线程cpu时间都是 预估的 ,都是要验证的。

首先通过用户慢慢递增来进行性能压测,观察QPS。

持续大的增加用户数, 压测出最大的吞吐量。

然后再 收集 最大的吞吐量场景的 线程等待时间,线程cpu时间, 再计算出最佳线程数。

第三步: 完成线程数的线上调整 (生产阶段)

压测的场景,是有限的。而线上的业务, 是复杂的,多样的。

由于系统运行过程中存在的不确定性,很难一劳永逸地规划一个合理的线程数。

所以,需要进行生产阶段线程数的两个目标:

  • 可监控预警
  • 可在线调整

图片

第1个维度:可在线监控预警

图片

第2个维度:可在线调整

图片

参数的在线动态调整:结合Nacos 实现动态化线程池

优秀的动态化线程池轮子,主要有:

  • Hippo4J
  • dynamic-tp

如果线上使用,可以使用这些轮子项目。

但是尼恩的是[技术自由圈]一个实战社群,必须自己从0到1,去撸一把代码,提升自己的水平。

大实操:5000qps 线程数的理论预估 大实操

1. 核心参数解释

  • 请求量 (QPS): 5000 QPS意味着每秒有5000个请求需要被处理。
  • 接口响应时间: 500ms,即每个请求的处理时间为500毫秒。
  • 接口超时时间: 1秒,表示如果请求处理时间超过1秒,接口就会超时。
  • 机器配置: 每台机器4个CPU核心,8GB内存。

2. 核心线程数 设计

为了设计合理的线程池, 需要考虑如何合理配置核心线程数最大线程数队列大小

首先是 核心线程数。

核心线程数决定了线程池中最小的线程数,线程池会始终保持这个数量的线程。

根据 面试的业务场景:

  • 每台机器有4个CPU核心,因此每个CPU核心可以并发处理多个请求。通常情况下,核心线程数会设置为与CPU核心数相同。
  • 由于接口响应时间是500ms,每个线程可以在500ms内处理完一个请求,因此设置核心线程数为4,或者根据实际负载情况适当调整。

建议: 核心线程数设置为 4(与CPU核心数一致)。

3. 最大线程数 设计

一般业务接口都是混合型 任务, 相对应的 ,线程池 属于 混合型线程池。

混合型任务 的工作,分为两个时间:

  • 等待时间,进行大量非 CPU 耗时操作 ,比如在 Web 应用处理 HTTP 请求处理时,一次请求处理会包括 DB 操作、 RPC 操作、缓存操作等多种耗时操作。
  • 工作时间, 执行简单的计算,一般是 几十个ms 搞定。

所以,混合型任务 CPU 利用率不是太高,非 CPU 耗时往往是 CPU 耗时的数10倍。

一般来说,一次 Web 请求的 CPU 计算耗时往往较少,大致在 20ms-50ms 之间,而其他耗时操作会占用 500ms-1000ms 甚至更多的时间。

在为混合型任务创建线程池时,如何确定线程数呢?

业界有一个比较成熟的估算公式,具体如下:

最佳线程数 = ((线程等待时间+线程CPU 时间) / 线程CPU 时间 ) * CPU 核数

比如在 Web 服务器处理 HTTP 请求时,假设平均线程 CPU 运行时间为 50ms,而线程等待时间(比如包括 DB 操作、 RPC 操作、缓存操作等)为500ms,如果 CPU核数为 4,那么根据上面这个公式,估算如下:

((500+50) / 50) * 450

建议:最大线程数50

4. 线程池 的队列大小 设计

队列的大小决定了等待处理的请求数量。

一般来说,线程池的队列大小设置与最大线程数成正比。

  • 如果队列太小,可能会导致请求被拒绝;

  • 如果队列太大,会导致内存压力增大。

在高并发场景下,为避免内存占用过高,队列的大小可以设置为最大线程数的2倍左右。

建议: 队列大小设置为 50*2 =100

5. 计算所需机器数量

为了计算所需机器数量,我们首先要计算每台机器能够处理的请求量,然后计算出总请求量所需的机器数。

a. 每台机器的处理能力

每台机器的4个CPU核心可以并行处理多个请求,假设每个线程的响应时间为500ms。

每个线程每秒能处理 2 个请求(500ms处理一个请求,1秒可以处理2个请求)。

每台机器的最大请求处理能力为:

  • 最大请求处理能力 = 每台机器最大线程数 * 每个线程每秒处理的请求数
  • 假设最大线程数为50,每台机器的最大处理能力为:

50 * 2 = 100 个请求/秒。

6. 所需机器数量

如果系统需要处理5000 QPS,每台机器可以处理100个请求/秒,计算所需机器数量:

  • 所需机器数量 = 总请求量 / 每台机器处理能力
  • 所需机器数量 = 5000 QPS / 100 请求/秒/机器 ≈ 50 台机器。

为了保证性能和冗余,建议多几台,因此需要 50台机器

7. 完成线程数的理论预估 (设计阶段) 总结

  • 核心线程数:4(与机器核心数一致)
  • 最大线程数:50(根据负载情况)
  • 队列大小:100(根据最大线程数设置)
  • 所需机器数量:大约 50 台机器

这些设置可以根据系统的实际负载和性能需求进一步调整。

相关面试题:

阿里面试:系统的最佳线程数,怎么确定?

说在最后:有问题找老架构取经‍

只要按照上面的 尼恩团队梳理的 方案去作答, 你的答案不是 100分,而是 120分。 面试官一定是 心满意足, 五体投地。

按照尼恩的梳理,进行 深度回答,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

在面试之前,建议大家系统化的刷一波 5000页《尼恩Java面试宝典PDF》,里边有大量的大厂真题、面试难题、架构难题。

很多小伙伴刷完后, 吊打面试官, 大厂横着走。

在刷题过程中,如果有啥问题,大家可以来 找 40岁老架构师尼恩交流。

另外,如果没有面试机会, 可以找尼恩来改简历、做帮扶。前段时间,刚指导一个小伙 暴涨200%(涨2倍),29岁/7年/双非一本 , 从13K一次涨到 37K ,逆天改命

狠狠卷,实现 “offer自由” 很容易的, 前段时间一个武汉的跟着尼恩卷了2年的小伙伴, 在极度严寒/痛苦被裁的环境下, offer拿到手软, 实现真正的 “offer自由” 。

尼恩技术圣经系列PDF

……完整版尼恩技术圣经PDF集群,请找尼恩领取

<think>好的,我需要准备关于Spring Cloud Sentinel的常见面试题及答案。首先,我应该回顾Spring Cloud Sentinel的基本概念和功能。记得用户提到过Sentinel是用于服务保护,包括降级、熔断和限流。我需要确保回答覆盖这些核心点。 接下来,我需要结合用户提供的引用内容。引用[1]提到Spring Cloud和Spring Boot的版本兼容性,这可能与整合Sentinel相关,需要提到版本匹配的问题。引用[3]详细介绍了Sentinel的服务降级、熔断和限流,这些都是面试题的常见问题。 我应该先列出可能的问题,例如:Sentinel的核心功能、服务降级与熔断的区别、如何配置规则、与Hystrix的对比等。然后逐一给出简洁准确的答案,并适当引用提供的资料。例如,服务降级可以引用[3]中的定义,版本兼容性引用[1]。 还要注意格式要求:使用中文,行内公式用$...$,独立公式单独成段。不过在Spring Cloud的上下文中可能数学公式不多,但如果有资源限流的算法,比如令牌桶,可能需要用LaTeX表达。 生成的问题要覆盖基本概念、配置、原理、对比和实际应用。答案要结构清晰,分点说明,确保用户容易理解。同时,检查是否有遗漏的重要知识点,比如动态规则配置、控制的使用等。 最后,确保每个答案正确无误,引用恰当,比如在提到版本兼容性时引用[1],服务降级引用[3]。如果有性能优化或实现原理的问题,可能需要引用[2]提到的synchronized和串行化,但Sentinel可能用不同的机制,需要确认相关性。 总结步骤:1. 确定核心主题和问题;2. 结合引用资料构建答案;3. 检查格式和引用标识;4. 生成相关问题。</think>### Spring Cloud Sentinel 常见面试题及答案 #### 1. **什么是Spring Cloud Sentinel?它的核心功能是什么?** **答案:** Spring Cloud Sentinel是阿里巴巴开源的分布式系统流量控制组件,专注于服务保护,核心功能包括: - **服务限流**:通过规则(如QPS线程数)控制资源访问量,防止系统过载。 - **服务熔断**:当资源响应时间过长或异常比例过高时,自动熔断请求,避免级联故障[^3]。 - **服务降级**:在系统高负载时暂时关闭非核心功能,保障核心业务可用性[^3]。 - **实时监控**:提供动态仪表盘,实时查看资源访问指标。 --- #### 2. **Sentinel 如何实现服务限流?支持哪些限流策略?** **答案:** Sentinel通过定义`FlowRule`实现限流,支持以下策略: - **直接拒绝(QPS限流)**:当每秒请求数超过阈值,直接拒绝新请求。 - **冷启动(Warm Up)**:根据系统负载逐步增加允许的QPS,避免瞬时流量激增。 - **匀速排队(Rate Limiter)**:以恒定速率处理请求,使用漏桶算法平滑流量。 ```java // 示例:定义QPS限流规则 FlowRule rule = new FlowRule("resA"); rule.setGrade(RuleConstant.FLOW_GRADE_QPS); rule.setCount(100); // 阈值100 QPS FlowRuleManager.loadRules(Collections.singletonList(rule)); ``` --- #### 3. **服务降级和服务熔断有什么区别?** **答案:** - **服务熔断**: 当资源异常(如响应超时、错误率过高)时,**立即拒绝所有请求**,进入熔断状态,后续请求直接失败。一段时间后进入半开状态试探恢复。 - **服务降级**: 在系统高负载时,**主动关闭非核心功能**(如返回默认值),释放资源保障核心业务,不一定是异常触发。 --- #### 4. **Sentinel 如何动态配置规则?** **答案:** Sentinel支持通过以下方式动态更新规则: - **控制配置**:通过Sentinel Dashboard实时推送规则到微服务。 - **API 编程**:调用`FlowRuleManager.loadRules()`更新内存中的规则。 - **集成配置中心**:如Nacos、ZooKeeper,规则持久化到配置中心后自动同步。 --- #### 5. **Sentinel 与 Hystrix 的主要区别是什么?** **答案:** - **功能维度**: Hystrix侧重熔断和线程隔离,Sentinel额外提供实时监控、多样化的流量控制(如冷启动、匀速排队)。 - **性能**: Sentinel基于滑动窗口统计,资源开销更低;Hystrix依赖线程池,上下文切换成本较高。 - **扩展性**: Sentinel支持动态规则配置和扩展数据源(如Nacos),Hystrix需手动更新配置[^1][^3]。 --- #### 6. **如何实现Sentinel的熔断降级规则?** **答案:** 定义`DegradeRule`,设置触发条件: - **异常比例**:当异常请求比例超过阈值(如50%),触发熔断。 - **响应时间**:当请求平均RT超过阈值(如200ms),触发降级。 ```java DegradeRule rule = new DegradeRule("resB"); rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO); rule.setCount(0.5); // 异常比例阈值50% rule.setTimeWindow(10); // 熔断时间10秒 DegradeRuleManager.loadRules(Collections.singletonList(rule)); ``` --- #### 7. **Sentinel 如何与Spring Cloud整合?需要注意什么?** **答案:** - **整合步骤**: 1. 添加依赖:`spring-cloud-starter-alibaba-sentinel`。 2. 配置Sentinel Dashboard地址:`spring.cloud.sentinel.transport.dashboard=localhost:8080`。 - **注意事项**: - 确保Spring Cloud与Sentinel版本兼容(如Spring Cloud 2021.x对应Sentinel 1.8.6)[^1]。 - 需启动Sentinel Dashboard才能查看实时监控。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值