什么是多运行时架构?

服务化演进中的问题

自从数年前微服务的概念被提出,到现在基本成了技术架构的标配。微服务的场景下衍生出了对分布式能力的大量需求:各服务之间需要相互协作和通信,以及共享状态等等,因此就有了各种中间件来为业务服务提供这种分布式能力。

图片

我们熟知的“Spring Cloud 全家桶”正是凭借着对各种中间件优秀的集成与抽象能力,成为了当时炙手可热的项目。

然而随着业务的快速发展,组织规模的不断扩大,微服务越来越多,系统规模越来越大则是服务化体系架构演进的必然。这就带来了两方面复杂度的上升:

1.服务治理与接入的复杂度

服务治理代表了系统中服务资源的地图及其获取途径,例如通过注册发现服务提供图谱能力,路由、网关、负载均衡服务提供获取途径。

服务接入则代表了如何使用系统中的服务能力,例如通过中间件提供的API 协议或是封装的 SDK 来接入该中间件。各种业务服务越多、中间件越复杂,整个系统服务治理与接入的复杂度就会急剧上升。

2.团队协作的复杂度

该复杂度主要体现在团队的认知负载上,复杂的依赖、沟通、协作将明显拖慢交付进度。正如康威定律所述的,由于服务复杂度的上升,团队之间的交互成本也随之上升。

如下是复杂度上升问题的一个显而易见的例子。

图片

当系统中的中间件都通过 SDK 作为其外化能力的控制方式,来封装协议、数据结构与操作方法。随着中间件数量和种类不断增多,大量孤立的 SDK 被绑定在业务服务上,导致两方面问题:

  • 版本升级困难:SDK 与业务服务的强依赖性导致想要升级 SDK 版本变得异常复杂与缓慢
  • 业务服务难以异构:SDK 所支持的语言反向限制了业务服务所能选择的语言,例如 Spring Cloud 几乎没有官方的多语言支持

如何治理这种不断上升的复杂度呢?复杂问题归一化是一种不错的手段。

什么是多运行时架构

多运行时微服务架构(Multi-Runtime Microservice Architecture)也被简称为多运行时架构,是由 Red Hat 的首席架构师 Bilgin Ibryam 在 2020 年初所提出的一种微服务架构形态,它相对完整地从理论和方法的角度阐述了多运行时架构的模型(实际上,在 2019 年末,微软的 Dapr v0.1.0 就已经发布)。

暂时先抛开到底什么是“多运行时”不谈(因为多运行时这个名字个人觉得起得可能不太妥当),先看看多运行时架构都包括了哪些内容。

分布式应用四大类需求

上一节提到,为了治理不断上升的复杂度问题,归一化是手段之一。归一化的第一步就是对问题进行归类。

Bilgin Ibryam 梳理了分布式应用的各类需求后,将其划分到了四个领域内:

图片

(来源:Multi-Runtime Microservices Architecture)

分别是:

  • 生命周期:即应用从开发态到运行态之间进行打包、部署、扩缩容等需求。
  • 网络:分布式系统中各应用之间的服务发现、容错、灵活的发布模式、跟踪和遥测等需求。
  • 状态:我们期望服务是无状态的,但业务本身一定需要有状态,因此包含对缓存、编排调度、幂等、事务等需求。
  • 绑定:与外部服务之间进行集成可能面临的交互适配、协议转换等需求。

Bilgin Ibryam 认为,应用之间对分布式能力的需求,无外乎这四大类。且在 Kubernetes 成为云原生场景下运行时的事实标准后,对生命周期这部分的需求已经基本被覆盖到了。

因此实际上我们更关注的是如何归一化其他三种需求。

与单机应用的类比

单机应用一般大都是以用户态进程的形式运行在操作系统上。显然,与微服务类似,单机应用的核心关注点也是业务逻辑,与业务关系不大的支撑能力,都要依赖操作系统来完成。

因此上述由 Bilgin 归纳的分布式应用四大类需求,其实我们很容易就可以和单机应用进行合理的类比:

从上述类比来看我们发现,单单是 Kubernetes 可能还不足以称为是 “云原生操作系统”,除非有一种解决方案,能在分布式环境下,把其他几项支撑能力也进行归一化整合,才能理直气壮的冠此大名。」

