大规模流量下的云边端一体化流量调度体系

news2024/11/17 9:31:36

/  

火山引擎是字节跳动旗下的云服务平台, 将字节跳动快速发展过程中积累的增长方法、技术能力和工具开放给外部企业,提供云基础、视频与内容分发、数智平台VeDI、 人工智能、开发与运维等服务,帮助企业在数字化升级中实现持续增长。LiveVideoStackCon 2023上海站邀请到刘学介绍火山引擎在大规模流量下的云边端一体化流量调度体系。

文/刘学

编辑/LiveVideoStack

大家好,我是来自火山引擎边缘云流量治理团队的负责人刘学。

今天我将会从大规模流量场景的挑战、云边端一体化调度体系、场景落地实例和未来展望四个部分展开介绍大规模流量下的云边端一体化流量调度体系。

-01-

大规模流量场景的挑战

图片

火山引擎边缘云提供了一系列标准化的接入产品,在端边云的接入路径上,长期服务于抖音集团内各种大规模音视频流量APP,包括抖音、今日头条、火山小视频、西瓜视频等。这些应用产生的基础流量主要分为点播、直播、投稿和API,各类型流量的特点分别为:

点播流量:包括CDN边缘层面的超大规模流量,以及多层缓存系统的回源流量。当边缘流量足够庞大、资源足够丰富时,回源流量在源站层面也是非常重要的流量之一。

直播流量:随着大型赛事活动、电商等业务的发展,直播也是我们流量成分中的重要组成部分。直播的流量架构会包括推拉流及审核流等,在源站和边缘层也都会占用比较可观的网络资源。

投稿流量:作为ugc形态的APP,投稿这部分流量是不可忽视的,近一段时间随着点播业务社交属性的增强,投稿流量的压力主要在冷流业务,比如每年投稿系统最大的峰值挑战,其实是在元旦春节的零点,这个时间大家都喜欢集中感慨一下,也给我们的系统提出了比较严峻的挑战。

API类流量:这类流量的特点是请求必须在源站,基于复杂的计算或海量用户数据来完成服务,且单个请求的体量较小。场景包括推荐、搜索、账号、直播间刷礼物、消息等等,这些也音视频APP必不可少的流量构成。

对于多种类型的业务流量,这些流量在外网接入的范畴,会经过火山引擎边缘云的哪些产品集进行支持呢?

①在端内:边缘云提供了字节统一的移动端网络库MNet,经过MNet代理的网络请求,在性能、协议、安全性等方面均能得到深度的定制优化支持;

②在边的层面:边缘云提供了多种形态的缓存和加速服务。其中包括用于支持点播流量的CDN产品,贴近用户提供点播推拉流、转码等计算和网络服务的边缘计算、边缘网络产品,以及为API类流量提供就近接入、全路径加速的DCDN产品;

③在云的层面:在请求到达最终的业务server之前,边缘云接入团队也提供了相应的4/7层负载均衡产品。

那么,对于我们提到的这些异构的流量,在比较复杂的全局接入架构下,会遇到那些有挑战的场景呢?我和我的团队,在过去几年中需要帮助业务去解决的一个主要问题是:对于抖音集团全部的接入流量,在日常用户规模、流量规模都非常庞大的的背景下,在公司层面进行诸如春晚红包、世界杯直播等大型活动时,外网流量接入的总体解决方案是什么?这里面我们面临的流量压力会包括:

•首先,各种流量都有常态的流量作为基础,并且随着活动的拉活,在线人数增加,像API、点播这类日常流量,会有一定的放大;

•在此基础上,我们还要继续承担特定的活动行为所带来的额外流量需求,比如春晚的红包组队任务、世界杯主直播间消息刷屏等;

•最后,就是一些特殊时刻的关键挑战,比如春晚的口播、元旦零点的投稿,这可能是整场活动的焦点时刻,是在前面所有流量上涨的基础之上,再叠加一个比较夸张的需求数字。

在上述流量场景背景下,我们所面临的挑战会包括:

