开源项目的演进会遇到哪些“坑”?KubeVela 从发起到晋级 CNCF 孵化的全程回顾

news2024/11/23 19:23:22

作者:孙健波、曾庆国

点击查看:「开源人说」第五期《KubeVela:一场向应用交付标准的冲锋》

2023 年 2 月,**KubeVela [ 1] ** 经过全体 ToC 投票成功进入 CNCF Incubation,是云原生领域首个晋级孵化的面向应用的交付和管理平台。KubeVela 背后的核心理念是 2019 年阿里云和微软联合发布的开放应用模型(OAM),演变至今,KubeVela 通过其可编程可扩展的架构、良好的用户体验,以及大量的生态核心能力,帮助了钉钉、招商银行、理想汽车、移动云、百度等数百家企业构建其云原生应用平台,大大降低了云原生技术的使用门槛。

KubeVela 本身也有别于“大厂开源”的惯性模式,它从第一天起就遵循“社区发起、开放治理、国际化运作”的原则,核心理念之一就是“始终以业界的最广泛和最真实场景作为项目演进的指南针”,所以发展路径中一直在倾听社区的声音,以最普遍、最共性的需求为最高优先级。因此,我们也有幸经历了一个项目从社区发起到用户群体壮大的全过程。从技术迭代、完善功能,到社区运营、开源治理,再到打磨产品、建立生态,我们克服了诸多困难,这或许是开源项目都会遇到的挑战。

今天,我们将做一个完整的回顾,梳理项目演进过程中的那些“坑”,希望对整个开源生态的发展有所帮助。

项目发起:明确目标和定位

一个开源项目的发起,其最核心的是明确项目的目标和定位。 OAM/KubeVela 诞生之初的 2018-2019 年,当时我们判断:随着云原生技术逐渐统一基础设施和工作负载层面的抽象,如何进一步简化和标准化应用交付与管理层面的操作和功能,会成为接下来一个非常自然的演化方向,也会成为市场的下一个焦点。这里面我们主要考虑了四个方面:

  • 受众

大多数开发者,也就是最终业务应用的开发者,他们日常关心的是应用开发和部署,而不是计算存储网络,这意味着应用层的大幅简化和标准化一定会成为强需求。

  • 定位和空间

Kubernetes 非常明确的要把它的抽象层次停留在基础设施层,这为应用层的进一步创新和工作提供了足够的空间和支撑。

  • 行业格局

在 Kubernetes 逐渐成为事实标准的背景下,大多数技术(比如 OpenShift)依然在做局限的封装,而原生的工具(如 helm、kustomize)又过于简单。这样既不满足云上用户碎片化、多样化的使用诉求,也无法打造用户友好的使用体验。

  • 技术储备

CRD Operator, Terraform 等 IaC 技术的逐步普及提供了一个快速交付可编程、模块化的应用管理抽象,而基于 Kubernetes,一个独立的应用管理和交付系统可以非常专注于该层本身,而无需关注基础设施层的问题。

基于以上趋势的判断,阿里开始在 2019 年逐步布局应用交付与管理领域,提出了一系列先导性探索和实践,包括 **Helm/Kustomzie 应用管理、多集群应用交付 [ 2] **等。最终确定将“让软件交付在当今流行的混合、多云环境中变得更加简单、高效、可靠”作为我们的核心目标和愿景,将“一个与基础设施无关的、用户友好但又灵活可扩展的应用交付抽象”作为我们的核心交付物,这个应用交付抽象就是今天的 OAM spec,而随后出现的 KubeVela 则是这一层抽象的具体实现。

在这里插入图片描述

图 1:KubeVela 是什么?