Service Mesh 的成功 

Service Mesh 在近几年的高速发展,让我们认识到网络相关的需求是如何被归一化并与业务本身解耦的:

通过流量控制能力实现多变的发布模式以及对服务韧性的灵活配置,通过安全能力实现的开箱即用的 mTLS 双向认证来构建零信任网络,通过可观察性能力实现的网络层Metrics,Logging 和 Tracing 的无侵入式采集。

而上述服务治理能力,全部被代理到 Sidecar 进程中完成。这就实现了 codebase level 的解耦,网络相关的分布式能力完全抛弃 SDK。

图片

伴随着 Service Mesh 的成功,我们不禁会想到,是否可以将另外的两种需求——状态和绑定 ——也进行 Mesh 化改造呢?

分布式能力 Mesh 化

基于对 Service Mesh 的拓展,我们大可以将其他的能力也进行 Mesh 化,每一类能力都以 Sidecar 的形式部署和运作:

图片

在业界也有不少从某些能力角度切入的方案:

图片

(来源:Multi-Runtime Microservices Architecture)

我们可以发现,各类方案都有自己的一套对某些能力需求的 Mesh 化方案,合理地选择它们,的确满足了分布式能力 Mesh 化的要求,但却引入了新的问题:

  • 复杂度从业务服务下沉到了 Mesh 层:多种 Mesh 化方案之间缺乏一致性,导致选型和运维的成本很高
  • 多个 Sidecar 进程会带来不小的资源开销,很多解决方案还需要搭配控制面进程,资源消耗难以忽视

对业务复杂度上升的归一化,现在变成了对 Mesh 复杂度上升的归一化。

Multi-Runtime = Micrologic + Mecha

Bilgin Ibryam 在多运行时微服务架构中,对前述讨论的各种问题点进行了整合,提出了 Micrologic + Mecha 的架构形态:

图片

(来源:Multi-Runtime Microservices Architecture)

在 Micrologic 中只包含业务逻辑,尽可能的把分布式系统层面的需求剥离出去,放到 Mecha 中。从 Mecha 的命名就可以明白它的功能:

由提供各种分布式能力的 “机甲” 组成的 Sidecar 进程,与 “裸奔的” 业务逻辑一起部署。因为是 Micrologic 进程和 Mecha 进程共同部署的这种多个 “运行时” 的架构,所以称之为 “多运行时架构”。

Mecha 不仅成功地将分布式能力从耦合的业务进程中抽取出来,还整合了方案,避免了多种方案混合的额外成本。可以说 Mecha 在本质上提供了一个分布式能力抽象层。

因此与其叫 “多运行时架构”,不如叫 “面向能力的架构”。

微软的尝试:Dapr

Dapr 是微软主导开发并开源的一种 Mecha runtime,从宏观上看它处在整个架构的中间层:

图片

(来源:Dapr)

自上而下分别是业务层、Dapr Runtime层、基础设施层。Dapr 通过 Http 或 gRPC API 向业务层提供分布式能力抽象,通过称为 “Component” 的接口定义,实现对具体基础设施的插件式管理。

Building Blocks

作为一个合格的 Mecha,最关键的就是如何定义分布式能力抽象层。如何把各类中间件提供的分布式能力定义清楚是一项挑战。Dapr 中定义的分布式能力抽象层,称为 Building Blocks。顾名思义,就是一系列的 “构建块”,每一个块定义了一种分布式能力。

图片

(来源:Dapr)

其中有一些 Blocks 的能力由 Dapr 自己就能实现,有一些则需要由实际的基础设施或中间件来实现。选取几个典型举例说明:

  • Service-to-service Invocation:提供服务间调用的能力,其中也隐含了服务的注册与发现。该 Block 的能力由 Dapr 直接实现。
  • State management:提供状态管理能力,最简单的就是存取状态。该 Block 需要其他基础设施通过 Component 的形式实现,例如定义一个 Redis Component。
  • Publish and subscribe:提供消息发布和订阅的能力,这是非常典型的一种分布式能力。也需要通过基础设施来实现,如定义一个 Kafka Component。

