没有预热,不叫高并发,叫并发高

2024-02-18 17:50
文章标签 并发 没有 预热

本文主要是介绍没有预热,不叫高并发,叫并发高,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

大家都知道,高并发系统有三把斧子:缓存、降级和限流。但还有一把斧子,经常被遗忘在角落里,郁郁不得志,那就是预热

640?wx_fmt=jpeg

现象举例

先说两个现象。这些现象,只能在并发高的系统中出现。
好吧,它已经引起了多个故障。

一、DB重启后,瞬间死亡

一个高并发环境下的DB,进程死亡后进行重启。由于业务处在高峰期间,上游的负载均衡策略发生了重分配。刚刚启动的DB瞬间接受了1/3的流量,然后load疯狂飙升,直至再无响应。

原因就是:新启动的DB,各种Cache并没有准备完毕,系统状态与正常运行时截然不同。可能平常1/10的量,就能够把它带入死亡。

二、服务重启后,访问异常

另外一个常见的问题是:我的一台服务器发生了问题,由于负载均衡的作用,剩下的机器立马承载了这些请求,运行的很好。当服务重新加入集群时,却发生了大量高耗时的请求,在请求量高的情况下,甚至大批大批的失败。

引起的原因大概可以归结于:

1、服务启动后,jvm并未完全准备完毕,JIT未编译等。
2、应用程序使用的各种资源未准备就绪。
3、负载均衡发生了rebalance。


这两个问题,都是没有做好预热

Warm Up,即冷启动/预热的方式。当系统长期处于低水位的情况下,流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过”冷启动”,让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。

我想要这样的曲线。

640?wx_fmt=jpeg

而不是这样的。

640?wx_fmt=jpeg

事实要复杂的多

流量是不可预测的,这不同于自然增长的流量,或者人为的攻击——这是一个从无到有的过程。甚至一些自诩超高速的组件,如lmax的disruptor,在这种突然到来的洪峰之下也会崩溃。

warmup最合适的切入层面就是网关。如图:node4是刚启动的节点,集成在网关中的负载均衡组件,将能够识别出这台刚加入的实例,然后逐步放量到这台机器,直到它能够真正承受高速流量。

640?wx_fmt=jpeg

假如所有的请求,都经过网关,一切都好办的多,也有像Sentinel 之类的组件进行切入。但现实情况往往不能满足条件。比如:

1、你的应用直接获取了注册中心的信息,然后在客户端组件中进行了流量分配。
2、你的应用通过了一些复杂的中间件和路由规则,最终定位到某一台DB上。
3、你的终端,可能通过了MQTT协议,直接连上了MQTT服务端。

我们进行一下抽象,可以看到:所有这些流量分配逻辑,包括网关,都可以叫做客户端。即所有的warmup逻辑都是放在客户端的,它们都与负载均衡紧密耦合在一起。

解决方式

接口放量

按照以上的分析,通过编码手段控制住所有的客户端调用,即可解决问题。

一个简单的轮询方式

1、我要能拿到所有要调用资源的集合,以及启动时间,冷启动的配置等。
2、给这些资源分配一些权重,比如最大权重为100,配置100秒之后冷启动成功。假如现在是第15秒,则总权重就是100*(n-1)+15。
3、根据算好的权重,进行分配,流量会根据时间流逝逐步增加,直到与其他节点等同。
4、一个极端情况,我的后端只有1个实例,根本就启动不起来。

拿SpringCloud来说,我们就要改变这些组件的行为。

1、ribbon的负载均衡策略。
2、网关的负载均衡策略。

还好,它们都是基础组件,不用来回拷贝代码了。

走马观花

顾名思义,意思就是把所有的接口都提前访问一遍,让系统对资源进行提前准备。
比如,遍历所有的http连接,然后发送请求。
这种方法是部分有效的,一些懒加载的资源会在这个阶段陆续加载进来,但不是全部。
JIT等一些增强功能,可能使得预热过程变得非常的长,走马观花的方式,只能在一定程度上有作用。

再比如某些DB,在启动之后,会执行一些非常有特点的sql,使得PageCache里加载到最需要的热数据。

状态保留

系统在死亡时做一个快照,然后在启动时,原封不动的还原回来。

这个过程就比较魔幻了,因为一般的非正常关闭,系统根本没有机会发表遗言,所以只能定时的,在运行中的系统中做快照。

节点在启动时,再将快照加载到内存中。这在一些内存型的组件中应用广泛。

End

通过比较,我们发现,最靠谱的方式还是进行编码,将warmup逻辑集成在客户端。这个工作可能是痛苦的、漫长的,但结局是美好的。
当然也可以通过“摘除nginx->修改权重->reload nginx”的方式。有时很有效但不总是有效,通常很放心但不总是放心。
一切随你。毕竟没有前戏直奔主题,那叫鲁莽。

更多精彩文章。

微服务不是全部,只是特定领域的子集
这么多监控组件,总有一款适合你
“分库分表” ?选型和流程要慎重,否则会失控
使用Netty,我们到底在开发些什么?
Linux生产环境上,最常用的一套“vim“技巧

Linux五件套之类的。

Linux之《荒岛余生》(一)准备篇
Linux之《荒岛余生》(二)CPU篇
Linux之《荒岛余生》(三)内存篇
Linux之《荒岛余生》(四)I/O篇
Linux之《荒岛余生》(五)网络篇

这篇关于没有预热,不叫高并发,叫并发高的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/721964

相关文章

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也

go动态限制并发数量的实现示例

《go动态限制并发数量的实现示例》本文主要介绍了Go并发控制方法,通过带缓冲通道和第三方库实现并发数量限制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录带有缓冲大小的通道使用第三方库其他控制并发的方法因为go从语言层面支持并发,所以面试百分百会问到

Go语言并发之通知退出机制的实现

《Go语言并发之通知退出机制的实现》本文主要介绍了Go语言并发之通知退出机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、通知退出机制1.1 进程/main函数退出1.2 通过channel退出1.3 通过cont

java如何实现高并发场景下三级缓存的数据一致性

《java如何实现高并发场景下三级缓存的数据一致性》这篇文章主要为大家详细介绍了java如何实现高并发场景下三级缓存的数据一致性,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 下面代码是一个使用Java和Redisson实现的三级缓存服务,主要功能包括:1.缓存结构:本地缓存:使

python多线程并发测试过程

《python多线程并发测试过程》:本文主要介绍python多线程并发测试过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、并发与并行?二、同步与异步的概念?三、线程与进程的区别?需求1:多线程执行不同任务需求2:多线程执行相同任务总结一、并发与并行?1、

Linux高并发场景下的网络参数调优实战指南

《Linux高并发场景下的网络参数调优实战指南》在高并发网络服务场景中,Linux内核的默认网络参数往往无法满足需求,导致性能瓶颈、连接超时甚至服务崩溃,本文基于真实案例分析,从参数解读、问题诊断到优... 目录一、问题背景:当并发连接遇上性能瓶颈1.1 案例环境1.2 初始参数分析二、深度诊断:连接状态与

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

jupyter代码块没有运行图标的解决方案

《jupyter代码块没有运行图标的解决方案》:本文主要介绍jupyter代码块没有运行图标的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录jupyter代码块没有运行图标的解决1.找到Jupyter notebook的系统配置文件2.这时候一般会搜索到

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制