明确的目标和定位不仅支撑了 KubeVela 开源团队以及大量社区贡献者可以在相对松散的模式下长期协作,还帮助团队从大量杂乱的需求中解放出来,专注在最核心的问题域中。 比如 KubeVela 不会触及工作负载本身,用户可以选择集成 Kubernetes 原生的 Deployment,或者自己扩展 CRD Operator,又或者选择 OpenKruise 这样的工作负载管理工具。同时团队专注于项目的集成能力和扩展性,比如我们投入了足够的精力去做 Kubernetes API 的编排,任意的 Kubernetes 资源都可以在 KubeVela 体系中组合、拆分、查看状态、传递参数,这一特性使得 KubeVela 早期快速的打出了自己的市场定位,并且获得了像第四范式这样的早期用户。

早期演进:明确要坚守的核心技术原则

开源项目的早期通常是沿着最初设定的目标去补齐核心功能,在此之前我们可能需要回答一个问题:“为了让我们的开源项目与众不同,我们该遵循怎样的设计原则?

KubeVela 项目的第一个年头是核心技术功能初步形成的阶段,设计之初我们给项目定下的关键原则是:

  • Kubernetes 原生

OAM 应用模型不局限于 Kubernetes 生态,但是我们选择将 KubeVela 控制平面通过 Kubernetes 的插件(CRD)模式实现。一方面它充分利用了 Kubernetes 声明式 API 面向终态的设计理念,为用户带去易用性和确定性,方便用户安装和使用。

另一方面它也帮助我们利用 Kubernetes 的 API 生态,快速实现了诸如 Helm 交付、弹性扩缩容、服务网关、灰度发布等应用所需的核心能力,而 KubeVela 团队随后发布的 **Terraform Controller 项目 [ 3] **也证明了基于 Kubernetes 控制平面衔接云能力的可行性。

  • 可扩展

KubeVela 基于 OAM 模型提供用户友好的上层抽象,但这些抽象可以随时扩展以满足用户的各种需求。这给技术实现带来了很大的挑战,但这也是一个非常重要的创新,它避免了 KubeVela 项目成为一个只能解决“最小公分母”问题的“鸡肋”项目

  • 可编程

在众多的可扩展性设计中,KubeVela 最终选择了 Infra as Code(IaC) 的可编程扩展方式。因为这种扩展方式不仅简单易用,还可以方便的模块化和插件化。这个选择不仅提供了扩展 KubeVela 的最佳方案,还为后来的插件市场等生态能力打下了基础。

围绕着这些原则,项目选择基于 **CUE 配置语言 [ 4] **来作为动态编程能力的基石,KubeVela 1.0 及早期版本给出了一个非常灵活的 OAM 实现。但项目的演进也使得 KubeVela 及 OAM 模型与早期发布的版本形成了较为明显的差异,这里形成了一个不小的挑战,即“开源项目的兼容性如何保证”。

在这里插入图片描述

图 2:KubeVela 可编程可扩展的模块化设计?

持续迭代:保持开源项目的兼容性

KubeVela 基本上就是在 OAM 社区的众多用户呼声下诞生的,那些早期参与贡献的工程师们,他们其实也同时是公司里面积极推进 OAM 落地的平台构建者,他们不仅提供了大量的建议和代码贡献,还通过自身的实际场景帮助社区做验证。我们知道一个新技术的推广,很重要的一点是在解决原有问题的同时,尽可能降低采纳的成本,也就是不引入新的问题。 所以当 KubeVela 发布的第一个版本的时候,我们的早期采纳者他们更多的是在做一个自身 OAM 实践的升级,而不是使用一个全新的系统。同样地,在后续的项目迭代过程中,对兼容性的考量一直都放在首要的位置。

当 KubeVela 项目的第一阶段功能实现完成,并被开源社区逐步采用的过程中。根据大量的用户反馈和调研,我们发现,除了基础的工作负载和运维需求之外,用户还会有诸如多集群高可用、资源共享、资源回收等应用管理策略的需求,而看似非常碎片化和复杂的各类应用交付场景,其背后确实存在一个非常本质的模型,那就是“工作流”。我们很快就开始同时演进 OAM 模型本身,并且在 KubeVela 实现了一个非常轻量级的工作流引擎。而“工作流”这个特性本身就又与 Kubernetes 和 GitOps 生态天然互补,KubeVela 的工作流步骤可以任意扩展,而声明式 API 面向终态的语义也可以很好的描述工作流的状态机,这使得 KubeVela 的工作流几乎可以满足任何交付场景的需要,所以这个创新后来也成为了 KubeVela 被大量采用的“杀手锏”。