Dapr 的限制与挑战

Dapr 期望通过定义一个能容纳所有需求的分布式能力抽象层,来彻底解放业务逻辑。从归一化的角度看,不得不说这是一种大胆而富有野心的尝试,理想条件下的确能非常优雅地解决问题。但现实总是充斥着各种跳脱出理想的情况,Dapr 在推广的过程中遇到了很多限制与挑战。

与 Service Mesh 整合

作为面向开发侧提供的能力抽象层,Dapr 在网络能力上包含了 mTLS、Observability 与 Resiliency(即超时重试熔断等),但并没有包含诸如负载均衡、动态切换、金丝雀发布等运维侧的流量管理能力。

图片

(来源:Dapr)

因此对于不断走向成熟的业务系统,可能既要 Service Mesh 在运维侧的流量管理能力,又要 Dapr 在开发侧的分布式抽象能力,不管谁先谁后,都将面临一个问题:怎样搭配使用它们才是正确的?某些场景下可以做适配,如:

  • 对于 distributed tracing 的能力,如果采用 Service Mesh 来实现,则需要考虑将原本 Dapr 直连的中间件也加入 mesh 网络,否则会 trace 不到。但从 distributed tracing 本身功能角度讲,更应该使用 Dapr。
  • mTLS 应该只在 Dapr 或者 Service Mesh 中开启,而不应该都开启。

但 Dapr 与 Service Mesh 配合使用中难以避免的是开销的问题,包括资源开销和性能开销。

每个应用 Pod 携带两种 sidecar,再加上 Dapr 和 Service Mesh 自己的控制面应用(高可用方案主备或多副本),这些资源开销是无法忽略,甚至是非常可观的。

而由于 Service Mesh 网络代理的流量劫持,网络调用需要先经过 Dapr sidecar,再经过网络代理 sidecar,被代理两次,也会造成一定的性能开销。

下表是汇总的 Dapr 官方标注的 daprd 资源与性能消耗数据,以及 Istio v1.16(最新版未找到)官方标注的 envoy 资源与性能消耗数据:

简单计算一下就会发现,当拥有 1000 个业务实例时,dapr + istio 的 Sidecar 进程可能会消耗 800+ vCPU 和 60+ GiB 内存。

随着分布式能力抽象层的不断扩展,到底哪些属于开发侧,哪些属于运维侧,也许不会像现在这样泾渭分明了。因此已经有对 Multi-Runtime 与 Service Mesh 能力边界越来越模糊的讨论。

Sidecarless?

从上一节的表格我们发现,资源消耗以及性能的问题其实不只是 Dapr 下的场景,实际上它是 sidecar 模式自有的限制,因此在 Service Mesh 领域的讨论中,已经有提出 Sidecarless 的概念了,即通过 DaemonSet 而不是 Sidecar 的形式来部署网络代理。

图片

对于网络代理的 Sidecarless 化,支持方认为它能带来高性能、低资源消耗的优点,而反对方则认为它会导致安全性与隔离性差、故障的爆炸半径过大等缺点。

那么,Mecha 是否也可能会走向 Sidecarless 呢?

与网络代理的 Sidecarless 类似,如果将 Mecha 做成 Daemonset,其优劣势也差不多。而 Daemonset 形式的 Mecha,由于只启动一次,可能会在 Serverless 的场景下大幅缩短 Serverless 函数的执行时间。对此 Dapr 项目也有相关的讨论。

就像今年 Cilium 发布支持 Service Mesh 能力的办法,通过 eBPF 在内核态实现 L3 L4 层能力,而对应的 L7 层能力则交给用户态的 Envoy 处理这种将问题一分为二的思想,也许多运行时架构的未来方案也可能是折中或是多种方式结合的。例如采用在 Node 上按 Service Account 或 Namespace 运行多实例,或是轻量级 Sidecar 做协议转换+DaemonSet 做流量管理和网络调用。

当然 DaemonSet 也有其固有的缺陷,资源被共享从而降低消耗的同时,故障也被共享了,而且故障产生的伤害面也变大了,此外还会导致 DaemonSet 被应用使用的争抢问题,以及应用之间的数据暴露风险。到底后续将会如何演进,我们拭目以待。