首先是在整个活动的时间轴上,我们需要考虑上述各种流量增长的高水位叠加。这些增长的流量,在时间和空间层面,有些是可预期的,比如红包的时间点,口播广告的时间点等等;有些是难以预期的,比如世界杯的小组赛阶段阿根廷对沙特、德国对日本的这两场,在比分爆冷后整个直播间流量上涨的的情况是远超前期预估的,这需要我们在难以准确预估的前提下,在方案上去根据资源的供给情况做倒推,根据流量上涨的程度设计分级的降级处理方案;

第二层挑战来自于资源层面:首先是周期问题,相对于活动决策,资源建设的周期,比如带宽扩容、机器的采购,都是需要比较长的周期的;其中有部分资源如果短期购买的话,成本是非常高的,这种高价资源的必要性如何去评估;以及如果短期内我们即使买到了一些异构的资源,架构上如何把这些资源比较稳妥的使用起来,在规划层面要给出经过计算排布、确保可行性、变量和风险可控制的接入方案,这些都是资源层面所面临的一些挑战;

最后是容灾场景。在前面我们介绍过的海量需求和复杂架构的背景下,我们需要进一步考虑容灾场景。在活动期间如果发生了各种场景的故障,我们需要具备提前设计好、计算好、演练过的预案。基于常规的接入架构设计方案,进一步的去做n种场景的容灾预案,会将整体的工作量放大n倍,并且进一步的拷问我们的系统极限在哪里,在最恶劣的情况下,我们要舍弃什么,保留什么,如何确保计划的动作能精准的实施下去。这些是我们在容灾极限场景下所面临的挑战。容灾的能力也十分重要。在各种大规模流量的输入情况下,资源十分受限,可能会导致出现一些故障,这时就需要按照提前计算规划以及演练过的成熟预案进行场景展开。场景上的展开,无论是在技术层面还是工作量层面都翻了很多倍,如何保证容灾的可行可控也具有也具有挑战性。

-02-

云边端一体化调度体系

图片

接下来这一页我们介绍一下,在前面提到的这些流量和场景的挑战下,我们从调度视角可以如何对各个接入产品的调度能力和策略进行整合,形成一个云边端一体化的调度体系。首先我们看左边这张架构图,这是对前面的接入架构图的一个简单的细化,里面包含了各组件的流量调度能力的部分:

首先在端内的层面,抖音集团的流量调度体系中,一个比较突出的特色点就是:我们将调度系统的边界,从传统的基于域名解析方式,上升到了端内。基于端内网络库的能力及云控方案,可以使我们获生效速度更快、能力更加强大多样、调度粒度更加精准的新一代解决方案。

其次,在边缘层面,抖音集团大规模的使用了融合架构。其中包括静态CDN在多厂商间的融合、直播CDN在自建的边缘计算资源和三方厂商之间的融合,以及动态CDN的融合。这里面我们提到的融合,即包括同构资源的横向融合,也包括一些异构资源在纵向的跨层融合,比如当我们核心机房的资源不足时,可以将一部分业务上移至距离核心机房较近的边缘资源上。

在源站层面,对于源站各机房、线路的入口带宽,各种接入组件提供了不同的回源调度能力,比如CDN系统基于302、回源配置的源站调度,以及API类流量基于域名解析的源站调度。在源站的入口和下游业务之间,LB产品也提供了最后一层的内网调度能力,将源站业务的调度需求,与复杂的外网接入接入链路进行最大程度的解耦和屏蔽。

由此,我们可以看到调度体系的一个关键特点,就是各系统间的分层和协作。

为了构建一个高内聚、低耦合的调度协作体系,我们需要引用计算机领域的一个通用思想,即能力和策略分层。在特定问题上,需要十分明确的定义,哪些系统是提供配置能力的,哪些系统或角色是负责对配置进行取值决策的,比如对于融合CDN调度系统,在边缘层面首先要负责指定域名在指定线路到指定厂商的决策,这是一个策略系统,其依赖的能力可以是dns、httpdns或者302配置,另一方面,对于回源流量,CDN提供多种回源配置的能力,但源站带宽的规划就是另一个独立的策略系统了。