在这里插入图片描述

图 3:KubeVela 1.0 发布后始终保持功能以及模型层面的兼容性

当然这也会为技术方案的长期演进带来很多包袱和困难,所以我们在随后也加入了项目功能的废弃机制,仅对少量不合理、且几乎没有用户的功能做废弃,并且在正式废弃前提前两个版本做通知。核心能力形成的过程中,我们观察到用户增长并不满足预期。通过运营分析,我们发现无论是 Github 还是官网,初次访问流量是比较大的,但实际转化数据不太理想。此时我们意识到项目的使用体验可能不尽如人意,而社区用户的使用和反馈是驱动我们项目持续增长的重要输入。

用户转化:注重易用性和首次体验

KubeVela 的理念是业界领先的,所以我们一直在做大量布道,许多用户被我们吸引过来。然而许多用户反馈说,看了 KubeVela 项目官网,看不懂这个项目是做什么的。此时我们意识到,项目的易用性出了问题。我们把自己从项目维护者的身份中走出来,开始作为用户审视这个项目,对于首次接触项目的新用户,我们问自己三个问题:

  • 第一个问题:我能一下子看明白项目解决的是什么问题吗?

KubeVela 项目本身是有一定的理解门槛的,它建立在 OAM 应用模型之上,OAM 模型关注点分离的核心思路又把平台的用户分成了平台的构建者和最终用户,这给直接接触 KubeVela 的用户带来了不小的认知成本。在 1.0 到 1.5 这接近一年的时间中,我们每次发版都会根据用户的反馈持续重构我们官网的文档,以广大用户最能产生共鸣的关键词、场景进行类比,同时也一直在做减法,将项目的高级功能藏到相对较深的位置。

另一方面,我们在产品实现上也持续明确目标用户群体,将 KubeVela 控制器核心定位给平台工程师,而开发的 VelaUX 子项目初始定位是业务开发者开箱即用,同时也为平台工程师构造企业平台提供参考和基础框架。通过明确定位的产品培养用户心智,进而将越来越多关键信息传播给社区用户,再通过用户社群持续影响更广泛的生态。

  • 第二个问题:我能一下子联想到我的场景是否能够用它吗,或者它能满足我的需求吗?

用户的注意力是有限的,通过对官网的用户访问数据进行分析,我们发现新用户在网站的平均驻留时间不超过 3 分钟,如何在有限的时间里迅速抓住目标用户的兴趣,文档结构的设计非常重要。通过对社区用户的大量访谈,我们意识到大多数用户会带着需求关键词来寻觅项目,所以们不断调整官网侧边栏目录,把项目能够实现的核心功能以用户熟悉的关键词体现到导航目录中方便用户快速匹配。

除了项目文档,另一个关键点是提炼用户案例,行业头部用户案例具备很强的带动作用。有一段时间理想汽车率先采纳了 KubeVela,没多久就看到了小鹏汽车的采纳,甚至在不久前,自动驾驶领域的巨头 Aurora 也在 Slack 上联系我们,计划全公司采纳 KubeVela,而招商银行的案例也带动了一大批金融行业的用户采纳 KubeVela。当然这些案例的积累是一个小火慢炖的过程,很难一蹴而就。 这不仅需要项目的维护者对于社区用户有足够的耐心,也需要站在开源项目背后支撑项目发展的公司有足够的远见, 我们非常感谢阿里云、招商银行、Napptive等公司的维护者们持续而坚定的投入。

  • 第三个问题:我想试一下项目的实际运行效果,我能在几分钟只能快速体验完整的 Demo 吗?