定义抽象能力的(API)的困境

分布式能力抽象层,是对分布式场景下需求的抽象性定义,抽象作为一种共识,其要义就在于保留共性而排除个性。但实际当中会发现,同类型中间件的差异化恰恰体现在了一些高级的、细分的专有特性上,很多业务对中间件选型的原因也在于这些专有特性上。

这就引出了一个困境:抽象能力所覆盖的需求,其丰富程度与可移植性成反比。

图片

就如上图所示,如果抽象能力范围只覆盖到红色的部分,则组件 ABC 的专有特性都无法被引入,而如果抽象能力范围覆盖到绿色,那么就无法迁移到组件C。

Dapr 的 Building Blocks 中,State management 就存在这样的一个例子:

State management 定义了基于事务操作的能力 /v1.0/state/<storename>/transaction,支持 State management 能力的 Component 有很多,对于支持事务的中间件如 Redis 就一切正常,但有一些并不支持事务的如 DynamoDB,则这种能力就无法使用。

定义抽象能力的困境,本质上是一种对能力收敛的权衡,这种权衡可能是与具体的业务需要高度相关的。

关于如何降低专有特性对能力集合可移植性的冲击,敖小剑在他的文章《死生之地不可不察:论API标准化对Dapr的重要性》中提到了四种解决思路:

(1) 在 Mecha 层弥补能力缺失 

如果缺失的能力支持用基础能力来间接实现,就可以在 Mecha 内做处理。例如对于不支持批量写入的基础设施,在 Dapr 中通过 forloop 连续调用单次写入也能间接地弥补这一能力(虽然无法做到性能一致)。 然而这样也可能导致 Dapr 越来越臃肿,怎么权衡见仁见智。

(2) 在 Component 层弥补能力缺失 

Component 作为某种具体基础设施与 Dapr 的适配器,可以将 1 中的方案下沉到 Component 里面,避免 Dapr 本身的臃肿,然而这种办法的缺陷在于每种基础设施只要想弥补缺失的能力,就都要分别在自己的 Component 中实现一遍。

(3) 直接忽略某些缺失的能力 

例如在 State management 中对多副本强一致性的配置属性 consistency,假如实际的存储中间件是单副本架构,那么就可以直接忽略掉该属性。

(4) 其余的情况,只能在业务侧处理 

就像前文提到的事务能力,对于不支持的基础设施必须要明确报错,否则可能导致业务不正确。这种情况就只能在业务侧做限制,本质上是侵入了业务层。

这四种解决思路从权衡与折中的角度,覆盖了绝大多数能力缺失的场景,本质上这些思路属于 “坚守API 能力交集” 的办法。假如跳出“抽象共识”这一限制,我们是否可以试图构建出一套包含了所有分布式能力的“大全集”呢?显然只是理论可行,但不现实。

然而,在企业实际的场景下,这个“全集”的规模可能并不一定像我们想象的那么庞大,因此就有可能提供额外的一种思路,即对分布是抽象层进行扩展,将有限规模的“个性”全部包含进去,形成 “并集” 从而规避上述问题。

图片

蚂蚁 Layotto 的设计中体现了这种方案,详见下文。

蚂蚁金服的方案:layotto

蚂蚁金服作为 Dapr 的早起使用者,在落地的过程中结合遇到的问题及业务思考,在 2021 年年中推出了自研的 Mecha 方案:layotto。

Layotto 的架构

图片

(来源:Layotto)

非常有趣的一点是,layotto 是以 MOSN 为基座的。MOSN 是蚂蚁金服自研的网络代理,可用于 Service Mesh 数据面。因此 layotto 类似于是 MOSN 的一个特殊的插件,向业务侧提供分布式能力抽象层,并且仍然以 Component 的形式封装各种中间件的访问与操作,而在这之下的所有网络层交互全部代理给 MOSN。

由于 layotto 在运行态上是与 MOSN 绑定在一个 Sidecar 内的,因此就减少了一部分前文提到的两个 Sidecar 之间通信的开销。当然 layotto 可以这样做也有一部分原因在于 MOSN 本身已经在蚂蚁内部大规模落地,同时蚂蚁也有足够的研发强度来支撑 layotto 的开发。

