作者回复: 1. 赞!对于特定一个热点业务,其实应该要做的尽量将流量分散开来,不然的话热点高并发可能打崩机器。也就是,不同业务的热点之间要隔离,同一个业务热点就不要隔离,并且应该尽量让热点分散到所有的机器上。 2. 你写 Java 应该很经常遇到,比如说用 @Async 注解。另外就是你使用的 ORM,RPC 框架的,你去看看是否有提供配置,能让你指定专门的线程池。比如说在 Dubbo 里面就有的。
作者回复: 2. 这时候,如果我是面试官我就会追问你,那么多线程池你怎么管?也就是你提到的,到处都是线程池有什么问题?怎么解决问题? 比如说我们之前就出过一个问题。也就是我们一个庞大的服务,每一个开发都觉得自己的业务很核心,然后就开了一个独立的线程池。本来每个人都开是没什么问题的,但是大家都开加一起就出问题了。 不过当时我们也没很好的办法。一个是将这个庞大的服务拆分了;另外一个是梳理了一下,对服务进行了分级,分成了三级:独享,部分共享,全服务无共享三种线程池。这样控制住了线程池数量和线程数量。 其实,后面在讲超时控制的内容也可以用于缓解这个问题。就是设置好超时时间,那么线程池的线程会及时释放,变相地就可以少用一些线程,也能缓解系统线程数量过多的问题。 彻底解决,还是依赖于当时我们直接拆分,一次拆出来三个核心服务,各自独立部署。
作者回复: 1. 其实线程池中的线程数和你的内核线程、用户线程模型没太大关系。线程数的确定要考虑你的业务会不会频繁引起阻塞。正常来说,线程池会有核心线程数、最大线程数、空闲线程数。核心线程数比 CPU 大 1 就可以,而空闲线程数就看你能给它多少资源了。 2. 不是,意思是你慢线程你就慢慢处理任务,但是那些快的任务,短的任务在另外一个线程池上,就不会受到影响。这种隔离确实不彻底,毕竟大家都还在共享 CPU。要彻底隔离,就得另外启动一个虚拟机,把快慢任务彻底分离。
作者回复: 感谢你的建议啊,后面讲解思路的时候可以用伪代码配合,但是文字怕是少不了,因为要用一种针对面试的口语化的表述清楚原理。 毕竟在面试的时候总不能说面试官我给你来一个伪代码=。=
作者回复: 1. Redis 在一些中小公司里面确实会被用作消息队列,比如说使用 Redis 的订阅功能。 2. 分组这个要讨论请求和实力分开来看。对于请求来说,可以是你任何一个上游打个标记,比如你说的网关,或者前端自己在 Header 里面带一个标记位。也可以是你自己计算一下,比如说对于一个用户是不是 VIP 这种,在登录校验那里或者权限校验那里,你就可以在上下文里面打一个标签。这个标签,是需要能够跨端传递的。而至于说某些实例属于哪些组,一种是服务端自己配置文件(或者环境变量)里面指定,而后注册到注册中心;也可以是动态计算,比如说服务端自己计算自己的当下状态,如果发现自己负载高了,也可以自己给自己打一个标签“高负载”。 3. 支持的,这个你需要去看看 SpringCloud 的文档 4. 正常来说,我是建议一台机器就启动一个实例的,让它独占资源,性能最好,出问题了影响也最小,同时也不会被别人影响。不过要是物理机虚拟出来了虚拟机,那么每个虚拟机一个也可以,因为资源从逻辑上也隔离了,你启多个容器也可以。目前在大公司里面的 MySQL 有些都是容器化部署的,那么一台物理机上可能就有非常多个 MySQL。