这个问题其实涉及到了开源项目的一个关键特点,那就是开源项目必须能够用户自助,即用户要有能力自发的安装、使用、运维,以及在社群进行传播。如果一个开源项目是大多数用户自己玩不起来的,那注定难以成功。所以我们在每次发版时都会检查以下两项:

  1. 大多数用户能否顺畅进行安装?对于国际化运作的 KubeVela 项目来说,我们需要帮助用户客服网络障碍,不管是访问文档还是下载安装都需要在国内外流畅进行;为了降低安装复杂度,我们甚至专门发起了一个叫 **VelaD [ 5] **的项目,帮助用户从单机一键离线拉起包括 Kubernetes 在内的完整体验环境,大大降低了用户的上手门槛。除此之外,还有包括 ARM 架构镜像支持、版本升级一键完成等体验优化。

  2. 第一个用例是否足够简单又充分说明项目特性?KubeVela 早期的第一个用例要么过于简单看不出功能特点,要么过于复杂没有多个集群都跑不起来。经过持续打磨,现在的第一个用例围绕着核心概念,体现了工作负载抽象、交付策略、多集群、工作流等核心能力,但对用户环境又无额外要求。

在这里插入图片描述

图 4:VelaD 全离线一键安装包括 Kubernetes 集群在内的完整环境

逐步成熟:产品化运作和社区用户

随着项目的逐步成熟,社区会迎来一批又一批的用户,而开源项目成功的核心就是大量的用户采纳。KubeVela 很幸运,一直有阿里巴巴内部大量的场景可以帮助打磨孵化,而我们也非常注重社区用户的需求。除了每周定期举办国内外社区会议,还会组织跟不同企业的点对点交流会,甚至帮助他们制定完整的平台架构。而这个过程的积累也是相互的,KubeVela 维护团队从各行各业的头部企业中了解了行业的现状和差异化痛点,得以从更广阔的视野做功能的设计。

在社区用户的过程中,我们也总结了一些关键经验:

  1. 如何给到开源用户安全感? 对于基础设施类的开源项目,一旦采纳就会成为企业内部核心架构的一部分,相比于企业内部自建,采纳开源往往会缺乏一些安全感,开源项目本身如何给到企业安全感至关重要。首先是项目维护团队的多样化、长期稳定性以及高活跃,KubeVela 是 CNCF 托管的孵化项目,背后有阿里云、招商银行、Napptive 等多个公司在持续维护。同时要持续对代码质量保持较高的要求、注重安全问题和稳定性,KubeVela 有 40 多项持续集成测试条目,总体测试覆盖率超过 60%,核心场景的覆盖率在 90% 以上,基本上每个合并的代码都能保证兼容性,同时对代码贡献者本身的能力也有较高的要求。而团队对安全问题的上报和稳定性问题也始终保持高度敏感,一旦发现会第一时间发布修复版本。最后是提供确定性,有明确的里程碑、发版计划 ,并且坚定的执行。 KubeVela 发布至今每隔 2-3 个月发布一次大版本,每隔 1-2 周发布一个小版本,社区一直保持极高的活跃度,至今已经发布了超过 150 个版本,每个版本都有清晰的变更文档。

  2. 如何平衡社区用户的小众需求? 社区用户在落地过程中由于场景的差异,必然会产生相对小众的需求。对于这一点,我们的策略是 Blocker Issue 优先,即如果由于一些功能设定和实现直接阻碍了场景落地,那么这类问题要第一时间解决。对于功能新增类的需求,则交由社区一同评估等待更多的反馈,确认是一个相对普遍的需求再加入到版本计划中。例如 KubeVela 早期有一些用户希望对接他们企业内部的统一认证平台,这可能并不是标准的协议模式,通过社区 Issue 的来会讨论,有贡献者指出采用了 Dex 作为企业单点登录的统一方式,不同企业自行对接 Dex 即可。这使得项目能够群策群力,着眼于长远发展。