“私有协议”与“可信协议”

Layotto 的开发者,在讨论多运行时架构以及 layotto 落地实践的文章中,尝试对可移植性的概念进行了扩展,将支撑分布式能力的协议划分为“可信协议”与“私有协议”。

其中,可信协议指代的是一类影响力很大的协议如 Redis 协议、S3 协议、SQL 标准等。这一类协议由于用户众多,且被各类云厂商所支持,因此可以认为它们本身就具有可移植性。

私有协议则指代一些企业内部自研的、闭源或影响力小的开源软件提供的协议。显然这一类协议才更需要考虑抽象与可移植性。

因此实际上的所谓分布式能力抽象层可能会是如下图所示的样子:

图片

(来源:如何看待 Dapr、Layotto 这种多运行时架构?)

各类可信协议不再二次抽象,而是直接支持,对其余的私有协议再进行抽象。这种直接支持开源协议的思路,部分缓解了定义抽象能力的困境问题。

灵活的扩展模型

前文提到的 API 扩展形成 “并集”,Layotto 通过提供 In-Tree 形式的私有 API 注册点,实现了不修改 Layotto 代码就能扩展 API 能力:

图片

(来源:Layotto 官方文档)

从代码角度看,Layotto 是通过暴露 API 注册钩子,暴露启动入口,来允许用户自行扩展代码,之后再调用启动函数启动进程。这样扩展 API 代码与 Layotto package 级隔离,但编译后可形成同一个二进制文件。

另外,通过 MOSN 的 WASM 插件能力,Layotto 也支持通过 WASM 镜像来扩展 API Filter。

未来展望

虽然多运行时架构这种理念从提出到现在只有两年,但已经很少有人会否认它所带来的价值,不论是 Dapr 还是 layotto 的快速发展,都明确了头部企业对这一领域的投资逻辑。

当然目前从理论到实践可能都不够成熟,大家在落地实践的过程中也都会或多或少遇到前文提到的一些局限。但这些局限所处的层次大都是工程化、技术选择等具体的问题,相信随着各方技术的不断整合,实践的不断完善,问题都能解决。

对多运行时架构实践的未来,结合当下的限制、挑战以及趋势,我们也许能勾勒出某种未来可能的架构形态:

图片

在这一架构形态下:

  • 分布式能力抽象层提供标准能力抽象,以及灵活扩展的私有协议的能力
  • 既成标准协议(对前文 "可信协议" 的另一种提法)作为 "既成的" 抽象能力,在Mecha 层只做协议转换或直接透传
  • Mecha 与网络代理层进程级耦合,各类特性不再明确区分开发侧与运维侧
  • 进程在 Node 上按租户/namespace 以及高可用要求划分多实例
  • 接入现代化的可观测性体系,提升对故障的洞察分析能力,降低由于架构分层带来的问题诊断困难

总之,不管是架构形态怎么变、能力怎么抽象,让业务逻辑不断内聚,越来越面向接口、面向能力编程的趋势不会改变,服务化体系的未来值得期待。

Reference

  • Multi-Runtime Microservices Architecture
  • Dapr
  • 死生之地不可不察:论API标准化对Dapr的重要性
  • Layotto
  • 如何看待 Dapr、Layotto 这种多运行时架构?

最后,推荐一款应用开发神器

扯个嗓子!关于目前低代码在技术领域很活跃!

低代码是什么?一组数字技术工具平台,能基于图形化拖拽、参数化配置等更为高效的方式,实现快速构建、数据编排、连接生态、中台服务等。通过少量代码或不用代码实现数字化转型中的场景应用创新。它能缓解甚至解决庞大的市场需求与传统的开发生产力引发的供需关系矛盾问题,是数字化转型过程中降本增效趋势下的产物。