好的设计能够使每个模块的目标是单一、内聚的,避免在决策时引入太多不合理的顾虑。比如字节在过去的一段时间,各API类流量的机房间流量调度,是依赖外网调度的,这会导致后端业务模块间的调度配置在域名维度被绑死了,不够灵活,同时外网在局部线路带宽不足需要调整时,还要参考各后端业务的部署容量情况,为了解决这类问题,我们在7层转发层强化了源站的内网调度能力,通过对内外网调度的解耦,使得各层级所要处理的问题更加合理。

对于这种跨多层问题的处理,我们也可以从另一个角度去理解。当问题规模足够大时,我们是用sacle up的方式尝试在一个单元中去解决所有问题呢,还是用scale out的方式,将问题进行合理的拆解,将不同的子问题分发到不同的单元中进行处理,最后再进行整合呢?在这里显然,我们走的是scale out的路线。

最后,每个调度子系统各司其职的前提下,我们仍然需要一个对全局情况进行汇总的综合调度系统,对应右边的这个系统BTM。对于一些综合性的问题,需要在全局层面进行统一决策协调的时候,我们仍然需要一个顶层的仲裁者的角色。比如前面我们提到过的活动期间的容灾场景,假设一个源站机房故障,各流量负责的系统都在向其他机房切流,那么谁来计算和保障其他机房的容量是安全的呢?谁来协调各流量间的降级优先级和降级深度呢?这都需要一个综合决策性质的系统,参考各业务流量的特点、流量实时大小,以及资源的水位和状态,从全局角度进行决策,在调度系统通用的这几个目标下,即容量、容灾、成本、质量、以及考虑特定的业务约束,寻求相对的最优解或者可行解。

-03-

场景落地Story

Story1

图片

接下来我们通过一些具体的场景和案例,介绍我们调度体系能够提供的解决方案,以及对应的特点。

首先还是将镜头拉回到春晚的场景,我们先讲一个最极端的时刻,就是口播时刻。这个场景在业务层面的情况是,主持人会在特定的广告时刻,引导全国的观众打开抖音系的app,进入红包活动。在技术层面,预期会发生的流量包括,以活动期间高于常规晚高峰的大盘流量为基础,段时间内叠加海量的冷启流量和活动流量。冷启流量包括启动后的一系列api请求,以及首刷点播,活动流量主要指红包玩法。众所周知,红包玩法可以做一系列的缓存、打散、削峰的定制化设计,反而是冷启流量更加难以控制,因为口播行为是固定的,口播带来的冷启请求也是无法做打散的。

为了应对这些挑战,传统的解决方案包括,对于首刷点播流量,可以通过限制码率、推荐高热视频等手段尽量减少CDN流量的消耗,对于API类流量,可以通过版本更新,将活动版本的冷启流量限制到最低,但这受限于活动版本的开发时间和发布周期,往往到活动时刻的版本覆盖率并不理想。在此基础上,常见的一些处理方案可能包括在dns层做黑洞,但整域名的封禁往往会伴随这很多误杀,且dns层面的封禁和解封时效性也并不可控,或者将接入层作限流作为主要手段,单这需要对接入层堆很多的资源,毕竟流量洪峰到来时,握手和协议的开销不可避免。

那么,是否存在着更加有效的解决方案呢?在抖音集团内部,端上的请求主要是通过定制化的网络库进行代理发送的。可以看到,请求处理的过程中,会由网络库进行内部域名的定制、协议优化、甚至请求drop等操作,这一系列操作都是云端实时可控的,经过网络库的请求,在调度层面可以获得更快、能力更强、维度更加精准的优势:

首先对于调度的生效速度,我们可以看到,端内的请求根据是否连接复用,会分为2种不同的执行情况:

①使用dns或httpdns解析,在变更解析结果进行调度时,除去解析结果缓存更新速度的影响,链接复用也是影响切流速的重要因素。在链接复用维持的较好的业务上,可能数十分钟都难以完成切流操作。

②端内调度使用的是域名替换的机制,在请求发起前决策具体要使用的域名,这样就避免了链接复用的影响。当前端调度我们能做到5min内切流93%的生效速度,结合动态加速回源机制,最快能做到2min97%的外网切流生效速度,这种方式对比常规域名解析的切流形成了巨大的优势。