3. 如何获得海外用户? 基础设施领域的开源项目,要想获得真正意义上的成功,如何打开国际化市场是一个绕不开的话题。一方面,项目本身要始终着眼于领域的最前沿,保持技术的先进性,聆听国外用户的使用场景和习惯,对技术发展趋势做出敏锐的判断。另一方面,KubeVela 的核心团队均在国内,也克服了包括时差、语言、文化在内的诸多客观困难,一直坚持在北美相对合适的时间召开社区会议,持续在 KubeCon 等各类海外大会布道,文档、文章始终用中英文双语发布,同时积极活跃在 Slack、Issue 中答疑,满足国外用户希望点对点沟通交流的诉求。这不仅需要项目维护者有较强的综合实力,也需要对项目真正的热爱。 团队也在积极培养海外贡献者,随着 KubeVela 生态的不断繁荣,Napptive、Guidewire 等企业合作伙伴也在陆续加入社区,共同承担项目维护的职责。

在这里插入图片描述

图 5:OAM/KubeVela 风雨无阻的国外社区会议

生态建设与社区运营

最后我们要谈一谈社区生态,因为做好一个开源项目绝不仅仅是做一项前沿的技术,它更像是在目标领域打造一款好的产品。除了打磨产品功能,我们还需要通过对项目持续运营、对社区治理,得到更多开发者的认可,让他们参与进来贡献。要实现这样的目标,就需要让开发者对 KubeVela 形成共识、主动加入并参与协作。

KubeVela 诞生于 OAM 社区,也是第一个将“以应用为中心”的设计理念落地的项目。因此早期,我们首先要让大家理解 OAM 模型的思想,大家才会有意愿开始了解 KubeVela 是什么。我们做了大量的布道,并联合 CNCF 发布业界首个“云原生技术公开课”,介绍 OAM“以应用为中心”的理念如何解决云原生时代应用开发问题,得到了越来越多开发者的共鸣。发展到 2021 年 5 月,阿里云联合信通院发布业内首个以 OAM 为核心的“云计算开放架构”标准,将 OAM “模型”化虚为实,也对 KubeVela 发展起到关键作用。

为使社区保持持续的生命力,2021 年 7 月,KubeVela 正式加入 CNCF ,项目受众也扩大至全球。我们投入了很多精力做海外运营,比如联动 CNCF TAG App Delivery,以及 Argo、FluxCD、Prometheus、K3s 等生态伙伴举办社区会议、在主流的海外开发者社区建立团队账号,渐渐将影响力渗透到北美、日本、西班牙、英国等多个国家。为了让周边生态繁荣起来,以便能够让项目在更大的领域得到广泛的传播,为此我们专门建立了一个插件(Addon)体系,方便社区里的开发者可以将生态项目的集成,方便地制作成一个具备版本、统一仓库、可发现、可分发、一键安装的插件包。

在这里插入图片描述

图 6:KubeVela 的插件生态

KubeVela 的技术很先进,社区的贡献者众多,但水平也有差异,为了保证项目的质量,又不打击贡献者的积极性。对于每一个代码提交,我们都会及时响应、充分交流,给予贡献者足够的尊重和耐心。同时我们会积极的补充开发者文档,将开发者遇到的常见问题体系化整理。另一方面,我们也建立了完善的开发者晋级机制,从组织的 member,到 reviewer、approver 最后到 maintainer,都有明确的达成条件,让开发者像打怪升级一样有成就感。

如今 KubeVela 贡献者已经遍布全球,所在的企业和组织超过70个。我们倡导的理念是,开源贡献的形式不只是代码,一次分享、一次解答,都是对项目的贡献。我们也在建立并逐步完善社区晋升模型和协作机制,让大家更规范、高效地参与社区。KubeVela 社区依然非常年轻,还有很多事情在逐步完善,很开心有这么多朋友同行,让这个队伍越来越壮大。也期待更多朋友来到 KubeVela 社区感受开源的魅力。

相关链接

[1] KubeVela

https://kubevela.net/

[2] Helm/Kustomzie 应用管理、多集群应用交付

https://www.infoq.cn/article/sbwSX8ypxgID2-SB723K

[3] Terraform Controller 项目

https://github.com/kubevela/terraform-controller

[4] CUE 配置语言