这边介绍一款好用的低代码平台——JNPF快速开发平台。近年在市场表现和产品竞争力方面表现较为突出,的是最新主流前后分离框架(SpringBoot+Mybatis-plus+Ant-Design+Vue3。代码生成器依赖性低,灵活的扩展能力,可灵活实现二次开发。

以JNPF为代表的企业级低代码平台为了支撑更高技术要求的应用开发,从数据库建模、Web API构建到页面设计,与传统软件开发几乎没有差异,只是通过低代码可视化模式,减少了构建“增删改查”功能的重复劳动,还没有了解过低代码的伙伴可以尝试了解一下。

应用:https://www.jnpfsoft.com/?csdn

有了它,开发人员在开发过程中就可以轻松上手,充分利用传统开发模式下积累的经验。所以低代码平台对于程序员来说,有着很大帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习(35)—— StarGAN(2)

深度学习&#xff08;34&#xff09;—— StarGAN&#xff08;2&#xff09; 完整项目在这里&#xff1a;欢迎造访 文章目录 深度学习&#xff08;34&#xff09;—— StarGAN&#xff08;2&#xff09;1. build model&#xff08;1&#xff09;generator&#xff08;2&#…

K8S 部署 RocketMQ

文章目录 添加模板部署本地访问 集群使用 kubesphere 作为工具 添加模板 添加 helm 模板 helm repo add rocketmq-repo https://helm-charts.itboon.top/rocketmq helm repo update rocketmq-repo编写 value.yaml 文件 配置主从节点的个数&#xff0c;例子为单节点 broker:…

使用langchain与你自己的数据对话(四):问答(question answering)

之前我已经完成了使用langchain与你自己的数据对话的前三篇博客&#xff0c;还没有阅读这三篇博客的朋友可以先阅读一下&#xff1a; 使用langchain与你自己的数据对话(一)&#xff1a;文档加载与切割使用langchain与你自己的数据对话(二)&#xff1a;向量存储与嵌入使用langc…

动画制作选择Blender还是Maya

Blender和Maya是两种最广泛使用的 3D 建模和动画应用程序。许多经验丰富的用户表示&#xff0c;Blender 在雕刻工具方面远远领先于 Maya&#xff0c;并且在 3D 建模方面达到了相同的质量水平。对于刚接触动画行业的人来说&#xff0c;您可能会问“我应该使用 Blender 还是 Maya…

Docker入门——保姆级

Docker概述 ​ —— Notes from WAX through KuangShen 准确来说&#xff0c;这是一篇学习笔记&#xff01;&#xff01;&#xff01; Docker为什么出现 一款产品&#xff1a;开发—上线 两套环境&#xff01;应用环境如何铜鼓&#xff1f; 开发 – 运维。避免“在我的电脑…

Windows测试模式打开/关闭 C++ Windows驱动开发

Windows测试模式打开 管理员身份运行CMD 2.输入&#xff1a;bcdedit /set testsigning on 重启计算机 右下角显示&#xff1a; 测试模式成功开启 Windows测试模式关闭 同理&#xff0c;第二步修改为&#xff1a; 重启后右下角&#xff1a; 没有测试模式显示&#xff0c;关闭…

学C的第三十二天【动态内存管理】

相关代码gitee自取&#xff1a;C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 学C的第三十一天【通讯录的实现】_高高的胖子的博客-CSDN博客 1 . 为什么存在动态内存分配 学到现在认识的内存开辟方式有两种&#xff1a; 创建变量&#xff1a; int val …

telnet检验网络能不能通

telnet检测网络能不能通&#xff08;ip地址端口号&#xff09;

高并发负载均衡---LVS

目录 前言 一&#xff1a;负载均衡概述 二&#xff1a;为啥负载均衡服务器这么快呢&#xff1f; ​编辑 2.1 七层应用程序慢的原因 2.2 四层负载均衡器LVS快的原因 三&#xff1a;LVS负载均衡器的三种模式 3.1 NAT模式 3.1.1 什么是NAT模式 3.1.2 NAT模式实现LVS的缺点…

SpringCloud实用篇1——eureka注册中心 Ribbon负载均衡原理 nacos注册中心

目录 1 微服务1.1 微服务的演变1.2 微服务1.3 SpringCloud1.4 小结 2 服务拆分及远程调用2.1 服务拆分2.2 服务拆分案例2.3 实现远程调用2.4 提供者与消费者 3 Eureka注册中心3.1 Eureka的结构和作用3.2 搭建eureka-server3.3 服务注册3.4 服务发现 4 Ribbon负载均衡4.1 负载均…

【Linux】多路转接 -- select函数

文章目录 1. 认识select函数2. select函数原型3. socket就绪条件4. select工作流程5. select服务器6. select的优缺点 首先我们要了解一下&#xff0c;什么是多路转接&#xff1f; 多路转接也叫多路复用&#xff0c;是一种用于管理多个IO通道的技术。它能实现同时监听和处理多个…

sk_buff操作函数学习

一. 前言 内核提供了大量实用的操作sk_buff的函数&#xff0c;在开发网络设备驱动程序和修改网络协议栈代码时需要用到。这些函数从功能上可以分为三类&#xff1a;创建&#xff0c;释放和复制socket buffer&#xff1b;操作sk_buff结构中的参数和指针&#xff1b;管理socket b…

webpack基础知识四:说说webpack中常见的Plugin?解决了什么问题?

一、是什么 Plugin&#xff08;Plug-in&#xff09;是一种计算机应用程序&#xff0c;它和主应用程序互相交互&#xff0c;以提供特定的功能 是一种遵循一定规范的应用程序接口编写出来的程序&#xff0c;只能运行在程序规定的系统下&#xff0c;因为其需要调用原纯净系统提供…

【小沐学前端】VuePress制作在线电子书、技术文档(VuePress + Markdown + node)

文章目录 1、简介1.1 VuePress简介1.2 它是如何工作的&#xff1f; 2、安装node3、安装VuePress4、配置VuePress4.1 修改标题4.2 修改导航条4.3 修改右侧栏4.4 修改正文 结语 1、简介 Vue驱动的静态网站生成器&#xff0c;生成的网页内容放到自己服务器上管理&#xff0c;可用于…

74. 搜索二维矩阵

题目链接&#xff1a;力扣 解题思路&#xff1a;因为矩阵整体上是有序的&#xff0c;所以可以先二分查找target在哪一行中&#xff0c;然后再次二分查找target在当前行的哪一列中。 具体算法如下&#xff1a; 对行使用二分查找&#xff1a; 初始值&#xff1a; int m matrix…

MongoDB SQL

Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation。保留所有权利。C:\Users\Administrator>cd C:\MongoDB\Server\3.4\binC:\MongoDB\Server\3.4\bin> C:\MongoDB\Server\3.4\bin> C:\MongoDB\Server\3.4\bin>net start MongoDB 请求的…

使用可视化docker浏览器,轻松实现分布式web自动化

01、前言 顺着docker的发展&#xff0c;很多测试的同学也已经在测试工作上使用docker作为环境基础去进行一些自动化测试&#xff0c;这篇文章主要讲述我们在docker中使用浏览器进行自动化测试如果可以实现可视化&#xff0c;同时可以对浏览器进行相关的操作。 02、开篇 首先…

【0805作业】Linux中 AB终端通过两根有名管道进行通信聊天(半双工)(全双工)

作业一&#xff1a;打开两个终端&#xff0c;要求实现AB进程对话【两根管道】 打开两个终端&#xff0c;要求实现AB进程对话 A进程先发送一句话给B进程&#xff0c;B进程接收后打印B进程再回复一句话给A进程&#xff0c;A进程接收后打印重复1.2步骤&#xff0c;当收到quit后&am…

【react】react中BrowserRouter和HashRouter的区别:

文章目录 1.底层原理不一样:2.path衣现形式不一样3.刷新后对路山state参数的影响4.备注: HashRouter可以用于解决一些路径错误相关的问题 1.底层原理不一样: BrowserRouter使用的是H5的history API&#xff0c;不兼容IE9及以下版不。 HashRouter使用的是URL的哈希值。 2.path衣…

MongoDB文档--基本安装-linux安装(mongodb环境搭建)-docker安装(挂载数据卷)-以及详细版本对比

阿丹&#xff1a; 前面了解了mongodb的一些基本概念。本节文章对安装mongodb进行讲解以及汇总。 官网教程如下&#xff1a; 安装 MongoDB - MongoDB-CN-Manual 版本特性 下面是各个版本的选择请在安装以及选择版本的时候参考一下&#xff1a; MongoDB 2.x 版本&#xff1a…