其次,在能力方面,由于网络库代理了端上网络请求的全流程,因此我们在请求的各个阶段都可以施加定制逻辑,比如决定这个请求使用什么协议,解析结果的使用策略如何,自动化的测速选路,甚至决定这个请求是否要发出。这对比传统的决策一个非连接复用的请求的目标ip,在能力上也是得到了极大的提升。

最后,在调度的粒度上,由于端上网络库的获取机制是基于用户参数的,因此我们的调度除了区分传统的地域运营商外,还可以增加各种丰富的维度,比如根据用户的机型和操作系统版本、app版本、用户id分组、实验分组,甚至能够在域名之内对不同的path定制不同的调度策略。

综上所述,我们在端内的调度层面提供了很多强大的特性,可以一定程度上理解为将7层能力下沉到端上,并且,这一切是不需要额外的资源消耗的。

图片

这张图是在21年春晚的现场,基于我们的接口级降级能力,现场全站实际流量的控制情况。在整场晚会期间,我们通过实时控制及预埋配置等手段,确保降级配置的在各版本的覆盖度。在口播前后,我们能做到2min内执行深度降级,口播结束2min后全量回复。可以看到,中间这个峰值就是口播降级后冷启流量的冲锋,如果没有高效灵活的降级策略,这个峰值会对我们系统造成比较大的冲击。最终正常活动在用户体验无损的情况下,基于有限的资源消耗顺利结束。

Story2

图片

接下来我们介绍一个端边调度结合的案例:

同样是春晚场景,即使我们在端上做了一系列的深度降级尝试后,流出到网络上的需求,依然对我们的资源产生了巨大的压力。比如在动态加速层面,我们的需求已经到达了97%的规划水位。这对我们提出了一个新的问题,如何做精细化的调度控制,确保流量在高水位情况下的运行是高度可控的。

对于静态流量,我们常见的精细化调度,可以通过302调度,或者在feed推荐服务返回资源链接时,顺便在服务端进行精细化的厂商间调度。这些操作对于CDN这种资源类的请求是合理的,因为调度的成本相对与请求的成本还是比较小的。但是对于API类流量,我们不太可能在请求同时,为了做调度而大范围的增加一跳302,或者对每个请求附加一次调度计算,这样成本就太高了。我们实际的解决方案,还是基于端能力的维度控制能力,将端按照设备id进行hash分组,控制不同分组的用户,指定请求发往不同的厂商,从而低成本的实现了高度精准可控的调度效果。

Story3

图片

接下来介绍一个云边调度结合的案例:

仍然是春晚场景,当我们的流量需求过大时,即使我们在端上做了足够的降级,在边缘层面做了精细化的调度,但是在源站层面,当时我们手上的资源,仍然不能满足需求。这就需要对我们的架构进行一些调整。

经过业务方的努力,可以将一部分便于拆解的活动业务,上移到源站机房之外,距离源站机房较近且有专线互联的边缘资源上,那么接下来对调度系统的挑战就会被细化成:

首先,业务在新的架构下部署,如何引导流量进行快速验证、在云边之间做灵活的流量切换;

其次,是流量进入边缘侧后,在边缘层面的多个节点间,符合确保负载均衡、就近接入的效果,以及容灾效果。

应对这些挑战,火山引擎提供了功能丰富的标准化解析类调度产品TrafficRoute。TrafficRoute能够将多个边缘节点上的业务,进行地址池的定义和编排,结合每个接入点的容量、以及临近省份线路的质量和举例,进行综合的负载均衡调度决策,并且其自带的拨测模块,也能够快速的发现故障并自动执行故障转移。

TrafficRoute在真实的海量活动流量场景下,提供了有效可靠的支持,也是我们内部最早完成内外部统一的标准化调度组件,欢迎大家在火山引擎官网进行试用。

Story4

图片