https://cuelang.org/

[5] VelaD

https://github.com/kubevela/velad

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

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

相关文章

35岁测试人该何去何从?10年工作经验的我,只不过是一年的工作经验用了10年......

如果到了这个年龄,还是初级测试,或者只会一些简单的自动化测试,那么真的是不好干了。 35的年龄,企业对员工是有另一层面的考量。 简单来说,就是年龄上去了,能力也要上去,要么是技术专家&#…

复习 Kotlin 从小白到大牛 第二版 笔记要点

4.2.2 常量和只读变量 常量和只读变量一旦初始化就不能再被修改。在kotlin中,声明常量是在标识符的前面加上val或const val 关键字。 1. val 声明的是运行时变量,在运行时进行初始化 2.const val 声明的是编译时常量,在编译时初始化 val …

【springmvc】10.拦截器

拦截器 1、拦截器的配置 SpringMVC中的拦截器用于拦截控制器方法的执行 SpringMVC中的拦截器需要实现HandlerInterceptor Component public class FirstInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, …

mysql5.7.33安装配置教程【保姆级安装教程】

MySQL5.7.33安装教程 1、官方网站下载 点击这里跳转页面下载 1.1、看下你是什么系统,系统是64位还是32位 2、解压到D盘跟路径或者其下面纯英文路径 2.1、可见它没有data、log等文件夹,不需手动添加(下面执行命令自动初始化)!! …

如何安装python

windows安装 下载安装包 登录python官网 https://www.python.org/ 点击downloads 置顶下载的是最新的python版本 如果想下载指定版本往下翻找 安装程序 点击即可下载,然后打开下载的exe程序 勾选添加pythonexec到path,也就是添加到环境变量 使用a…

Vue2.0开发之——购物车案例-Footer组件封装-计算商品的总价格(51)

一 概述 App.vue中计算勾选商品的总价格定义子组件Footer中的商品总价格将App.vue中商品的总价格传递给Footer显示 二 App.vue中计算勾选商品的总价格 2.1 商品总价格的计算逻辑 所有勾选商品的价格*数量 2.2 App.vue中通过计算属性计算总价格 通过计算属性计算总价格 co…

esp8266WiFi模块通过MQTT连接华为云

esp8266WiFi模块通过MQTT连接华为云总结:一、 MQTT透传AT固件烧录二、 串口调试2.1 设置模块为STA模式2.2 连接WiFi2.3 设置MQTT的登陆用户名与密码2.4 设置MQTT的ClientID2.5 设置MQTT接入地址2.6 订阅设备属性上报的主题2.7 上传数据2.8 平台下发命令2.9 华为云物…

网络编程学习笔记(1)--TCP/IP协议基础

目录 全称 定义 分层结构 端到端的数据传输 ​编辑 举个栗子——浏览网页 应用层 传输层 TCP UDP 网络层 IP协议 特点 IP地址 网络掩码 ARP协议 PARP协议 ICMP协议 数据链路层 名词解释 数据段 数据报 数据包 数据帧 比特流 全称 Transmission Contro…

关于进制的转换

将n进制转化为m进制一般,我们是通过位值定理来将n进制转化为10进制;然后对整数进行辗转相除来得到m进制整数void find(int x){//integer; w0;while(sum>0){ //先除为低; t[w]q[sum%m];w;sum/m;}markw; }for(int ik-1,j0;i>0;i--,j){//i…

Linux操作系统学习(线程基础)

文章目录线程的基础概念线程控制内核LWP和线程ID的关系线程的基础概念 ​ 一般教材对线程描述是:是在进程内部运行的一个分支(执行流),属于进程的一部分,粒度要比进程更加细和轻量化 ​ 一个进程中是可能存在多个线程…

【Java|golang】1653. 使字符串平衡的最少删除次数---动态规划

给你一个字符串 s &#xff0c;它仅包含字符 ‘a’ 和 b’​​​​ 。 你可以删除 s 中任意数目的字符&#xff0c;使得 s 平衡 。当不存在下标对 (i,j) 满足 i < j &#xff0c;且 s[i] ‘b’ 的同时 s[j] ‘a’ &#xff0c;此时认为 s 是 平衡 的。 请你返回使 s 平衡…

亚马逊、速卖通、lazada店铺一直不出单,没流量怎么办?

近几年&#xff0c;跨境电商入驻的卖家越来越多&#xff0c;平台的流量越来越分散&#xff0c;导致店铺没有流量没有订单的情况经常发生&#xff0c;因此卖家对店铺的优化尤为主要。 对于亚马逊卖家来说&#xff0c;几乎每天都会问虽然我把我的产品放在货架上&#xff0c;但没…

4N60-ASEMI高压MOS管4N60

编辑-Z 4N60在TO-220封装里的静态漏极源导通电阻&#xff08;RDS(ON)&#xff09;为2.5Ω&#xff0c;是一款N沟道高压MOS管。4N60的最大脉冲正向电流ISM为16A&#xff0c;零栅极电压漏极电流(IDSS)为1uA&#xff0c;其工作时耐温度范围为-55~150摄氏度。4N60功耗&#xff08;…

Vue基础17之配置代理

Vue基础17配置代理使用node启动两台服务器server1.jsserver2.js使用axios发送ajax请求安装axios库引入axios库发送axios请求App.vue跨域问题解决代理服务器开启&#xff1a;方式一代理服务器开启&#xff1a;方式二server1.jsserver2.jsvue.config.jsApp.vue总结&#xff1a;Vu…

面向对象设计模式:结构型模式之代理模式

一、引入 访问 FB&#xff1a;代理服务器 二、代理模式 aka Surrogate 2.1 Intent 意图 Provide a surrogate (代理) or placeholder for another object to control access to it. 为另一个对象提供一个代理或占位符&#xff0c;以控制对它的访问。代理模式给某一个对象提…

2023年如何在Google做外贸

2023年如何在Google做外贸 答案是&#xff1a;利用谷歌SEO获取自然流量促进成交。 随着全球化和数字化的发展&#xff0c;外贸行业越来越重视互联网的渠道拓展。 在Google搜索引擎上做好SEO优化&#xff0c;是吸引国际客户和提高品牌知名度的关键。 本文将探讨2023年如何在…

【容器运行时】一文理解 OCI、runc、containerd、docker、shim进程、cri、kubelet 之间的关系

参考 docker&#xff0c;containerd&#xff0c;runc&#xff0c;docker-shim 之间的关系Containerd shim 进程 PPID 之谜内核大神教你从 Linux 进程的角度看 DockerRunC 简介OCI和runCContainerd 简介从 docker 到 runCDockershim究竟是什么技术干货&#xff5c;Docker和 Con…

C# 中的abstract和virtual

重新理解了下关键字abstract,做出以下总结&#xff1a; 1.标记为abstract的类不能实例化&#xff0c;但是依然可以有构造函数&#xff0c;也可以重载构造函数&#xff0c;在子类中调用 2.abstract类中可以有abstract标记的方法和属性&#xff0c;也可以没有&#xff0c;被标记…

Linux网络编程学习(网络基础)

文章目录网络基础浅谈计算机网络背景了解协议网络传输基本流程局域网传输基本流程跨网络的数据传输流程网络基础 浅谈计算机网络背景 ​ 计算机最早是没有网络的&#xff0c;当时想要数据之间交互就需要人来传递&#xff0c;但是这样效率非常低&#xff0c;而且也容易出错&am…

机器人姿态规划的三种常见方法:欧拉角、角轴和四元数

参考文献&#xff1a; 1. 布鲁诺西西里安诺等[意] 《机器人学&#xff1a;建模、规划与控制》 2. 四元数小总结 - 孤独の巡礼 - 博客园 (cnblogs.com) 3. 基于单位四元数的姿态插补&#xff08;Matlab&#xff09; - 知乎 (zhihu.com) 4. 基于四元数的工业机器人姿态规划与插…