接下来介绍云边端一体的综合调度系统。当缺乏一个全局综合操作系统时,可能会遇到如下的情况:各标准化的产品,基于自身提供的能力,各自面向不同的业务需求提供服务。其中有一些是经过接入方SRE把控的,有一些是业务直接和产品对接的。在这种情况下,各需求和方案没有一个统一的控制方,可能会导致方案的规范性问题,比如有些自动容灾特性被遗漏,或者有些特性被应用到错误的场景上。此外,各方案独立维护,对于全局公用的资源缺乏协调决策,当出现冲突时,方案之间的同步成本较高,决策链条较长,这在大型流量场景下都导致了全局可控性变差。

图片

为了规范性的管理和解决上述问题,我们对调度体系中的策略管理体系进行了梳理。从策略影响的资源角度进行划分,对于完全独立控制资源的策略系统,不需要综合调度系统进行干涉的,可以直接对接全部需求方,比如融合CDN在厂商间的容量分配,或者自建CDN在节点间的容量分配,这些问题都是系统内闭环的。

另一方面,对于需要进行综合决策的资源,比如源站的带宽、各业务公用的接入集群,我们将需求统一收敛到全局流量综合调度系统BTM中,由BTM负责感知全局的流量和资源情况,在具备全量背景信息的状态下进行综合决策,并负责将决策结果下发至各实际调度系统中去执行。

那么,BTM作为一个全局感知、综合决策的系统,其内部应当如何设计呢?这是一个在业界没有参考的问题,需要我们独立去抽象和拆解它。我们首先从系统的核心元数据模型进行介绍。

根据经验,我们认为大多数调度决策系统的共性问题,可以抽象为流量、策略和资源三元素。这个模型可以描述为,首先我们存在这一定接入资源,这些资源有容量、拓扑、状态信息。其次,系统中存在着各种流量,每种流量可能由不同的调度系统负责,根据不同的策略,最终都在这个具有拓扑和容量的资源系统中。只要我们能对这个三元素的元数据完成建模,就有可能在一个抽象的空间中进行模拟和规划,快速获得全局调度的可行解。

图片

接下来简单介绍一下BTM系统的架构:

首先整个系统的运行被划分成物理层抽象层:如同我们为了让一次编译后的程序运行在不同的硬件机器上一样,我们需要有操作系统,有各种硬件设备的驱动适配,有虚拟的运行时地址空间,通过物理和抽象之间的映射,为上层策略层提供统一稳定的控制环境。物理层和抽象层的边界,我们称为adapter,对标操作系统的驱动。adapter需要适配各个实际调度系统的api、逻辑和特性,尽可能的将各系统的能力按照流量、策略、资源三元素进行抽象,完成状态上传和指令下达的功能。同时,我们还需要一套强大的数据adapter,根据多种数据源,根据BTM对各种流量和资源的定义将真实的流量运行数据反馈上来。

在抽象层内,我们的工作会分为静态管理和运行时管理

在静态管理范畴,BTM的主要工作是基于对资源的容量及拓扑、流量的调度策略模型的抽象,对流量需求进行管理,在规划层面对流量进行快速的预分配,其中也包含了大量容灾场景的自动规划工作。这些前置性的工作能够以较低的成本,快速发现局部的资源风险,为流量架构设计及资源建设提供有效的输入。

运行时的管理,是BTM的核心模块。其中包含了对流量的实时数据、调度配置的实时元数据取值的统一管理,在运行时根据资源和流量调度的实时结果,快速完成规划,并通过adapter下发执行,观察执行后的流量变化情况,在下一轮中进一步调整,最终形成闭环。当前BTM的规划能力,对于上千条flow,在上百各资源对象的规划取值,已经能够做到分钟级求解。

图片

最后我们从另一个角度来介绍BTM系统的愿景,即数字孪生。

数字孪生的概念提出:对于物理运行的系统,应当存在着一套infrastructure as code的数字系统,对其进行实时映射。

那么基于这个数字的映射,我们就可以监控观察系统的状态,当系统存在问题时,能够进行快速的诊断。当我们预期要做一些操作时,可以在数字孪生系统中对系统行为进行预测,从而提前规避风险。最终,数字系统对物理系统应当是具有可控性,能够将我们规划验证好的操作,快速批量的执行下去。基于这样的数字孪生系统,我们的调度体系对与大规模复杂流量场景的控制,能够获得更加成熟、高效、可控的效果。

-04-

未来展望

图片

结合实际处理线上大规模流量的经验,我们提出对未来的一些展望。

首先在资源层面,当前我们源站接入正在向更加复杂的pop点方式演进。如果调度系统能够适配加入资源的复杂度,就能获得新资源在容量和成本上的收益。当然这对我们的资源体系构建、容灾场景的复杂化,都提出了进一步的挑战。

其次,字节整体的服务架构正在向着多Region化、多云的方向演进,这对调度系统的适配也提出了进一步的挑战,我们需要在抽象层面全面适配业务的单元化改造。

最后综合调度系统作为一个协调者,他对下游调度系统的影响,有些是指令式的。比如直接控制一个域名的解析,这种方式对底层的能力系统是没有决策空间的;而另一种和下游调度系统的联动是策略式的,是间接的影响。比如我会希望直播系统在源站某条线路的使用,最多不能超过一个quota值,而在quota内的调度,由直播调度系统来自行决策。这样对综合调度系统提出的挑战是,为了给出实际可执行的决策,我们需要对这些策略型的调度系统进行建模,根据一个有效的模型推导出有效的quota决策,进而持续提升策略联动的可控性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1002042.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在 IntelliJ IDEA 中远程部署 Java 程序

文章目录 远程调试与远程部署的区别远程部署的步骤完整源代码 笔者的运行环境: 客户端: 部署成功过的客户端的 Java 版本: Java 17.0.7 部署成功过的客户端的 Java 程序: Spring Boot 3.1.0 部署成功过的客户端的 IntelliJ IDEA…

论文浅尝 | 思维树:使用大语言模型反复思考解决问题

笔记整理:许泽众,浙江大学博士,研究方向为知识图谱上的神经符号推理 链接:https://arxiv.org/abs/2305.10601 1. 动机 语言模型是一种强大的工具,可以用于各种需要数学、符号、常识或知识推理的任务。然而,…

初识MyBatis(一)基于配置文件下的一些增删改查

MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录 MyBatis 是一个 半自动的ORM(Object Relation Mapping)框架 创建好m…

手机+卫星的科技狂想

最近硬件圈最火热的话题之一,应该就是突然上线、遥遥领先的华为Mate 60 Pro了。 其中,CPU和类5G网速是怎么实现的,是大家特别关注的问题。相比之下,卫星通话这个功能,讨论度就略低一些(没有说不火的意思&am…

62、SpringBoot 使用RestTemplate 整合第三方 RESTful 服务

这节的要点: 就是弄两个项目 , 从 端口9090 这个项目,通过 restTemplate, 去访问 端口8080 的项目,并获取8080项目的数据。 ★ RESTful服务包含两方面的含义 1. 自己的应用要暴露一些功能供别人来调用。此时我们是服…

postgresql-DML

DML 语句 创建示例表插入数据插入单行数据插入多行数据复制数据返回插入的数据 更新数据单表更新跨表更新返回更新后的数据 删除数据单表删除跨表删除返回被删除的数据 合并数据MERGE 语句INSERT ON CONFLICT DML 语句与 CTE 创建示例表 CREATE TABLE dept (department_id int…

面向Ai设计的Mojo编程语言支持下载,当前只有Linux系统版本

据了解,Mojo是Modular AI公司开发的专门面向AI设计的编程语言,号称比Python快68000倍。 Mojo现已开放本地下载运行,除了编译器之外,Mojo SDK还包括一整套开发者和IDE工具,并用来构建和迭代 Mojo应用。 公司方面表示&…

leetcode 589. N 叉树的前序遍历(java)

N 叉树的前序遍历 题目描述前序遍历后序遍历 题目描述 难度 - 简单 LC - 589.N叉树的前序遍历 给定一个 n 叉树的根节点 root ,返回 其节点值的 前序遍历 。 n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔(请参见示例…

RK3399平台开发系列讲解(内核调试篇)USB摄像头快速测试

🚀返回专栏总目录 文章目录 一、检测设备二、安装必要的库三、 mjpeg-stream 安装四、实时预览沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇介绍如何快速测试 USB 摄像头。 一、检测设备 将 USB 摄像头插上,查看是否找到设备,输入指令:v4l2-ctl --list-d…

vuex中actions异步调用以及读取值

项目场景: 提示:这里简述项目相关背景: 将根据segmentId查出来的合同信息托管到vuex中,让每个人都可以获取到合同信息 描述以及问题点 1:调用vuex异步函数的语法是 this.$store.dispatch(actions方法名,值) 2&#…

JUC并发编程--------线程安全篇

目录 什么是线程安全性问题? 如何实现线程安全? 1、线程封闭 2、无状态的类 3、让类不可变 4、加锁和CAS 并发环境下的线程安全问题有哪些? 1、死锁 2、活锁 3、线程饥饿 什么是线程安全性问题? 我们可以这么理解&#…

计算机竞赛 基于设深度学习的人脸性别年龄识别系统

文章目录 0 前言1 课题描述2 实现效果3 算法实现原理3.1 数据集3.2 深度学习识别算法3.3 特征提取主干网络3.4 总体实现流程 4 具体实现4.1 预训练数据格式4.2 部分实现代码 5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习机器视觉的…

如何设计一个复杂的业务系统

一、设计要干啥 作为一个企业级应用架构,自然会把专注点转移到业务应用功能性设计本身上来。现在来说对于一个复杂业务架构进行设计,我们要想做到又快又好,无非是两种情况:一是架构师本身对业务理解很深、能力超强、炉火纯青&…

QT QMdiArea控件 使用详解

本文详细的介绍了QMdiArea控件的各种操作,例如:新建界面、源代码、添加界面、移除一个子窗口、设置活动子窗口、子窗口级联排列、子窗口平铺排列、关闭当前子窗口、关闭当前子窗口、返回当前子窗口、返回当前子窗口、返回子窗口列表、信号槽、单击信号、…

使用python-docx对doc文档修改页眉时,遇到的一点小问题

之前在百度和google搜到的也修改页眉的方式,代码如下 import docx # 打开 Word 文档 doc docx.Document(sample.docx) # 遍历每个节 for section in doc.sections: # 获取节的页眉 header section.header # 获取页眉中的段落 p header.paragraphs[0] # 替换段落…

冒泡排序、选择排序、插入排序、希尔排序

冒泡排序 基本思想 代码实现 # 冒泡排序 def bubble_sort(arr):length len(arr) - 1for i in range(length):flag Truefor j in range(length - i):if arr[j] > arr[j 1]:temp arr[j]arr[j] arr[j 1]arr[j 1] tempflag Falseprint(f第{i 1}趟的排序结果为&#…

基于51单片机+DS1302时钟模块+4位数码管显示

一、DS1302时钟模块简介 二、绘制Proteus 仿真电路图 三、编写51单片机代码 #include "DS1302.h"// 位定义 sbit DS1302_DATA P3^3; sbit SCLK P3^2; sbit RST P3^1;// 向DS1302写一个字节 void DS1302_Write_Byte(unsigned char addrOrData) {unsigned char i;f…

RocketMQ的架构及概念

RocketMQ就是一个消息中间键用于实现异步传输与解耦 那什么是消息中间键呢? 消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展…

CSP 201312-1 出现次数最多的数

答题 用两个map&#xff0c;一个map记录每个数出现的次数并降序排序&#xff0c;另一个map将次数作为键&#xff0c;数本身作为值&#xff0c;降序排序&#xff0c;搞定 #include<iostream> #include<map> using namespace std; int main(){map<int,int,great…

arm栈推导

按照栈生长方向分&#xff1a;可以分为递增栈&#xff08;向高地址生长&#xff09;&#xff1b;递减栈&#xff08;向低地址生长&#xff09; 按照sp执行位置来分&#xff1a;满栈&#xff08;sp指向栈顶元素的位置&#xff09;&#xff1b;空栈&#xff08;sp指向即将入栈的…