「开源人说」| 开源项目的演进会遇到哪些“坑”?KubeVela 从发起到晋级 CNCF 孵化的全程回顾
2023 年 2 月,KubeVela[1] 经过全体 ToC 投票成功进入 CNCF Incubation,是云原生领域首个晋级孵化的面向应用的交付和管理平台。KubeVela 背后的核心理念是 2019 年阿里云和微软联合发布的开放应用模型(OAM),演变至今,KubeVela 通过其可编程可扩展的架构、良好的用户体验,以及大量的生态核心能力,帮助了钉钉、招商银行、理想汽车、移动云、百度等数百家企业构建其云原生应用平台,大大降低了云原生技术的使用门槛。KubeVela 本身也有别于“大厂开源”的惯性模式,它从第一天起就遵循“社区发起、开放治理、国际化运作”的原则,核心理念之一就是“始终以业界的最广泛和最真实场景作为项目演进的指南针”,所以发展路径中一直在倾听社区的声音,以最普遍、最共性的需求为最高优先级。因此,我们也有幸经历了一个项目从社区发起到用户群体壮大的全过程。从技术迭代、完善功能,到社区运营、开源治理,再到打磨产品、建立生态,我们克服了诸多困难,这或许是开源项目都会遇到的挑战。今天,我们将做一个完整的回顾,梳理项目演进过程中的那些“坑”,希望对整个开源生态的发展有所帮助。01项目发起:明确目标和定位一个开源项目的发起,其最核心的是明确项目的目标和定位。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 早期快速的打出了自己的市场定位,并且获得了像第四范式这样的早期用户。02早期演进:明确要坚守的核心技术原则开源项目的早期通常是沿着最初设定的目标去补齐核心功能,在此之前我们可能需要回答一个问题:“为了让我们的开源项目与众不同,我们该遵循怎样的设计原则?” 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 可编程可扩展的模块化设计?03持续迭代:保持开源项目的兼容性KubeVela 基本上就是在 OAM 社区的众多用户呼声下诞生的,那些早期参与贡献的工程师们,他们其实也同时是公司里面积极推进 OAM 落地的平台构建者,他们不仅提供了大量的建议和代码贡献,还通过自身的实际场景帮助社区做验证。我们知道一个新技术的推广,很重要的一点是在解决原有问题的同时,尽可能降低采纳的成本,也就是不引入新的问题。所以当 KubeVela 发布的第一个版本的时候,我们的早期采纳者他们更多的是在做一个自身 OAM 实践的升级,而不是使用一个全新的系统。同样地,在后续的项目迭代过程中,对兼容性的考量一直都放在首要的位置。当 KubeVela 项目的第一阶段功能实现完成,并被开源社区逐步采用的过程中。根据大量的用户反馈和调研,我们发现,除了基础的工作负载和运维需求之外,用户还会有诸如多集群高可用、资源共享、资源回收等应用管理策略的需求,而看似非常碎片化和复杂的各类应用交付场景,其背后确实存在一个非常本质的模型,那就是“工作流”。我们很快就开始同时演进 OAM 模型本身,并且在 KubeVela 实现了一个非常轻量级的工作流引擎。而“工作流”这个特性本身就又与 Kubernetes 和 GitOps 生态天然互补,KubeVela 的工作流步骤可以任意扩展,而声明式 API 面向终态的语义也可以很好的描述工作流的状态机,这使得 KubeVela 的工作流几乎可以满足任何交付场景的需要,所以这个创新后来也成为了 KubeVela 被大量采用的“杀手锏”。图 3:KubeVela 1.0 发布后始终保持功能以及模型层面的兼容性当然这也会为技术方案的长期演进带来很多包袱和困难,所以我们在随后也加入了项目功能的废弃机制,仅对少量不合理、且几乎没有用户的功能做废弃,并且在正式废弃前提前两个版本做通知。核心能力形成的过程中,我们观察到用户增长并不满足预期。通过运营分析,我们发现无论是 Github 还是官网,初次访问流量是比较大的,但实际转化数据不太理想。此时我们意识到项目的使用体验可能不尽如人意,而社区用户的使用和反馈是驱动我们项目持续增长的重要输入。04用户转化:注重易用性和首次体验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 集群在内的完整环境05逐步成熟:产品化运作和社区用户随着项目的逐步成熟,社区会迎来一批又一批的用户,而开源项目成功的核心就是大量的用户采纳。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 风雨无阻的国外社区会议06生态建设与社区运营最后我们要谈一谈社区生态,因为做好一个开源项目绝不仅仅是做一项前沿的技术,它更像是在目标领域打造一款好的产品。除了打磨产品功能,我们还需要通过对项目持续运营、对社区治理,得到更多开发者的认可,让他们参与进来贡献。要实现这样的目标,就需要让开发者对 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 社区感受开源的魅力。您可以通过如下材料了解更多关于 KubeVela 以及 OAM 项目的细节:项目代码库:https://github.com/kubevela/kubevela 欢迎 Star/Watch/Fork!项目官方主页与文档:kubevela.io从 1.1 版本开始,已提供中文、英文文档,更多语言文档欢迎开发者进行翻译。项目钉钉群:23310022;Slack:CNCF #kubevela Channel加入微信群:请先添加以下 maintainer 微信号,表明进入KubeVela用户群:相关链接[1] KubeVelahttps://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] VelaDhttps://github.com/kubevela/velad作者:孙健波、曾庆国
「开源人说」第五期 | KubeVela:一场向应用交付标准的“冲锋”
01云原生下的开源标准化演进 回顾信息产业几十年的发展历史,整个行业存量的数千万台服务器,在集群管理、资源切分供给、资源调度、任务编排、应用交付、应用运维等领域,一直没有形成标准和规范。几年前一份行业调研显示,全球服务器平均资源利用率不超过10%,这里面存在巨大的社会资源浪费,也存在巨大的优化空间。 云计算的发展使这些问题变得可以解决了。基础设施逐渐向云上迁移的过程中,催生了容器和 Kubernetes 的迅速流行,也为上述领域构建统一的标准,不同云厂商间 IaaS 的差异性被屏蔽,使用户在所有云环境中可以灵活使用资源,并且可以无缝的迁移和维护应用。 云原生的理念也因此得到快速普及。企业将越来越多的工作负载都迁移到 Kubernetes 之上,包括有状态或无状态的,比如微服务、大数据、AI、数据库、中间件等等。为了管理和运维这些应用,开发者不得不面对大量的底层API,这形成了两个挑战。一方面,应用交付和管理标准的缺失,使各种工作负载都会形成自己的运维和管理平台,带来企业平台层的分化。另一方面,Kubernetes 对于业务开发者而言过于复杂,带来了很高的使用门槛和稳定性风险。 在 Kubernetes 和云原生技术对基础设施和工作负载层面的抽象逐渐统一的态势下,如何进一步简化和标准化应用交付与管理层面的操作和功能,成为接下来一个非常自然但重要的演化方向,也会成为市场真正需要角逐的战场。2019年阿里云与微软联合发布OAM 2018年前后,阿里云云原生团队和微软同时看到了这个方向,在一次于阿里硅谷中心的深度交流和头脑风暴后,双方当即决定联合起来,共同孵化这个应用交付与管理体系,并于 2019 年联合发布了应用标准化模型OAM(Open Application Model),为云原生生态的应用平台建设提供理论依据。 02KubeVela:一场向应用交付标准的冲锋 OAM 的开源引发了业界不小的震动,不少企业都在进行积极的推广验证,这其中当然包括阿里的多个产品线。然而一段时间之后,阿里云云原生团队意识到要真正解决用户的问题,只靠模型还远远不够。 由于没有具体的实现方案,仅遵循 OAM 模型的思想,仍会使系统之间形成巨大差异,特别是在规模较大的场景下。比如阿里内部就形成了多套实现,能力无法复用,应用间也不能互通。而在社区的推进过程中,得到的更多反馈是 OAM 模型没有实现,很难落地使用。因此云原生团队下决心要把 OAM 的实现做出来,并且是以开源的方式去做,这也是来自社区的呼声。 KubeVela 开源团队在沟通技术实现细节 KubeVela 就此诞生。 一、新技术要解决原有问题,而不是带来新的问题 KubeVela 诞生于 OAM 社区,也是第一个将“以应用为中心”的设计理念落地的项目。发展到 2021 年 5 月,阿里云联合信通院发布业内首个以 OAM 为核心的“云计算开放架构”标准,将 OAM“模型”化虚为实,也对 KubeVela 后来的发展起到关键作用,推动其成为一个真正意义上的跨云应用交付与管理平台。 凭借过去做云产品的经验积累,KubeVela 团队深知一个新技术想要顺利推广,很重要的一点是在解决原有问题的同时,尽可能降低用户采纳的成本。社区对之前的实践和功能做了充分兼容。当 KubeVela 发布第一个正式版本的时候,用户做的操作更像是升级而不是使用一个全新的系统。 为了保证社区后续的演进不偏离这个路线,在设计之初 KubeVela 创始团队就定下了一些核心原则,指导整个 KubeVela 开源社区的长期发展。 1、兼顾用户友好和可扩展性 KubeVela 基于 OAM 模型提供用户友好的上层抽象,但这些抽象可以随时扩展以满足用户的各种需求。这就避免了 KubeVela 项目成为了一个只能解决“最小公分母”问题的“鸡肋”项目。这是一个非常重要的创新。 2、可编程而在众多的可扩展性设计中,KubeVela 最终选择了 Infra as Code 的可编程扩展方式。因为这种扩展方式不仅简单易用,还可以方便的模块化和插件化。这个选择不仅提供了扩展 KubeVela 的最佳方案,还为后来的插件市场等生态能力打下了基础。 3、以工作流为核心的交付模型 在 KubeVela 被开源社区逐步采用的过程中,根据大量的用户反馈和调研显示,看似非常碎片化和复杂的各类应用交付与管理场景,其背后确实有一个非常本质的基础模型存在的。这个基础模型就是“工作流”,所以在 KubeVela 创立后,团队很快就开始同时演进 OAM 模型本身,引入了“工作流”这个基础模型并且在 KubeVela 实现了一个非常轻量级的工作流引擎。而“工作流”这个特性本身就又与 Kubernetes 和 GitOps 生态天然互补,所以这个关键创新很快就成为了 KubeVela 被大量采用的“杀手锏”。 4、以业界最广泛和最真实的场景作为项目演进指南针 KubeVela 的发展过程中,大量关键的设计比如对交付 Helm 组件的完善支持、基于 GitOps 的核心交付流程、以多集群/多云/混合云环境作为首要交付目标等,都是结合阿里内部大规模实践,同大量的开源社区用户一起打磨、设计、然后最终实现出来的。这也是为什么很多人评价 KubeVela 是一个非常接地气的项目。这种基于阿里最佳实践但又紧贴业界最广泛场景的演进方式,对于 KubeVela 项目的广泛采用,做出了至关重要的贡献。 云原生时代的工具和技术百花齐放,对于企业来说,如何将这些丰富的技术快速落地为我所用,是一个很大的挑战。KubeVela的价值就在这里。如果做一个类比的话,它有点像云原生生态的 “Spring 框架”。在 Java 生态中,开发者可以通过Spring 快速构建业务应用,使用一致的编程模型、不需要了解各类技术框架的细节,从而能够大幅降低技术门槛。 相对应的,KubeVela 是将云原生技术组件和企业应用连接起来,建立管理和运维交付的标准,让开发者对云原生的关注点从 Kubernetes 向应用平台升级。 二、更多的功能和更低的门槛,怎么选? OAM 先进的理念、社区的用户基础加之阿里内部大规模的实践检验,使 KubeVela 初期的发展非常顺利,正式发布的第一周就冲上了 GitHub 的 Go 语言项目的趋势榜榜首。 同时,它也不可避免地遇到了刚起步的开源项目都可能遇到的问题。 首先,开源项目要成功的一大关键就是用户初始体验,而早期团队一般会更注重产品能力研发。KubeVela 本身的灵活性和可扩展性强大,这就导致第一个用例要么过于简单无法突出特色,要么过于复杂跑不起来。为了解决这些问题,团队开始重视安装复杂度、第一个用例的设计,文档结构的设计等等。直到现在,社区也一直在不断完善相关工具和文档,让初始用户可以低门槛体验项目。 第二, 可扩展性是 KubeVela与生俱来的核心设计。刚开始的时候,KubeVela 的扩展点众多,但是没有一个统一的概念,没有对应的工具链,几乎没有社区开发者能够知道如何进行扩展。因此,社区提出 Addon 的产品概念,将扩展能力以相对规范的形式进行开发、整合。投入开发者重点维护全链路工具,打通 Addon 的开发、存储、分发、升级机制。目前 Addon 的产品概念已成为 KubeVela 的特色之一。 第三,随着项目面临的场景越来越多、功能越来越丰富,KubeVela不可避免地会遇到复杂性挑战。2021年下半年,KubeVela 迎来v1.1版本,加入多集群管理的能力,同时也具备了通过工作流驱动整个交付过程的能力,这些都大大提升了KubeVela 整个项目的可扩展性,但是也加剧了用户使用的门槛。也是在这时,KubeVela 团队意识到,项目的用户群体需要分层:下层是PaaS的构建者和运维,基于 KubeVela 的引擎能力去构建 PaaS ,他们需要充分的灵活性和扩展性去适配企业内的不同场景;而上层是业务的开发者,相对来说他们更需要一个简单易用的平台,快速足业务开发需求。于是,社区开启了一个新的项目 VelaUX , 以插件化的方式集成到 KubeVela 内核上,使用户可以通过点击一个插件实现安装一个直接开箱即用的平台。 VelaUX 的出现也将 KubeVela 从以 Kubernetes 为主的技术性高扩展性项目实现向平台化高扩展性项目的跃迁。 三、热爱,就是一种竞争力 相比于那些已经在公司内孵化好再开源的项目,KubeVela 是特殊的。它从第一天起就在社区发起、在社区演进,甚至 KubeVela 这个名字也是由早期成员投票产生的。KubeVela 的初创团队邀请了许多 OAM 早期采纳公司的工程师一起来合作开发,保证项目核心部分的代码质量和稳定性。剩下的许多模块设计也都是在社区群策群力下完成的,比如官网的 UI 设计、命令行功能的使用方法、对于云资源支持的优先级等等,确保 KubeVela 许多用户体验方面的设计都建立在满足社区最广泛需求的基础之上,也保证了 KubeVela 项目贴近开发者的初心。 KubeVela 发展初期,团队成员每天打开 Github 页面都能看到大家给出的使用反馈、建议、以及代码贡献,这给了初创团队很深的感触和鼓舞。工程师在贡献开源的时候,其实都是在做自己喜欢的事情。如果一个人一直在做自己喜欢的事情,这本身就是一种强大的竞争力。KubeVela 社区也通过构建包容、开放、专业的协作环境,鼓励大家参与到开源建设中来,肯定每个人的工作,尊重每个人的价值。 从诞生之初, KubeVela 就是按照面向全球的开源项目去运作的。为使社区保持持续的生命力,2021 年 7 月,阿里云将 KubeVela 捐赠给 CNCF ,渐渐将影响力渗透到北美、日本、西班牙、英国等多个国家。如今,KubeVela 贡献者已经遍布全球,所在的企业和组织超过70个。不久前,KubeVela 正式晋升为 CNCF Incubation 项目,证明项目的影响力和成熟度得到业界认可。 KubeVela 社区的贡献者们 今天,企业对 KubeVela 的采纳程度正在快速提升。在阿里云内部,KubeVela 已经陆续成为SAE、ACK One、EDAS、云效、CDN 等多款产品的 PaaS 内核;在社区中,招商银行、第四范式、中国电子、Napptive 等大量国内外公司也正在企业的平台工程中展开 KubeVela 的落地实践。 03让平台化、标准化的理念生根发芽 在最近 Gartner 发布的“2023年十大重要技术趋势”中,“平台工程”(Platform Engineering)这一项和 KubeVela 的定位不谋而合。KubeVela 正在成为平台工程的最佳范式。记得一次社区例会上,社区的一位企业用户代表在分享他们的实践方案时说了这样一段话:“通过使用 KubeVela,目前在我们的团队,产品、后端、前端甚至是交付同事之前的沟通语言由原来的 Kubernetes 技术概念完全变更成了 OAM 的标准化概念,我们不再需要向具有不同技术背景的同事去解释技术,特别是Kubernetes 复杂生态的技术。平台化、标准化理念正在公司生根发芽。” 云原生技术的普及催生了全新的应用开发方式,其带来的技术水位的持续上移,将会把应用的交付和管理带向成熟和统一。也许这条路还很长,但我们相信,在这场面向应用交付标准的冲锋中,KubeVela 的贡献势必会留下浓墨重彩的一笔。
使用 DataAnnotations(数据注解)实现模型的通用数据校验
参数校验的意义在实际项目开发中,无论任何方式、任何规模的开发模式,项目中都离不开对接入数据模型参数的合法性校验,目前普片的开发模式基本是前后端分离,当用户在前端页面中输入一些表单数据时,点击提交按钮,触发请求目标服务器的一系列后续操作,在这中间的执行过程中(标准做法推荐)无论是前端代码部分,还是服务端代码部分都应该有针对用户输入数据的合法性校验,典型做法如下:前端部分:当用户在页面输入表单数据时,前端监听页面表单事件触发相应的数据合法性校验规则,当数据非法时,合理的提示用户数据错误,只有当所有表单数据都校验通过后,才继续提交数据给目标后端对应的接口;后端部分:当前端数据合法校验通过后,向目标服务器提交表单数据时,服务端接收到相应的提交数据,在入口源头出就应该触发相关的合法性校验规则,当数据都校验通过后,继续执行后续的相关业务逻辑处理,反之则响应相关非法数据的提示信息;特别说明:在实际的项目中,无论前端部分还是服务端部分,参数的校验都是很有必要性的。无效的参数,可能会导致应用程序的异常和一些不可预知的错误行为。常用参数的校验这里例举一些项目中比较常用的参数模型校验项,如下所示:Name:姓名校验,比如需要是纯汉字的姓名;Password:密码强度验证,比如要求用户输入必须包含大小写字母、数字和特殊符号的强密码;QQ号:QQ 号码验证,是否是有效合法的 QQ 号码;China Postal Code:中国邮政编码;IP Address:IPV4 或者 IPV6 地址验证;Phone:手机号码或者座机号码合法性验证;ID Card:身份证号码验证,比如:15 位和 18 位数身份证号码;Email Address:邮箱地址的合法性校验;String:字符串验证,比如字段是否不为 null、长度是否超限;URL:验证属性是否具有 URL 格式;Number:数值型参数校验,数值范围校验,比如非负数,非负整数,正整数等;File:文件路径及扩展名校验;对于参数校验,常见的方式有正则匹配校验,通过对目标参数编写合法的正则表达式,实现对参数合法性的校验。.NET 中内置 DataAnnotations 提供的特性校验上面我们介绍了一些常用的参数验证项,接下来我们来了解下在 .NET 中内置提供的 DataAnnotations 数据注解,该类提供了一些常用的验证参数特性。官方解释:提供用于为 ASP.NET MVC 和 ASP.NET 数据控件定义元数据的特性类。该类位于 System.ComponentModel.DataAnnotations 命名空间。关于 DataAnnotations 中的特性介绍让我们可以通过这些特性对 API 请求中的参数进行验证,常用的特性一般有:[ValidateNever]: 指示应从验证中排除属性或参数。[CreditCard]:验证属性是否具有信用卡格式。[Compare]:验证模型中的两个属性是否匹配。[EmailAddress]:验证属性是否具有电子邮件格式。[Phone]:验证属性是否具有电话号码格式。[Range]:验证属性值是否位于指定范围内。[RegularExpression]:验证属性值是否与指定的正则表达式匹配。[Required]:验证字段是否不为 null。[StringLength]:验证字符串属性值是否不超过指定的长度限制。[Url]:验证属性是否具有 URL 格式。其中 RegularExpression 特性,基于正则表达式可以扩展实现很多常用的验证类型,下面的( 基于 DataAnnotations 的通用模型校验封装 )环节举例说明;关于该类更多详细信息请查看,https://learn.microsoft.com/zh-cn/dotnet/api/system.componentmodel.dataannotations?view=net-7.0基于 DataAnnotations 的通用模型校验封装此处主要是使用了 Validator.TryValidateObject() 方法:Validator.TryValidateObject(object instance, ValidationContext validationContext, ICollection<ValidationResult>? validationResults, bool validateAllProperties);Validator 类提供如下校验方法:基于 DataAnnotations 的特性校验助手实现步骤错误成员对象类 ErrorMembernamespace Jeff.Common.Validatetion;
/// <summary>
/// 错误成员对象
/// </summary>
public class ErrorMember
{
/// <summary>
/// 错误信息
/// </summary>
public string? ErrorMessage { get; set; }
/// <summary>
/// 错误成员名称
/// </summary>
public string? ErrorMemberName { get; set; }
}验证结果类 ValidResultnamespace Jeff.Common.Validatetion;
/// <summary>
/// 验证结果类
/// </summary>
public class ValidResult
{
public ValidResult()
{
ErrorMembers = new List<ErrorMember>();
}
/// <summary>
/// 错误成员列表
/// </summary>
public List<ErrorMember> ErrorMembers { get; set; }
/// <summary>
/// 验证结果
/// </summary>
public bool IsVaild { get; set; }
}定义操作正则表达式的公共类 RegexHelper(基于 RegularExpression 特性扩展)using System;
using System.Net;
using System.Text.RegularExpressions;
namespace Jeff.Common.Validatetion;
/// <summary>
/// 操作正则表达式的公共类
/// Regex 用法参考:https://learn.microsoft.com/zh-cn/dotnet/api/system.text.regularexpressions.regex.-ctor?redirectedfrom=MSDN&view=net-7.0
/// </summary>
public class RegexHelper
{
#region 常用正则验证模式字符串
public enum ValidateType
{
Email, // 邮箱
TelePhoneNumber, // 固定电话(座机)
MobilePhoneNumber, // 移动电话
Age, // 年龄(1-120 之间有效)
Birthday, // 出生日期
Timespan, // 时间戳
IdentityCardNumber, // 身份证
IpV4, // IPv4 地址
IpV6, // IPV6 地址
Domain, // 域名
English, // 英文字母
Chinese, // 汉字
MacAddress, // MAC 地址
Url, // URL
}
private static readonly Dictionary<ValidateType, string> keyValuePairs = new Dictionary<ValidateType, string>
{
{ ValidateType.Email, _Email },
{ ValidateType.TelePhoneNumber,_TelephoneNumber },
{ ValidateType.MobilePhoneNumber,_MobilePhoneNumber },
{ ValidateType.Age,_Age },
{ ValidateType.Birthday,_Birthday },
{ ValidateType.Timespan,_Timespan },
{ ValidateType.IdentityCardNumber,_IdentityCardNumber },
{ ValidateType.IpV4,_IpV4 },
{ ValidateType.IpV6,_IpV6 },
{ ValidateType.Domain,_Domain },
{ ValidateType.English,_English },
{ ValidateType.Chinese,_Chinese },
{ ValidateType.MacAddress,_MacAddress },
{ ValidateType.Url,_Url },
};
public const string _Email = @"^(\w)+(\.\w)*@(\w)+((\.\w+)+)$"; // ^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$ , [A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}
public const string _TelephoneNumber = @"(d+-)?(d{4}-?d{7}|d{3}-?d{8}|^d{7,8})(-d+)?"; //座机号码(中国大陆)
public const string _MobilePhoneNumber = @"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$"; //移动电话
public const string _Age = @"^(?:[1-9][0-9]?|1[01][0-9]|120)$"; // 年龄 1-120 之间有效
public const string _Birthday = @"^((?:19[2-9]\d{1})|(?:20(?:(?:0[0-9])|(?:1[0-8]))))((?:0?[1-9])|(?:1[0-2]))((?:0?[1-9])|(?:[1-2][0-9])|30|31)$";
public const string _Timespan = @"^15|16|17\d{8,11}$"; // 目前时间戳是15开头,以后16、17等开头,长度 10 位是秒级时间戳的正则,13 位时间戳是到毫秒级的。
public const string _IdentityCardNumber = @"^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$";
public const string _IpV4 = @"^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$";
public const string _IpV6 = @"^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$";
public const string _Domain = @"^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?$";
public const string _English = @"^[A-Za-z]+$";
public const string _Chinese = @"^[\u4e00-\u9fa5]{0,}$";
public const string _MacAddress = @"^([0-9A-F]{2})(-[0-9A-F]{2}){5}$";
public const string _Url = @"^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$";
#endregion
/// <summary>
/// 获取验证模式字符串
/// </summary>
/// <param name="validateType"></param>
/// <returns></returns>
public static (bool hasPattern, string pattern) GetValidatePattern(ValidateType validateType)
{
bool hasPattern = keyValuePairs.TryGetValue(validateType, out string? pattern);
return (hasPattern, pattern ?? string.Empty);
}
#region 验证输入字符串是否与模式字符串匹配
/// <summary>
/// 验证输入字符串是否与模式字符串匹配
/// </summary>
/// <param name="input">输入的字符串</param>
/// <param name="validateType">模式字符串类型</param>
/// <param name="matchTimeout">超时间隔</param>
/// <param name="options">筛选条件</param>
/// <returns></returns>
public static (bool isMatch, string info) IsMatch(string input, ValidateType validateType, TimeSpan matchTimeout, RegexOptions options = RegexOptions.None)
{
var (hasPattern, pattern) = GetValidatePattern(validateType);
if (hasPattern && !string.IsNullOrWhiteSpace(pattern))
{
bool isMatch = IsMatch(input, pattern, matchTimeout, options);
if (isMatch) return (true, "Format validation passed."); // 格式验证通过。
else return (false, "Format validation failed."); // 格式验证未通过。
}
return (false, "Unknown ValidatePattern."); // 未知验证模式
}
/// <summary>
/// 验证输入字符串是否与模式字符串匹配,匹配返回true
/// </summary>
/// <param name="input">输入字符串</param>
/// <param name="pattern">模式字符串</param>
/// <returns></returns>
public static bool IsMatch(string input, string pattern)
{
return IsMatch(input, pattern, TimeSpan.Zero, RegexOptions.IgnoreCase);
}
/// <summary>
/// 验证输入字符串是否与模式字符串匹配,匹配返回true
/// </summary>
/// <param name="input">输入的字符串</param>
/// <param name="pattern">模式字符串</param>
/// <param name="matchTimeout">超时间隔</param>
/// <param name="options">筛选条件</param>
/// <returns></returns>
public static bool IsMatch(string input, string pattern, TimeSpan matchTimeout, RegexOptions options = RegexOptions.None)
{
return Regex.IsMatch(input, pattern, options, matchTimeout);
}
#endregion
}定义验证结果统一模型格式类 ResponseInfo(此类通常也是通用的数据响应模型类)namespace Jeff.Common.Model;
public sealed class ResponseInfo<T> where T : class
{
/*
Microsoft.AspNetCore.Http.StatusCodes
System.Net.HttpStatusCode
*/
/// <summary>
/// 响应代码(自定义)
/// </summary>
public int Code { get; set; }
/// <summary>
/// 接口状态
/// </summary>
public bool Success { get; set; }
#region 此处可以考虑多语言国际化设计(语言提示代号对照表)
/// <summary>
/// 语言对照码,参考:https://blog.csdn.net/shenenhua/article/details/79150053
/// </summary>
public string Lang { get; set; } = "zh-cn";
/// <summary>
/// 提示信息
/// </summary>
public string Message { get; set; } = string.Empty;
#endregion
/// <summary>
/// 数据体
/// </summary>
public T? Data { get; set; }
}实现验证助手类 ValidatetionHelper,配合 System.ComponentModel.DataAnnotations 类使用// 数据注解,https://learn.microsoft.com/zh-cn/dotnet/api/system.componentmodel.dataannotations?view=net-7.0
using System.ComponentModel.DataAnnotations;
using Jeff.Common.Model;
namespace Jeff.Common.Validatetion;
/// <summary>
/// 验证助手类
/// </summary>
public sealed class ValidatetionHelper
{
/// <summary>
/// DTO 模型校验
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static ValidResult IsValid(object value)
{
var result = new ValidResult();
try
{
var validationContext = new ValidationContext(value);
var results = new List<ValidationResult>();
bool isValid = Validator.TryValidateObject(value, validationContext, results, true);
result.IsVaild = isValid;
if (!isValid)
{
foreach (ValidationResult? item in results)
{
result.ErrorMembers.Add(new ErrorMember()
{
ErrorMessage = item.ErrorMessage,
ErrorMemberName = item.MemberNames.FirstOrDefault()
});
}
}
}
catch (ValidationException ex)
{
result.IsVaild = false;
result.ErrorMembers = new List<ErrorMember>
{
new ErrorMember()
{
ErrorMessage = ex.Message,
ErrorMemberName = "Internal error"
}
};
}
return result;
}
/// <summary>
/// DTO 模型校验统一响应信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <returns></returns>
public static ResponseInfo<ValidResult> GetValidInfo<T>(T model) where T : class
{
var result = new ResponseInfo<ValidResult>();
var validResult = IsValid(model);
if (!validResult.IsVaild)
{
result.Code = 420;
result.Message = "DTO 模型参数值异常";
result.Success = false;
result.Data = validResult;
}
else
{
result.Code = 200;
result.Success = true;
result.Message = "DTO 模型参数值合法";
}
return result;
}
}如何使用 DataAnnotations 封装的特性校验助手?首先定义一个数据模型类(DTO),添加校验特性 ValidationAttributeusing System.ComponentModel.DataAnnotations;
using Jeff.Common.Validatetion;
namespace Jeff.Comm.Test;
public class Person
{
[Display(Name = "姓名"), Required(ErrorMessage = "{0}必须填写")]
public string Name { get; set; }
[Display(Name = "邮箱")]
[Required(ErrorMessage = "{0}必须填写")]
[RegularExpression(RegexHelper._Email, ErrorMessage = "RegularExpression: {0}格式非法")]
[EmailAddress(ErrorMessage = "EmailAddress: {0}格式非法")]
public string Email { get; set; }
[Display(Name = "Age年龄")]
[Required(ErrorMessage = "{0}必须填写")]
[Range(1, 120, ErrorMessage = "超出范围")]
[RegularExpression(RegexHelper._Age, ErrorMessage = "{0}超出合理范围")]
public int Age { get; set; }
[Display(Name = "Birthday出生日期")]
[Required(ErrorMessage = "{0}必须填写")]
[RegularExpression(RegexHelper._Timespan, ErrorMessage = "{0}超出合理范围")]
public TimeSpan Birthday { get; set; }
[Display(Name = "Address住址")]
[Required(ErrorMessage = "{0}必须填写")]
[StringLength(200, MinimumLength = 10, ErrorMessage = "{0}输入长度不正确")]
public string Address { get; set; }
[Display(Name = "Mobile手机号码")]
[Required(ErrorMessage = "{0}必须填写")]
[RegularExpression(RegexHelper._MobilePhoneNumber, ErrorMessage = "{0}格式非法")]
public string Mobile { get; set; }
[Display(Name = "Salary薪水")]
[Required(ErrorMessage = "{0}必须填写")]
[Range(typeof(decimal), "1000.00", "3000.99")]
public decimal Salary { get; set; }
[Display(Name = "MyUrl连接")]
[Required(ErrorMessage = "{0}必须填写")]
[Url(ErrorMessage = "Url:{0}格式非法")]
[RegularExpression(RegexHelper._Url, ErrorMessage = "RegularExpression:{0}格式非法")]
public string MyUrl { get; set; }
}控制台调用通用校验助手验证方法 ValidatetionHelper.IsValid() 或 ValidatetionHelper.GetValidInfo()// 通用模型数据验证测试
static void ValidatetionTest()
{
var p = new Person
{
Name = "",
Age = -10,
Email = "www.baidu.com",
MobilePhoneNumber = "12345",
Salary = 4000,
MyUrl = "aaa"
};
// 调用通用模型校验
var result = ValidatetionHelper.IsValid(p);
if (!result.IsVaild)
{
foreach (ErrorMember errorMember in result.ErrorMembers)
{
// 控制台打印字段验证信息
Console.WriteLine($"{errorMember.ErrorMemberName}:{errorMember.ErrorMessage}");
}
}
Console.WriteLine();
// 调用通用模型校验,返回统一数据格式
var validInfo = ValidatetionHelper.GetValidInfo(p);
var options = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, // 设置中文编码乱码
WriteIndented = false
};
string jsonStr = JsonSerializer.Serialize(validInfo, options);
Console.WriteLine($"校验结果返回统一数据格式:{jsonStr}");
}在控制台Program.Main 方法中调用 ValidatetionTest() 方法:internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
{
#region 数据注解(DataAnnotations)模型验证
ValidatetionTest();
#endregion
}
Console.ReadKey();
}启动控制台,输出如下信息:如何实现自定义的验证特性?当我们碰到这些参数需要验证的时候,而上面内置类提供的特性不能满足需求时,此时我们可以实现自定义的验证特性来满足校验需求,按照微软给出的编码规则,我们只需继承 ValidationAttribute 类,并重写 IsValid() 方法即可。自定义校验特性案例比如实现一个密码强度的验证,实现步骤如下:定义密码强度规则,只包含英文字母、数字和特殊字符的组合,并且组合长度至少 8 位数;/// <summary>
/// 只包含英文字母、数字和特殊字符的组合
/// </summary>
/// <returns></returns>
public static bool IsCombinationOfEnglishNumberSymbol(string input, int? minLength = null, int? maxLength = null)
{
var pattern = @"(?=.*\d)(?=.*[a-zA-Z])(?=.*[^a-zA-Z\d]).";
if (minLength is null && maxLength is null)
pattern = $@"^{pattern}+$";
else if (minLength is not null && maxLength is null)
pattern = $@"^{pattern}{{{minLength},}}$";
else if (minLength is null && maxLength is not null)
pattern = $@"^{pattern}{{1,{maxLength}}}$";
else
pattern = $@"^{pattern}{{{minLength},{maxLength}}}$";
return Regex.IsMatch(input, pattern);
}实现自定义特性 EnglishNumberSymbolCombinationAttribute,继承自 ValidationAttribute;using System.ComponentModel.DataAnnotations;
namespace Jeff.Common.Validatetion.CustomAttributes;
/// <summary>
/// 是否是英文字母、数字和特殊字符的组合
/// </summary>
public class EnglishNumberSymbolCombinationAttribute : ValidationAttribute
{
/// <summary>
/// 默认的错误提示信息
/// </summary>
private const string error = "无效的英文字母、数字和特殊字符的组合";
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value is null) return new ValidationResult("参数值为 null");
//if (value is null)
//{
// throw new ArgumentNullException(nameof(attribute));
//}
// 验证参数逻辑 value 是需要验证的值,而 validationContext 中包含了验证相关的上下文信息,这里可自己封装一个验证格式的 FormatValidation 类
if (FormatValidation.IsCombinationOfEnglishNumberSymbol(value as string, 8))
//验证成功返回 success
return ValidationResult.Success;
//不成功 提示验证错误的信息
else return new ValidationResult(ErrorMessage ?? error);
}
}以上就实现了一个自定义规则的 自定义验证特性,使用方式很简单,可以把它附属在我们 请求的参数 上或者 DTO 里的属性,也可以是 Action 上的形参,如下所示:public class CreateDTO
{
[Required]
public string StoreName { get; init; }
[Required]
// 附属在 DTO 里的属性
[EnglishNumberSymbolCombination(ErrorMessage = "UserId 必须是英文字母、数字和特殊符号的组合")]
public string UserId { get; init; }
}
...
// 附属在 Action 上的形参
[HttpGet]
public async ValueTask<ActionResult> Delete([EnglishNumberSymbolCombination]string userId, string storeName)该自定义验证特性还可以结合 DataAnnotations 内置的 [Compare] 特性,可以实现账号注册的密码确认验证(输入密码和确认密码是否一致性)。关于更多自定义参数校验特性,感兴趣的小伙伴可参照上面案例的实现思路,自行扩展实现哟。总结对于模型参数的校验,在实际项目系统中是非常有必要性的(通常在数据源头提供验证),利用 .NET 内置的 DataAnnotations(数据注解)提供的特性校验,可以很方便的实现通用的模型校验助手,关于其他特性的用法,请自行参考微软官方文档,这里注意下RegularExpressionAttribute(指定 ASP.NET 动态数据中的数据字段值必须与指定的正则表达式匹配),该特性可以方便的接入正则匹配验证,当遇到复杂的参数校验时,可以快速方便的扩展自定义校验特性,从此告别传统编码中各种 if(xxx != yyyy) 判断的验证,让整体代码编写更佳简练干净。
把盏言欢,款款而谈,ChatGPT结合钉钉机器人(outgoing回调)打造人工智能群聊/单聊场景,基于Python3.10
就像黑火药时代里突然诞生的核弹一样,OpenAI的ChatGPT语言模型的横空出世,是人工智能技术发展史上的一个重要里程碑。这是一款无与伦比、超凡绝伦的模型,能够进行自然语言推理和对话,并且具有出色的语言生成能力。好吧,本篇的开头其实是由ChatGPT生成的:没办法,面对这个远超时代的AI产品,我们能说什么呢?顶礼膜拜?惊为天人?任何言语对于描述ChatGPT来说已经是苍白无力的,而辞海中的形容词在面对ChatGPT时也已经鞭长莫及。一句话:言语不能赞其伟大。本次我们利用ChatGPT的开放API接入钉钉群聊/单聊机器人,让钉钉机器人具备进行自然语言推理和对话的能力,所谓化腐朽为神奇,不过如此。注册和使用OpenAi的ChatGPT首先注册OpenAi平台:https://beta.openai.com/ ,由于ChatGPT过于火爆,导致很多地区无法正常注册,这里推荐使用北美地区的代理IP,与此同时,一定要注意,如果之后希望使用后端的API接口方式调用ChatGPT,就不要使用谷歌或者微软的三方账号进行登录,否则无法通过邮箱和秘钥交换OpenAi平台的access\_token,切记。同时,接受验证码手机号也必须是北美地区的手机号,这里推荐一个北美地区的接码平台:https://sms.qisms.com/index 非常好用。注册成功之后,这里推荐github上开源大神rawandahmad698已经封装好的开源SDK,避免重复造轮子:https://github.com/rawandahmad698/PyChatGPT安装SDK:pip3 install chatgptpy --upgrade安装好之后,编写测试脚本:chat = Chat(email="OpenAi邮箱", password="OpenAi密码",proxies="代理地址")
answer = chat.ask("你好")
print(answer)注意,运行代码之前,一定要使用代理proxies,并且确保是北美地区的IP地址。程序返回:[OpenAI] Email address: ********
[OpenAI] Password: *********
[OpenAI] Using proxy: {'http': 'http://localhost:4780', 'https': 'http://localhost:4780'}
[OpenAI] Beginning auth process
[OpenAI][1] Making request to https://chat.openai.com/auth/login
[OpenAI][1] Request was successful
[OpenAI][2] Beginning part two
[OpenAI][2] Grabbing CSRF token from https://chat.openai.com/api/auth/csrf
[OpenAI][2] Request was successful
[OpenAI][2] CSRF Token: 1b1357a34e4b0b9a74e999372fe0413ab981c9a72e030a54b3bf172bd6176c5e
[OpenAI][3] Beginning part three
[OpenAI][3] Making request to https://chat.openai.com/api/auth/signin/auth0?prompt=login
[OpenAI][3] Request was successful
[OpenAI][3] Callback URL: https://auth0.openai.com/authorize?client_id=TdJIcbe16WoTHtN95nyywh5E4yOo6ItG&scope=openid%20email%20profile%20offline_access%20model.request%20model.read%20organization.read&response_type=code&redirect_uri=https%3A%2F%2Fchat.openai.com%2Fapi%2Fauth%2Fcallback%2Fauth0&audience=https%3A%2F%2Fapi.openai.com%2Fv1&prompt=login&state=RJt9U13ATPmlt795xMNohQZcUNOytZNvHoq3JI8HGZ4&code_challenge=Pq97ptna00Ybak2dUmIMhR3eqmXZnZz-Fij7otMMw7U&code_challenge_method=S256
[OpenAI][4] Making request to https://auth0.openai.com/authorize?client_id=TdJIcbe16WoTHtN95nyywh5E4yOo6ItG&scope=openid%20email%20profile%20offline_access%20model.request%20model.read%20organization.read&response_type=code&redirect_uri=https%3A%2F%2Fchat.openai.com%2Fapi%2Fauth%2Fcallback%2Fauth0&audience=https%3A%2F%2Fapi.openai.com%2Fv1&prompt=login&state=RJt9U13ATPmlt795xMNohQZcUNOytZNvHoq3JI8HGZ4&code_challenge=Pq97ptna00Ybak2dUmIMhR3eqmXZnZz-Fij7otMMw7U&code_challenge_method=S256
[OpenAI][4] Request was successful
[OpenAI][4] Current State: hKFo2SA5VzlqUDA0Mkl5TnQtNUpYcGRBU0ZfRkhQVUY1eVpWV6Fur3VuaXZlcnNhbC1sb2dpbqN0aWTZIGMzU0xvbThRUXFxMTczeVg4bF8zRFZnYVNOM2M3Q0RFo2NpZNkgVGRKSWNiZTE2V29USHROOTVueXl3aDVFNHlPbzZJdEc
[OpenAI][5] Making request to https://auth0.openai.com/u/login/identifier?state=hKFo2SA5VzlqUDA0Mkl5TnQtNUpYcGRBU0ZfRkhQVUY1eVpWV6Fur3VuaXZlcnNhbC1sb2dpbqN0aWTZIGMzU0xvbThRUXFxMTczeVg4bF8zRFZnYVNOM2M3Q0RFo2NpZNkgVGRKSWNiZTE2V29USHROOTVueXl3aDVFNHlPbzZJdEc
[OpenAI][5] Request was successful
[OpenAI][5] No captcha detected
[OpenAI][6] Making request to https://auth0.openai.com/u/login/identifier
[OpenAI][6] Email found
[OpenAI][7] Entering password...
[OpenAI][7] Password was correct
[OpenAI][7] Old state: hKFo2SA5VzlqUDA0Mkl5TnQtNUpYcGRBU0ZfRkhQVUY1eVpWV6Fur3VuaXZlcnNhbC1sb2dpbqN0aWTZIGMzU0xvbThRUXFxMTczeVg4bF8zRFZnYVNOM2M3Q0RFo2NpZNkgVGRKSWNiZTE2V29USHROOTVueXl3aDVFNHlPbzZJdEc
[OpenAI][7] New State: c3SLom8QQqq173yX8l_3DVgaSN3c7CDE
[OpenAI][8] Making request to https://auth0.openai.com/authorize/resume?state=c3SLom8QQqq173yX8l_3DVgaSN3c7CDE
[OpenAI][8] All good
[OpenAI][8] Access Token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UaEVOVUpHTkVNMVFURTRNMEZCTWpkQ05UZzVNRFUxUlRVd1FVSkRNRU13UmtGRVFrRXpSZyJ9.eyJodHRwczovL2FwaS5vcGVuYWkuY29tL3Byb2ZpbGUiOnsiZW1haWwiOiJ6Y3hleTI5MTFAb3V0bG9vay5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZ2VvaXBfY291bnRyeSI6IlVTIn0sImh0dHBzOi8vYXBpLm9wZW5haS5jb20vYXV0aCI6eyJ1c2VyX2lkIjoidXNlci1IcHQ2SXF6R0k0RW43V213dGdzaUVOUjUifSwiaXNzIjoiaHR0cHM6Ly9hdXRoMC5vcGVuYWkuY29tLyIsInN1YiI6ImF1dGgwfDYzOTA3ZWRiMTQzYTFkZjQxMzk5Yzc0YyIsImF1ZCI6WyJodHRwczovL2FwaS5vcGVuYWkuY29tL3YxIiwiaHR0cHM6Ly9vcGVuYWkuYXV0aDAuY29tL3VzZXJpbmZvIl0sImlhdCI6MTY3MDQ1OTkzNywiZXhwIjoxNjcwNTQ2MzM3LCJhenAiOiJUZEpJY2JlMTZXb1RIdE45NW55eXdoNUU0eU9vNkl0RyIsInNjb3BlIjoib3BlbmlkIGVtYWlsIHByb2ZpbGUgbW9kZWwucmVhZCBtb2RlbC5yZXF1ZXN0IG9yZ2FuaXphdGlvbi5yZWFkIG9mZmxpbmVfYWNjZXNzIn0.PtXKhJqwudNKLIkNRc5OO6T7Tsl8ydZ8WWnCJ3Ax2c40CQibRTiGLDmfvk2gW5pVIkOpKldWYs6Jrd8UVi0Ih9VMDwS9JL6HpZKsoRaIhy6r6l7AW5vMMQN-l0ntCsgefQeGIrwtCTUsIklN8dyZDkRkympC2AzRkayAcFvFckXTHi_J5Fivr5J7We_OM4cGFJEKTLkaSw6MnYku-uYwAKPVEpFsF7fLnUBRQxn5Zz90FhdeLYEg4IUjPWKPp1iMbp_fa9qhwwtKBwogtrIVzq2t8NdUotoNYgoo2uV2xjQWC2m4V4C_xgkSzLj2TTtRJMOYKGH-lHWs2_yRQF0wOg
[OpenAI][9] Saving access token...
[OpenAI][8] Saved access token首次运行程序会通过代理自动登录OpenAi平台,并且换取token,最后将token存储在本地。随后返回ChatGPT的信息:➜ mydemo git:(master) ✗ /opt/homebrew/bin/python3.10 "/Users/liuyue/wodfan/work/mydemo/test_chatgpt.py"
Using proxies: http://localhost:4780
你好,很高兴为你提供帮助。有什么需要我帮忙的吗?至此,ChatGPT接口就调试好了。配置钉钉Dingding机器人随后,我们来配置C端的机器人,注意这里一定要使用支持outgoing回调的企业机器人,而不是普通的机器人,参考文档:https://open.dingtalk.com/document/group/enterprise-created-chatbot创建好企业机器人之后,获取机器人应用的Key和秘钥,同时配置好出口IP和接口地址:所谓出口IP即调用钉钉服务合法的ip,消息接受地址是接受C端信息的地址,这里我们使用异步非阻塞的Tornado框架来构建接受信息服务:import hmac
import hashlib
import base64
import json
import tornado
from tornado.options import define, options
define('port', default=8000, help='default port',type=int)
class Robot(tornado.web.RequestHandler):
async def post(self):
timestamp = self.request.headers.get('timestamp', None)
sign = self.request.headers.get('sign', None)
app_secret = '钉钉机器人秘钥'
app_secret_enc = app_secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, app_secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(app_secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
my_sign = base64.b64encode(hmac_code).decode('utf-8')
if sign != my_sign:
return self.finish({"errcode":1,"msg":"签名有误"})
data = json.loads(self.request.body)
text = data['text']["content"]
atUsers = data.get("atUsers",None)
uid = data.get("senderStaffId",None)
return self.finish({"errcode":0,"msg":text})
urlpatterns = [
(r"/robot_chat/",Robot),
]
# 创建Tornado实例
application = tornado.web.Application(urlpatterns,debug=True)
if __name__ == "__main__":
tornado.options.parse_command_line()
application.listen(options.port)
tornado.ioloop.IOLoop.instance().start()这里我们通过Robot异步控制器来接受所有来自钉钉客户端的信息,即人类对机器人说的话,需要注意的是,后端服务需要对请求头中的timestamp和sign进行验证,以判断是否是来自钉钉的合法请求,避免其他仿冒钉钉调用开发者的HTTPS服务传送数据。所以这里一旦签名有问题,就结束逻辑:
timestamp = self.request.headers.get('timestamp', None)
sign = self.request.headers.get('sign', None)
app_secret = '钉钉机器人秘钥'
app_secret_enc = app_secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, app_secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(app_secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
my_sign = base64.b64encode(hmac_code).decode('utf-8')
if sign != my_sign:
return self.finish({"errcode":1,"msg":"签名有误"})
最后该接口会返回发信人id(uid)以及具体信息内容(text)。至此,后端接受服务就配置好了。下面就是后端推送服务,首先,根据官方文档:https://open.dingtalk.com/document/orgapp-server/obtain-the-access\_token-of-an-internal-app?spm=ding\_open\_doc.document.0.0.5f255239xgW3zE#topic-2056397需要获取钉钉接口的token:def get_token(self):
res = requests.post("https://api.dingtalk.com/v1.0/oauth2/accessToken",data=json.dumps({"appKey":self._appKey,"appSecret":self._appSecret}),headers={"Content-Type":"application/json"})
token = res.json()["accessToken"]
return token随后,根据文档:https://open.dingtalk.com/document/group/chatbots-send-one-on-one-chat-messages-in-batches?spm=ding\_open\_doc.document.0.0.22e749acXECz5m#topic-2080109我们来配置单聊推送:# 单聊
def send_message(self,uid,message):
res = requests.post("https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend",data=json.dumps({"robotCode":self._appKey,"userIds":[uid],"msgKey":"sampleText","msgParam":'{"content":"'+message+'"}'}),headers={"Content-Type":"application/json","x-acs-dingtalk-access-token":self._token})
print(res.text)具体效果:接着,继续根据官方文档:https://open.dingtalk.com/document/robots/guide-to-user-access-for-intra-enterprise-robot-group-chat配置群聊推送方法:# 群聊
def send_user(self,uid,message):
data = {
"at": {
"atUserIds": [
uid
]
},
"text": {
"content": message
},
"msgtype": "text"
}
res = requests.post(self._webhook,data=json.dumps(data),headers={"Content-Type":"application/json"})
print(res.text)群聊效果:这里需要注意的是,单聊是通过接口的方式进行推送,而群内聊天是通过webhook方式进行推送,关于webhook,请移玉步至:使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)完整代码:import requests
import json
from pychatgpt import Chat
class DingDing:
def __init__(self,appKey=None,appSecret=None) -> None:
self._appKey = appKey
self._appSecret = appSecret
self._token = self.get_token()
# 机器人webhook地址
self._webhook = ""
def get_token(self):
res = requests.post("https://api.dingtalk.com/v1.0/oauth2/accessToken",data=json.dumps({"appKey":self._appKey,"appSecret":self._appSecret}),headers={"Content-Type":"application/json"})
token = res.json()["accessToken"]
return token
# 单聊
def send_message(self,uid,message):
res = requests.post("https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend",data=json.dumps({"robotCode":self._appKey,"userIds":[uid],"msgKey":"sampleText","msgParam":'{"content":"'+message+'"}'}),headers={"Content-Type":"application/json","x-acs-dingtalk-access-token":self._token})
print(res.text)
# 群聊
def send_user(self,uid,message):
data = {
"at": {
"atUserIds": [
uid
]
},
"text": {
"content": message
},
"msgtype": "text"
}
res = requests.post(self._webhook,data=json.dumps(data),headers={"Content-Type":"application/json"})
print(res.text)
if __name__ == '__main__':
dingding = DingDing("appkey","appSecret")
#chat = Chat(email="OpenAi邮箱", password="OpenAi密码",proxies="代理地址")
#answer = chat.ask("你好")
# 单聊
#dingding.send_message('uid',answer)
# 群聊
#dingding.send_user('uid',answer)
#print(answer)至此,后端推送服务就配置好了。结语最后,奉上Github项目地址,与众亲同飨:https://github.com/zcxey2911/Python\_ChatGPT\_ForDingding\_OpenAi ,毫无疑问,ChatGPT是NLP领域历史上最伟大的项目,没有之一,伟大,就是技术层面的极致,你同意吗?
容器持久化存储-容器有状态应用调研报告
前言本文通过调研主流开源社区、权威调研机构推荐总结了最常用的 TOP 有状态应用分布。同时基于使用容器持久化存储部署容器有状态应用总结了当前应用部署方案、数据类型、有状态应用类型占比,分析了容器持久化存储数据共享、弹性扩展、性能需求以及挑战。“从用户视角看云原生带来的存储变化,最明显的就是用户使用存储界面发生上移,和应用不直接相关的存储服务从应用层下沉到云平台,用户更关心应用。存储供给的特性更加高密、弹性、极速。”—— 徐立 阿里云文件存储负责人 1. 容器持久化存储-容器有状态应用调研说明TOP 有状态应用列表:- 通过调研主流开源社区推荐、调研 ACK 容器服务应用目录 & Gartner 推荐有状态应用目录、调研权威机构如 Bitnami 适合云上部署 Mulit-tier application & single-tier application 应用【请参考本文 “4.附录” 章节】- 总结最常用的 TOP 有状态应用列表如下:数据库:Cassandra、MariaDB、MongoDB、MySQL、Neo4j、PostgreSQL、Redis、etcd内容管理:Drupal、CKAN、MediaWIKI、DNN、Joomls持续集成部署:Jenkins、Gitlab、maven、Puppet大数据:Hadoop、Hypertable、Mesos、Presto、Solr、Spark、Storm分析搜索:Grafana、ElasticSearch、Prometheus、kibana、logstashWeb服务:NGINX、WordPress、Apache HTTP Server、Tomcat、httpdInfrastructure:RabbitMQ、Memcached、Kafka、ZooKeeper、Node.js、NATS、wildfly开发工具:LAMPAI:mxnet、Pytorch、tensorflow-notebook、tensorflow-resnet 2. 容器持久化存储-容器有状态应用调研总结:当前应用采用容器化部署比例:75.34%当前容器化部署环境占比:36.99% 选择阿里云容器服务 ACK12.33% 选择阿里云 Serverless 容器服务 ASK53.42% 选择自建容器服务当前容器环境使用持久化存储方案: 73.97% 使用文件存储43.84% 使用块存储方案当前数据的主要类型:结构化数据,例如数据库占比 79.45%非结构化数据,例如文件占比 49.32%当前容器的主要应用类型:选择有状态应用的用户占比 61.64% 选择无状态应用的用户占比 56.16%当前容器的有状态应用类型占比:TOP3 数据库 Web服务 持续集成部署数据库: 64.38%,其有状态应用的分布比例如下所示题目/选项CassandraMariaDBMongoDBMySQLNeo4jPostgreSQLRedisetcd数据库应用2.13%4.26%10.64%74.47%02.13%4.26%2.13%内容管理:10.96%,其有状态应用的分布比例如下所示题目/选项DrupalCKANMediaWIKIDNNJoomls其他内容管理37.50%37.50%50.00%37.50%25.00%12.50%持续集成部署:42.47%,其有状态应用的分布比例如下所示题目/选项JenkinsGitlabmavenPuppet其他持续集成部署80.65%48.39%48.39%9.68%12.90%大数据:12.33%,其有状态应用的分布比例如下所示题目/选项HadoopHypertableMesosPrestoSolrSparkStorm大数据77.78%11.11%00011.11%0分析搜索:10.96%,其有状态应用的分布比例如下所示题目/选项GrafanaElasticSearchPrometheuskibanalogstash其他分析搜索12.50%62.50%12.50%0012.50%Web服务:45.21%,其有状态应用的分布比例如下所示题目/选项NGINXWordPressApache HTTP ServerTomcathttpd其他Web 服务57.58%3.03%9.09%27.27%3.03%0Infrastructure:9.59%,其有状态应用的分布比例如下所示题目/选项RabbitMQMemcachedKafkaZooKeeperNode.jsNATSwildfly其他Infrastructure71.43%14.29%42.86%28.57%28.57%0042.86%开发工具:16.44%AI:8.22%,其有状态应用的分布比例如下所示题目/选项mxnetPytorchtensorflow-notebooktensorflow-resnet其他AI75.00%100.00%50.00%75.00%25.00%有容器持久化存储数据共享需求用户占比:64.38% 有容器持久化存储弹性扩展需求用户占比:60.27%当前结构化数据容量规模:500GB 以下:占比 15%500GB - 2TB:占比 70%2 - 10TB:占比 10%10TB 以上:占比 5%当前非结构化数据容量规模50TB 及以上占比:37%20-30TB 占比:15%1-10TB 占比:27%1TB 以下占比:21%当前非结构化数据访问的性能要求:Bandwidth:53%Latency:25%IOPS:26%当前在使用容器存储的过程中,面临的主要挑战有哪些?数据安全,如权限、加密:占比 18%性能:占比 12%学习实践,如技术迭代慢、缺少实战经验:占比 32%弹性伸缩:占比 10%简化开发运维,如部署复杂度高、开发难度高,问题排查困难:占比 14%数据共享高可用:占比 12%成本:占比 4%稳定性:占比 8% 3. 容器持久化存储-容器有状态应用调研问卷反馈详情:3.1 当前应用采用容器化部署比例:75.34%3.2 当前容器化部署环境占比:36.99% 选择阿里云容器服务 ACK12.33% 选择阿里云 Serverless 容器服务 ASK53.42% 选择自建容器服务3.3 当前容器环境使用持久化存储方案: 73.97% 使用文件存储43.84% 使用块存储方案3.4 当前数据的主要类型:结构化数据,例如数据库占比 79.45%非结构化数据,例如文件占比 49.32%3.5 当前容器的主要应用类型:有状态应用占比 61.64% 无状态应用占比 56.16%3.6 当前容器的有状态应用类型占比:选项比例数据库:Cassandra、MariaDB、MongoDB、MySQL、Neo4j、PostgreSQL、Reids、etcd64.38%内容管理:Drupal、CKAN、MediaWIKI、DNN、Joomls10.96%持续集成部署:Jenkins、Gitlab、maven、Puppet42.47%大数据:Hadoop、Hypertable、Mesos、Presto、Solr、Spark、Storm12.33%分析搜索:Grafana、ElasticSearch、Prometheus、kibana、logstash10.96%Web服务:NGINX、WordPress、Apache HTTP Server、Tomcat、httpd45.21%Infrastructure:RabbitMQ、Memcached、Kafka、ZooKeeper、Node.js、NATS、wildfly9.59%开发工具:LAMP16.44%AI:mxnet、Pytorch、tensorflow-notebook、tensorflow-resnet5.48%其他8.22%3.7 当前容器环境的【数据库】的应用类型:题目/选项CassandraMariaDBMongoDBMySQLNeo4jPostgreSQLRedisetcd数据库应用2.13%4.26%10.64%74.47%02.13%4.26%2.13%3.8 当前容器环境的【内容管理】的有状态应用类型题目/选项DrupalCKANMediaWIKIDNNJoomls其他内容管理37.50%37.50%50.00%37.50%25.00%12.50%3.9 当前容器环境的【持续集成部署】的有状态应用类型题目/选项JenkinsGitlabmavenPuppet其他持续集成部署80.65%48.39%48.39%9.68%12.90%3.10 当前容器环境的【大数据】的应用类型题目/选项HadoopHypertableMesosPrestoSolrSparkStorm大数据77.78%11.11%00011.11%03.11 当前容器环境的【分析搜索】的应用类型题目/选项GrafanaElasticSearchPrometheuskibanalogstash其他分析搜索12.50%62.50%12.50%0012.50%3.12 当前容器环境的【Web 服务】的有状态应用类型题目/选项NGINXWordPressApache HTTP ServerTomcathttpd其他Web 服务57.58%3.03%9.09%27.27%3.03%03.13 当前容器环境的【Infrastructure】的有状态应用类型题目/选项RabbitMQMemcachedKafkaZooKeeperNode.jsNATSwildfly其他Infrastructure71.43%14.29%42.86%28.57%28.57%0042.86%3.14 当前容器环境的【AI】的有状态应用类型题目/选项mxnetPytorchtensorflow-notebooktensorflow-resnet其他AI75.00%100.00%50.00%75.00%25.00%3.15 有容器持久化存储数据共享需求用户占比:64.38% 3.16 有容器持久化存储弹性扩展需求用户占比:60.27%3.17 当前结构化数据容量规模:500GB 以下:占比 15%500GB - 2TB:占比 70%2 - 10TB:占比 10%10TB 以上:占比 5%3.18 当前非结构化数据容量规模:50TB 及以上占比:37%20-30TB 占比:15%1-10TB 占比:27%1TB 以下占比:21%3.19 当前非结构化数据访问的性能要求Bandwidth:53%Latency:25%IOPS:26%3.20 当前在使用容器存储的过程中,面临的主要挑战有哪些?数据安全,如权限、加密:占比 18%性能:占比 12%学习实践,如技术迭代慢、缺少实战经验:占比 32%弹性伸缩:占比 10%简化开发运维,如部署复杂度高、开发难度高,问题排查困难:占比 14%数据共享高可用:占比 12%成本:占比 4%稳定性:占比 8%4. 附录4.1 附录1:容器开源应用调研大数据HadoopApache 主持的这个项目是最广为人知的大数据工具。众多公司为 Hadoop 提供相关产品或商业支持,包括亚马逊网络服务、Cloudera、Hortonworks、IBM、Pivotal、Syncsort 和 VMware。知名用户包括:阿里巴巴、美国在线、电子港湾、Facebook、谷歌、Hulu、领英、Spotify、推特和雅虎。 支持的操作系统:Windows、Linux 和 OS X 相关网站:http://hadoop.apache.orgHypertableHypertable 在互联网公司当中非常流行,它由谷歌开发,用来提高数据库的可扩展性。用户包括百度、电子港湾、Groupon 和 Yelp。它与 Hadoop 兼容,提供商业支持和培训。 支持的操作系统:Linux 和 OS X 相关网站:http://www.hypertable.comMesosApache Mesos 是一种资源抽象工具,有了它,企业就可以鼗整个数据中心当成一个资源池,它在又在运行 Hadoop、Spark 及类似应用程序的公司当中很流行。使用它的企业组织包括:Airbnb、欧洲原子核研究组织(CERN)、思科、Coursera、Foursquare、Groupon、网飞(Netflix)、推特和优步。 支持的操作系统:Linux 和 OS X 相关网站:http://mesos.apache.orgPrestoPresto 由 Facebook 开发,自称是“一款开源分布式 SQL 查询引擎,用于对大大小小(从 GB 级到 PB 级)的数据源运行交互式分析查询。”Facebook 表示,它将 Presto 用于对 300PB 大小的数据仓库执行查询,其他用户包括 Airbnb 和 Dropbox。 支持的操作系统:Linux 相关网站:https://prestodb.ioSolr这种“快若闪电”的企业搜索平台声称高度可靠、扩展和容错。使用它的公司包括:AT&T、Ticketmaster、康卡斯特、Instagram、网飞、IBM、Adobe 和 SAP Hybris。 支持的操作系统:与操作系统无关 相关网站:http://Lucene.apache.org/solr/SparkApache Spark 声称,“它在内存中运行程序的速度比 Hadoop MapReduce 最多快 100 倍,在磁盘上快 10 倍。”Spark“支持”的企业组织包括:亚马逊、百度、Groupon、日立解决方案、IBM、MyFitnessPal、诺基亚和雅虎。 支持的操作系统:Windows、Linux 和 OS X 相关网站:http://spark.apache.orgStorm正如 Hadoop 用来处理批量数据,Apache Storm 用来处理实时数据。官方网站上显示用户包括:天气频道、推特、雅虎、WebMD、Spotify、威瑞信(Verisign)、Flipboard 和 Klout。 支持的操作系统:Linux 相关网站:https://storm.apache.org版本控制BazaarBazaar 由 Canonical 管理,被许多开源项目所使用,包括 Ubuntu、 GNU 基金会、Linux 基金会、MySQL、Bugzilla、 Debian 和 Maria DB。它简单易学,支持任何工作流程和工作区间模式,承诺存储效率很高、速度很快。 支持的操作系统:Windows、Linux 和 OS X 相关网站:http://bazaar.canonical.com/en/ Git这个版本控制系统已变得极受欢迎,这一方面归功于 GitHub 服务的使用日益广泛。使用它的公司和项目包括:谷歌、Facebook、微软、推特、领英、网飞、Perl、PostgreSQL、安卓、Rails、QT、Gnome 和 Eclipse。 支持的操作系统:Windows、Linux 和 OS X 相关网站:http://git-scm.com MercurialMercurial 是一种分布式源代码控制管理工具,专注于帮助团队更轻松、更快速地协同工作。用户包括 OpenJDK 和 NetBeans 等各大项目。 支持的操作系统:Windows、Linux 和 OS X 相关网站:https://www.mercurial-scm.orgSubversion这个企业级版本控制系统得到 Apache 的支持,首次发布于 2000 年。使用它的企业组织包括 Apache 软件基金会自己、Hobby Lobby、Mono、Plone 和 GNU Enterprise。 支持的操作系统:Windows、Linux 和 OS X 相关网站:http://subversion.apache.orgWeb 服务Apache HTTP ServerApache 至今已有 20 年多的历史,专利是自 1996 年以来互联网上最受欢迎的 Web 服务器系统。据 W3Techs 声称,目前所有网站中 55.3% 是由 Apache 支持的。 支持的操作系统:Windows、Linux 和 OS X 相关网站:http://httpd.apache.orgNginxNginx 的人气也极旺,它被互联网上所有网站中的大约四分之一所使用。除了俄罗斯许多访问量很大的网站外,用户还包括网飞和 WordPress.com。 支持的操作系统:Windows、Linux 和 OS X 相关网站:http://nginx.org内容管理DNN这款内容管理解决方案之前名为 DotNetNuke,承诺构建丰富的交互式网站时,只要花较少的精力,就能收到显著的成效。用户包括佳能、时代华纳有线电视、德州仪器和美国银行。 支持的操作系统:Windows 相关网站:http://www.dnnsoftware.comDrupalDrupal 声称,98000 多个开发人员在为这个极其流行的内容管理系统积极贡献代码。支持者包括微软、Zend、Fastly 和 New Relic,其内容市场有数百家公司参与其中,它们提供了相关的产品和服务。 支持的操作系统:与操作系统无关 相关网站:https://www.drupal.orgJoomlaJoomla 为数百万个网站提供平台,其下载量超过了 5000 万人次。许多用户当中就有这些公司:电子港湾、巴诺书店、MTV 和标致。 支持的操作系统:与操作系统无关 相关网站:https://www.joomla.orgMediaWikiMediaWiki 以维基百科使用的软件而出名,它还为百度、Vistaprint、Novell、英特尔和美国宇航局支持网站。它是构建可编辑网页的不错选择,许多企业组织用它来构建内部知识库。 支持的操作系统:Windows、Linux/Unix 和 OS X 相关网站:https://www.mediawiki.org/wiki/MediaWiki数据库Cassandra这种 NoSQL 数据库由 Facebook 开发,其用户包括苹果、欧洲原子核研究组织(CERN)、康卡斯特、电子港湾、GitHub、GoDaddy、Hulu、Instagram、Intuit、网飞、Reddit 及其他科技公司。它支持极其庞大的数据集,声称拥有非常高的性能和出色的耐用性和弹性。可通过第三方获得支持。 支持的操作系统:与操作系统无关 相关网站:http://cassandra.apache.orgCouchDBCouchDB 为 Web 而开发,这种 NoSQL 数据库将数据存储在 JSON 文档中,这类文档可通过 HTTP 来加以查询,并用 JavaScript 来处理。Cloudant 现在归 IBM 所有,它提供一款专业人员支持的软件版本,用户包括:三星、Akamai、Expedia、微软游戏工作室及其他公司。 支持的操作系统:Windows、Linux、OS X 和安卓 相关网站:http://couchdb.apache.orgMongoDBMongoDB 是一种 NoSQL 数据库,声称“针对关键任务型部署环境进行了优化”,用户包括 Foursquare、《福布斯》、Pebble、Adobe、领英、eHarmony 及其他公司。提供收费的专业版和企业版。 支持的操作系统:Windows、Linux、OS X 和 Solaris 相关网站:http://www.mongodb.orgMySQLMySQL 自称是“世界上最流行的开源数据库”,备受众多互联网公司的青睐,比如 YouTube、贝宝、谷歌、Facebook、推特、电子港湾、领英、优步和亚马逊。除了免费社区版外,它还有多款收费版。最新更新版声称速度比老版本快三倍。 支持的操作系统:Windows、Linux、Unix 和 OS X 相关网站:http://www.mysql.comNeo4jNeo4J 自诩为“世界上领先的图形数据库”,用于欺诈检测、推荐引擎、社交网站、主数据管理及更多领域。用户包括电子港湾、沃尔玛、思科、惠普、埃森哲、CrunchBase、eHarmony、Care.com 及另外许多企业组织。 支持的操作系统:Windows 和 Linux 相关网站:http://neo4j.com中间件JBoss红帽的 JBoss 中间件包括各种轻量级、对云计算友好的工具,同时结合、集成和自动化各个企业应用程序和系统。用户包括:橡树岭国家实验室、日产、思科、冠群科技、AMD 及其他公司。 支持的操作系统:Linux 相关网站:http://www.redhat.com/en/technologies/jboss-middleware开发工具BugzillaBugzilla 是开源社区的宠儿,用户包括 Mozilla、Linux 基金会、GNOME、KDE、Apache、LibreOffice、Open Office、Eclipse、红帽、Novell 及其他公司。这款软件缺陷追踪系统(bugtracker)的重要功能包括:高级搜索功能、电子邮件通知、预定报告、时间追踪、出色的安全及更多特性。 支持的操作系统:Windows、Linux 和 OS X 相关网站:https://www.bugzilla.orgEclipseEclipse 项目最为知名的是,它是一种大受欢迎的面向 Java 的集成开发环境(IDE),它还提供面向C/C++和 PHP 的 IDE,此外提供另外一大批开发工具。主要支持者包括冠群科技、谷歌、IBM、甲骨文、红帽和 SAP。 支持的操作系统:与操作系统无关 相关网站:http://www.eclipse.orgEmber.js这种框架用于“构建野心勃勃的 Web 应用程序”,旨在为 JavaScript 开发人员提高工作效率。官方网站上显示用户包括雅虎、Square、Livingsocial、Groupon、Twitch、TED、网飞、Heroku 和微软。 支持的操作系统:与操作系统无关 相关网站: http://emberjs.comGruntGrunt 是一种 JavaScript 任务运行工具,有助于自动处理重复性的开发任务。使用它的知名科技公司包括:Adobe、推特、Mozilla、Cloudant 和 WordPress。 支持的操作系统:与操作系统无关 相关网站:http://gruntjs.comLoopBack这个 Node.js 框架旨在让用户很容易构建 REST API,并连接到后端数据存储区。知名用户包括 GoDaddy、美国能源部和赛门铁克。 支持的操作系统:Windows、Linux、OS X、安卓和 iOS 相关网站:http://loopback.ioNode.jsNode.js 的成名之处在于,它让开发人员可以使用 JavaScript,编写服务器端应用程序。开发工作之前由 Joyent 管控,现在交由 Node.js 基金会监管。用户包括 IBM、微软、雅虎、SAP、领英、贝宝和网飞。 支持的操作系统:Windows、Linux 和 OS X 相关网站:https://nodejs.org/en/PhoneGapApache Cordova 是一种开源框架,让开发人员可以使用 HTML、CSS 和 JavaScript 等 Web 技术,构建移动应用程序。PhoneGap 是最受欢迎的 Cordova 发行版。使用某一种 Cordova 发行版的科技公司包括:维基百科、Facebook、 Salesforce、IBM、微软、Adobe 和黑莓。 支持的操作系统:Window、Linux 和 OS X 相关网站:http://phonegap.comReact NativeReact Native 由 Facebook 开发,这种框架可用于使用 JavaScript 和 React JavaScript 库(同样由 Facebook 开发),构建原生移动应用程序。其他用户包括:《探索》频道和 CBS 体育新闻网。 支持的操作系统:OS X 相关网站:http://facebook.github.io/react-native/Ruby on Rails这个 Web 开发框架在开发人员当中极其流行,它声称“为确保编程员满意和持续高效地工作进行了优化”。用户包括 Basecamp、推特、Shopify 和 GitHub 等公司。 支持的操作系统:Windows、Linux 和 OS X 相关网站:http://rubyonrails.orgSencha TouchSencha Touch 自称是“一种用于构建通用移动应用程序的领先的跨平台移动 Web 应用程序框架,基于 HTML5 和 JavaScript”。它既有开源许可证版本,也有商业许可证版本。据官方网站声称,《财富》100 强中 60% 使用它。 支持的操作系统:与操作系统无关 相关网站:https://www.sencha.com/products/touch/ ZK索尼、Sun、IBM、Adobe、电子港湾、富士通、梦工厂和优利系统等公司使用这种 Java Web 框架来构建 Web 和移动应用程序。提供收费支付及相关工具。 支持的操作系统:与操作系统无关 相关网站:http://www.zkoss.org系统管理工具AnsibleAnsible 现在归红帽所有,它自称是“一种异常简单的 IT 自动化引擎,可以使云服务配置、配置管理、应用程序部署、服务内部的编排以及其他许多 IT 操作实现自动化。”使用它的科技公司包括:思科、瞻博网络、Evernote、推特、威瑞信、GoPro、EA Sports、Atlassian 和韦里逊。它既有免费版,也有收费版。 支持的操作系统:Linux 相关网站:http://www.ansibleworks.comChef作为另一款自动化工具,Chef 支持开发运维方法,同时改善了速度、协作和安全性。拥有免费版和收费版。官方网站上显示用户包括:塔吉特(Target)、诺德斯特龙(Nordstrom)、Facebook、Etsy、IGM、雅虎和彭博社。 支持的操作系统:Windows、Linux 和 OS X 相关网站:https://www.chef.io/chef/HudsonHudson 在使用敏捷和开发运维方法的企业当中很流行,它是一种可扩展的持续集成服务器系统,可以监控重复作业的执行。这个项目得到了 Eclipse 基金会、甲骨文、Atlassian 和 YourKit 的支持。 支持的操作系统:与操作系统无关 相关网站:http://hudson-ci.orgPuppetPuppet 号称“使用最广泛的开源 IT 管理系统”,它包括 40 多个基础设施管理方面的开源项目。除了开源版本外,它还有一款收费的企业版本。它声称,用户包括 25000 多家企业,比如迪士尼、沃尔玛、1-800-Flowers.com、Heartland Payment Systems、盖蒂图片社(Getty Images)和 Yelp。 支持的操作系统:Windows、Linux、Unix 和 OS X 相关网站:https://puppetlabs.com/puppet/open-source-projects4.2 附录2:容器服务应用目录 Gartner 应用调研容器服务 APP HUB已标签分类ApplicationSolution CatalogairflowWorkflowbitcoind数字货币bitcoind数字货币cassandra数据库cassandra-operator数据库cassandra-reaper数据库couchdb数据库elasticsearch分析搜索elasticsearch-curator分析搜索elasticsearch-exporter分析搜索elasticsearch-exporter分析搜索etcd数据库etcd-operator数据库grafana分析搜索grafana分析搜索hadoop大数据hadoop大数据IPFSJenkins持续集成jenkins-operator持续集成kafkaInfrastructurekibana分析搜索kibana分析搜索LAMP开发工具logstash分析搜索logstash分析搜索mariadb数据库mariadb数据库mariadb-galera数据库mediawiki内容管理memcachedInfrastructurememcachedInfrastructureMongoDB数据库mongodb数据库moodleeLearningmxnetAIMySQL数据库mysqldump数据库mysqldump数据库mysqlha数据库natsInfrastructurenatsInfrastructureneo4j数据库nginxWeb服务nginx-ingressWeb服务nginx-ingress-controllerWeb服务prometheus分析搜索prometheus-adapter分析搜索prometheus-adapter分析搜索prometheus-blackbox-exporter分析搜索prometheus-blackbox-exporter分析搜索prometheus-cloudwatch-exporter分析搜索prometheus-cloudwatch-exporter分析搜索prometheus-consul-exporter分析搜索prometheus-consul-exporter分析搜索prometheus-couchdb-exporter分析搜索prometheus-couchdb-exporter分析搜索prometheus-mysql-exporter分析搜索prometheus-mysql-exporter分析搜索prometheus-nats-exporter分析搜索prometheus-nats-exporter分析搜索prometheus-node-exporter分析搜索prometheus-node-exporter分析搜索prometheus-postgres-exporter分析搜索prometheus-postgres-exporter分析搜索prometheus-pushgateway分析搜索prometheus-pushgateway分析搜索prometheus-rabbitmq-exporter分析搜索prometheus-rabbitmq-exporter分析搜索prometheus-redis-exporter分析搜索prometheus-redis-exporter分析搜索prometheus-snmp-exporter分析搜索prometheus-snmp-exporter分析搜索prometheus-to-sd分析搜索prometheus-to-sd分析搜索pytorchAIrabbitmqInfrastructurerabbitmqInfrastructurerabbitmq-haInfrastructurerabbitmq-haInfrastructureredis数据库redis数据库redis-cache数据库redis-ha数据库redis-ha数据库spark大数据spark-history-server大数据spark-history-server大数据sparkoperator大数据tensorflow-notebookAItensorflow-resnetAItomcat中间件wordpressWeb服务wordpressWeb服务wildflyInfrastructurezeppelinInfrastructurezookeeperINfrastructure未标签分类aerospikeambassadorambassadorapacheapm-serverapm-serveratlantisatlantisauditbeataws-alb-ingress-controlleraws-cluster-autoscaleraws-iam-authenticatorburrowbuzzfeed-ssocentrifugocerebrocerebrochaoskubechaoskubechartmuseumchronografchronografclamavclamavcluster-autoscalercluster-autoscalercluster-overprovisionercluster-overprovisionercockroachdbcollabora-codecollabora-codeconsulcontourcorednscorednscosbenchcoscalecouchdbdaskdask-distributeddatadogdexdistributed-jmeterdistributed-tensorflowdmarc2logstashdocker-registrydocker-registrydokuwikidokuwikidronedronedrupalefs-provisionerefs-provisionerelastabotelastalertelastalertenvoyetcd-operatorethereumeventroutereventrouterexternal-dnsexternal-dnsfactoriofalcofalcofilebeatfilebeatfluent-bitfluent-bitfluentdfluentdfluentd-cloudwatchgangwaygangwaygce-ingressgcp-night-kingghostgocdgocdgogsgoldfishgoldpingerguestbookguestbook-kruisehaproxy-ingressharborhazelcasthazelcasthazelcast-jethazelcast-jetheapsterheapsterheartbeathelm-exporterhl-composerhlf-couchdbhlf-ordhlf-peerhlf-peerhoardhome-assistanthome-assistanthoneydipperhorovodhoverflyhubothubotigniteinbucketinfluxdbinfluxdbingressmonitorcontrollerinstana-agentinstana-agentjaegerjasperreportsjoomlak8s-spot-reschedulerk8s-spot-termination-handlerk8s-spot-termination-handlerkanister-operatorkapacitorkapacitorkarmakarmakatafygiokeycloak-proxykiamkiamkongkube-downscalerkube-hunterkube-hunterkube-legokube-registry-proxykube-slackkube-slackkube-state-metricskube-state-metricskube2iamkube2iamkubelesskuberhealthykubernetes-dashboardkubernetes-dashboardkubernetes-vaultkuberoskuberoskubewatchkubewatchkuredkuredlinkerdlocustlocustlogdna-agentlogdna-agentmagentomagic-ip-addressmagic-namespacemcroutermercuremetabasemetabasemetallbmetricbeatmetricbeatminecraftminecraftminiominiomsomsmssql-linuxnewrelic-infrastructurenewrelic-infrastructurenextcloudnfs-server-provisionernginx-legonode-problem-detectornode-problem-detectornode-rednode-redoauth-proxyoauth2-proxyoauth2-proxyodooopaopaopencartopenebsopenebsopenibanopenldapopenldapopenvpnopenvpnorangehrmorientdbosclassowncloudpachydermparseparseperconapercona-xtradb-clusterpgadminphabricatorphpbbphpmyadminpomeriumpomeriumpostgresqlpostgresqlpostgresql-haprestashopprestopuppet-forgeredminereloaderreloaderrethinkdbriemannrisk-advisorrookoutrundecksatisfyschema-registry-uisealed-secretssealed-secretsseleniumsematext-agentsentry-kubernetesseqsignalfx-agentsignalsciencessocat-tunnellersonatype-nexussonatype-nexusspartakusspotify-docker-gcstackdriver-exporterstackdriver-exportersuitecrmsupersetsupersetsysdigtelegraftelegrafterracottaterracottatestlinktraefiktraefikunboundunifivaultvaultingkubeverdaccioverdacciowavefrontweave-cloudweave-scopeweave-scopewebpagetest-agentwebpagetest-server4.3 附录3:容器应用调研 Bitnami Multi-Tier Single-Tier 应用调研Multi-Tier Single-Tier 应用调研Single-Tier 架构:适用于单节点server架构。所有服务部署在一台 Server上。Multi -Tier 架构:适用于多节点共享架构。把各个服务分别部署在多个 Server上,比如 web服务器,应用服务器,多实例数据库服务。Multi-Tier 提供多节点的更高性能,高可用,副本数据复制数据保护和数据安全。适用于云上部署 Multi-Tier 多节点 Server 共享架构的应用调研如下:分析搜索GrafanaMulti-Tier Single-Tiergrafana 是一款采用 go 语言编写的开源应用,主要用于大规模指标数据的可视化展现,是网络架构和应用分析中最流行的时序数据展示工具,目前已经支持绝大部分常用的时序数据库。 相关网站:http://docs.grafana.org/ElasticsearchMulti-Tier Single-TierElasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎。 相关网站:https://www.elastic.co/cn/elasticsearch/持续集成部署JenkinsMulti-Tier Single-TierJenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于持续、自动的构建/测试软件项目、监控外部任务的运行。Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。常用的版本控制工具有SVN、GIT,构建工具有Maven、Ant、Gradle。 相关网站:http://www.jenkins.org.cn/deLearningMoodle LMSMulti-Tier Single-Tier开源在线教育学习管理系统。以功能强大,而界面简单、精巧而著称。它是eLearning技术先驱,已成为全球大中学院校建立开放式课程系统的首选软件。 相关网站:https://moodle.com/lms/Web 服务NginxMulti-Tier Single-TierNginx 的人气也极旺,它被互联网上所有网站中的大约四分之一所使用。除了俄罗斯许多访问量很大的网站外,用户还包括网飞和 WordPress.com。 支持的操作系统:Windows、Linux 和 OS X 相关网站:http://nginx.orgWordPressMulti-Tier Single-TierWordPress是一款能让您建立出色网站、博客或应用程序的开源软件。WordPress是使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站。也可以把 WordPress当作一个内容管理系统(CMS)来使用。 相关网站:https://cn.wordpress.org/内容管理DrupalMulti-Tier Single-TierDrupal 声称,98000 多个开发人员在为这个极其流行的内容管理系统积极贡献代码。支持者包括微软、Zend、Fastly 和 New Relic,其内容市场有数百家公司参与其中,它们提供了相关的产品和服务。 支持的操作系统:与操作系统无关 相关网站:https://www.drupal.orgCKANMulti-TierCKAN是开源的Data Management System数据管理系统。 相关网站:https://ckan.org/ https://github.com/ckan/ckanMediaWikiMulti-TierMediaWiki 以维基百科使用的软件而出名,它还为百度、Vistaprint、Novell、英特尔和美国宇航局支持网站。它是构建可编辑网页的不错选择,许多企业组织用它来构建内部知识库。 支持的操作系统:Windows、Linux/Unix 和 OS X 相关网站:https://www.mediawiki.org/wiki/MediaWiki数据库CassandraMulti-Tier Single-Tier这种 NoSQL 数据库由 Facebook 开发,其用户包括苹果、欧洲原子核研究组织(CERN)、康卡斯特、电子港湾、GitHub、GoDaddy、Hulu、Instagram、Intuit、网飞、Reddit 及其他科技公司。它支持极其庞大的数据集,声称拥有非常高的性能和出色的耐用性和弹性。可通过第三方获得支持。 支持的操作系统:与操作系统无关 相关网站:http://cassandra.apache.orgMariaDBMulti-Tier Single-TierMariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。在存储引擎方面,使用XtraDB(英语:XtraDB)来代替MySQL的InnoDB。 相关网站:https://mariadb.org/MongoDBMulti-Tier Single-TierMongoDB 是一种 NoSQL 数据库,声称“针对关键任务型部署环境进行了优化”,用户包括 Foursquare、《福布斯》、Pebble、Adobe、领英、eHarmony 及其他公司。提供收费的专业版和企业版。 支持的操作系统:Windows、Linux、OS X 和 Solaris 相关网站:http://www.mongodb.orgMySQLMulti-Tier Single-TierMySQL 自称是“世界上最流行的开源数据库”,备受众多互联网公司的青睐,比如 YouTube、贝宝、谷歌、Facebook、推特、电子港湾、领英、优步和亚马逊。除了免费社区版外,它还有多款收费版。最新更新版声称速度比老版本快三倍。 支持的操作系统:Windows、Linux、Unix 和 OS X 相关网站:http://www.mysql.comNeo4jMulti-Tier Single-TierNeo4J 自诩为“世界上领先的图形数据库”,用于欺诈检测、推荐引擎、社交网站、主数据管理及更多领域。用户包括电子港湾、沃尔玛、思科、惠普、埃森哲、CrunchBase、eHarmony、Care.com 及另外许多企业组织。 支持的操作系统:Windows 和 Linux 相关网站:http://neo4j.comPostgreSQLMulti-Tier Single-TierPostgreSQL是一个功能非常强大的、源代码开放的客户/服务器关系型数据库管理系统(RDBMS)。PostgreSQL支持大部分的SQL标准并且提供了很多其他现代特性,如复杂查询、外键、触发器、视图、事务完整性、多版本并发控制等。同样,PostgreSQL也可以用许多方法扩展,例如通过增加新的数据类型、函数、操作符、聚集函数、索引方法、过程语言等。 相关网站:https://www.postgresql.org/RedisMulti-Tier Single-TierNoSQL数据库 Redis 是一个开源的内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如字符串(strings),散列(hashes),列表(lists),集合(sets), 有序集合(sorted sets)与范围查询,bitmaps,hyperloglogs 和地理空间索引半径查询。Redis 内置了复制,LUA脚本,LRU驱动事件,事务和不同级别的磁盘持久化, 并通过Redis哨兵和自动分区提供高可用性。 相关网站:https://redis.io/etcdMulti-Tier Single-TierNoSQL数据库 etcd是一个分布式的、高可用的、一致的key-value存储数据库,基于Go语言实现,主要用于共享配置和服务发现 相关网站:https://etcd.io/MariaDB GaleraMulti-Tier相关网站:https://downloads.mariadb.org/mariadb-galera/InfrastructureRabbitMQMulti-Tier Single-TierRabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。 相关网站:https://www.rabbitmq.com/MemcachedMulti-Tier Single-Tiermemcached是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但被许多网站使用。这是一套开放源代码软件,以BSD license授权发布。 相关网站:http://memcached.org/KafkaMulti-Tier Single-TierKafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。 相关网站:http://kafka.apache.org/ZooKeeperMulti-Tier Single-TierZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。 相关网站:https://zookeeper.apache.org/Node.jsMulti-Tier Single-TierNode.js 的成名之处在于,它让开发人员可以使用 JavaScript,编写服务器端应用程序。开发工作之前由 Joyent 管控,现在交由 Node.js 基金会监管。用户包括 IBM、微软、雅虎、SAP、领英、贝宝和网飞。 支持的操作系统:Windows、Linux 和 OS X 相关网站:https://nodejs.org/en/NATSMulti-Tier Single-Tiernats是一个开源的,云原生的消息系统。 核心基于EventMachine开发,原理是基于消息发布订阅机制,每台服务器上的每个模块会根据自己的消息类别向MessageBus发布多个消息主题,而同时也向自己需要交互的模块,按照需要的主题订阅消息。 相关网站:https://nats.io/开发工具LAMPMulti-Tier Single-TierLAMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写。Linux,操作系统,Apache,网页服务器,MariaDB或MySQL,数据库管理系统(或者数据库服务器),PHP、Perl或Python,脚本语言。
Azure OpenAI服务&chatgpt模型
一.什么是 Azure OpenAI 服务?Azure OpenAI 服务允许通过 REST API 访问 OpenAI 的强大语言模型,包括 GPT-3、Codex 和 Embeddings 模型系列。这些模型可以轻松适应特定的任务,包括但不限于内容生成、汇总、语义搜索和自然语言到代码的转换。 用户可以在 Azure OpenAI Studio 中通过 REST API、Python SDK 或基于 Web 的界面访问该服务。1.1 功能概述功能Azure OpenAI可用的模型GPT-3 基本系列
Codex 系列
Embeddings 系列微调Ada
Babbage
Curie
Cushman*
Davinci*
* 当前不可用。 **在美国东部区域,微调目前对新客户不可用。 请使用美国中南部区域进行位于美国的训练虚拟网络支持和专用链接支持是托管标识是,通过 Azure Active DirectoryUI 体验用于帐户和资源管理的 Azure 门户
用于模型探索和微调的 Azure OpenAI Service Studio区域可用性美国东部
美国中南部
西欧内容筛选使用自动化系统根据内容策略评估提示和完成情况。 将筛选高严重性内容。1.2 负责任的 AIMicrosoft 致力于遵照“以人为本”的原则推动 AI 的进步。 生成性模型(例如 Azure OpenAI 中提供的模型)提供显著的潜在优势,但如果不经过精心设计和采用全方位的缓解措施,此类模型有可能会生成错误甚至有害的内容。 Microsoft 已做出大量投资来帮助防范滥用和意外损害,其中包括要求申请人展示妥善定义的用例、融入 Microsoft 的负责任 AI 使用原则、生成内容筛选器以支持客户,并向已加入的新客户提供负责任 AI 实施指导。1.3 如何访问 Azure OpenAI?由于需要应对很高的需求、即将推出的产品改进以及履行 Microsoft 对负责任 AI 做出的承诺,我们目前会限制访问。 当前,我们正在与已经同 Microsoft 建立了合作关系的客户、用例风险较低的客户以及承诺融入缓解措施的客户合作。 除了申请初始访问权限外,所有使用 Azure OpenAI 的解决方案都需要经历用例审查,然后才能发布用于生产用途。一般而言,提交审批的方案的敏感程度越高,风险缓解措施就越重要。1.3 比较 Azure OpenAI 和 OpenAIAzure OpenAI 服务通过 OpenAI GPT-3、Codex 和 DALL-E 模型为客户提供高级语言 AI,并能够实现 Azure 的安全性和企业前景。 Azure OpenAI 与 OpenAI 共同开发 API,确保兼容性的同时能够实现二者之间的平稳过渡。使用 Azure OpenAI,客户可在运行与 OpenAI 相同的模型时获得 Microsoft Azure 的安全功能。 Azure OpenAI 提供专用网络、区域可用性和负责任 AI 内容筛选功能。1.4 关键概念1.4.1 提示和补全补全是 API 服务的核心组件。 此 API 提供对模型的文本输入、文本输出接口的访问。 用户只需提供一个包含英文文本命令的输入提示,模型就会生成文本补全。下面是一个简单的提示和补全的示例:提示:""" count to 5 in a for loop """补全:for i in range(1, 6): print(i)1.4.2 令牌(token)Azure OpenAI 通过将文本分解为标记来处理文本。 标记可以是单词,也可以是字符块。 例如,单词“hamburger”将分解为标记“ham”、“bur”和“ger”,而“pear”之类的常见短单词只是一个单个标记。 许多标记以空格开头,例如“ hello”和“ bye”。给定请求中处理的标记总数取决于输入、输出和请求参数的长度。 处理的标记数量也会影响模型的响应延迟和吞吐量。1.4.3 资源Azure OpenAI 是 Azure 上的一个新产品。 可以像在 Azure 订阅中使用任何其他可用于创建资源或服务实例的 Azure 产品一样开始使用 Azure OpenAI。 1.4.3 部署创建 Azure OpenAI 资源后,必须先部署模型,然后才能开始发出 API 调用和生成文本。 可以使用部署 API 来完成此操作。 这些 API 允许指定要使用的模型。1.4.4 上下文学习Azure OpenAI 使用的模型使用生成调用期间提供的自然语言指令和示例来识别请求的任务和所需的技能。 使用此方法时,提示的第一个部分包括自然语言指令和/或所需特定任务的示例。 然后,模型通过预测概率最高的下一段文本来完成任务。 这种技术称为“上下文”学习。 在此步骤中不会重新训练这些模型,而是根据你在提示中包含的上下文做出预测。上下文学习有三种主要方法:少样本学习、单样本学习和零样本学习。 这些方法根据提供给模型的任务特定数据量而异:少样本学习在这种情况下,用户在调用提示中包含几个示例来演示预期的答案格式和内容。 以下示例显示了几个提示,我们在其中提供了多个示例(模型将生成最后一个答案):Convert the questions to a command:
Q: Ask Constance if we need some bread.
A: send-msg `find constance` Do we need some bread?
Q: Send a message to Greg to figure out if things are ready for Wednesday.
A: send-msg `find greg` Is everything ready for Wednesday?
Q: Ask Ilya if we're still having our meeting this evening.
A: send-msg `find ilya` Are we still having a meeting this evening?
Q: Contact the ski store and figure out if I can get my skis fixed before I leave on Thursday.
A: send-msg `find ski store` Would it be possible to get my skis fixed before I leave on Thursday?
Q: Thank Nicolas for lunch.
A: send-msg `find nicolas` Thank you for lunch!
Q: Tell Constance that I won't be home before 19:30 tonight — unmovable meeting.
A: send-msg `find constance` I won't be home before 19:30 tonight. I have a meeting I can't move.
Q: Tell John that I need to book an appointment at 10:30.
A:示例数量通常为 0 到 100 个,具体取决于单个提示的最大输入长度可以容纳多少个示例。 最大输入长度可能因使用的特定模型而异。 少样本学习可以大大减少准确进行预测所需的任务特定数据量。 此方法的准确度通常不如微调的模型。单样本学习这种情况与少样本学习方法相同,不过只提供了一个示例。零样本学习在这种情况下,未向模型提供任何示例,而只提供了任务请求。1.4.5 模型该服务为用户提供对多种不同模型的访问。 每种模型提供不同的功能和价位。 GPT-3 基础模型按功能降序和速度升序顺序分别称为 Davinci、Curie、Babbage 和 Ada。Codex 系列模型是 GPT-3 的后代,并且已基于自然语言和代码进行训练,可为自然语言到代码用例提供支持。 在模型概念页上详细了解每个模型。二. Azure OpenAI 服务配额和限制2.1 配额和限制参考以下部分提供了适用于 Azure OpenAI 配额和限制的快速指南:限制名称限制值每个区域的 OpenAI 资源2每个模型每分钟的请求数*Davinci 模型(002 及更高版本):120
所有其他模型:300每个模型每分钟的标记数*Davinci 模型(002 及更高版本):40,000
所有其他模型:120,000最大微调模型部署*2能够将同一模型部署到多个部署不允许每个资源的训练作业总数100每个资源同时运行训练作业的最大数目1排队的最大训练作业数20每个资源的最大文件数50每个资源的所有文件的总大小1 GB最大训练作业时间(如果超过,作业将失败)120 小时最大训练作业大小(训练文件中的标记数)×(时期数)Ada:40-M 令牌
Babbage:40-M 令牌
Curie:40-M 令牌
Cushman:40-M 令牌
Davinci:10-M三. Azure OpenAI 服务模型3.1 模型系列通过 Azure OpenAI 可使用很多不同模型,这些模型按系列和功能分组。 模型系列通常按其预期任务关联模型。 下表介绍了 Azure OpenAI 中当前可用的模型系列。 目前并非所有模型都可在所有区域中使用。模型系列说明GPT-3可以理解和生成自然语言的模型系列。Codex可以理解和生成代码(包括将自然语言翻译为代码)的模型系列。嵌入一组可以理解和使用嵌入的模型。 嵌入是一种特殊的数据表示格式,可由机器学习模型和算法轻松使用。 嵌入是一段文本的语义含义的信息密集表示。 目前,我们提供了三个系列的嵌入模型以实现不同的功能:相似性、文本搜索和代码搜索。3.2 模型功能每个模型系列都有一系列模型,这些模型按功能进一步区分。 这些功能通常由名称标识,并且这些名称的字母顺序通常指示给定模型系列中该模型的相对功能和成本。例如,GPT-3 模型使用 Ada、Babbage、Curie 和 Davinci 等名称来指示相对功能和成本。 Davinci 比 Curie 功能更强大(且成本更高),而 Curie 又比 Babbage 功能更强大(且成本更高),依此类推。备注功能较低的模型(如 Ada)可执行的任何任务都可以由功能较高的模型(如 Curie 或 Davinci)执行。3.3 命名约定Azure OpenAI 的模型名称通常对应于以下标准命名约定:{capability}-{family}[-{input-type}]-{identifier}元素说明{capability}模型的功能。 例如,GPT-3 模型使用 text,而 Codex 模型使用 code。{family}模型的相关系列。 例如,GPT-3 模型包括 ada、babbage、curie 和 davinci。{input-type}(仅限嵌入模型)模型支持的嵌入的输入类型。 例如,文本搜索嵌入模型支持 doc 和 query。{identifier}模型的版本标识符。例如,我们最强大的 GPT-3 模型称为 text-davinci-003,而我们最强大的 Codex 模型称为 code-davinci-002。名为 ada、babbage、curie 和 davinci 的旧版 GPT-3 模型不遵循标准命名约定,它们主要用于微调(借助 Azure OpenAI 服务,你可以使用称为微调的过程根据个人数据集定制模型)3.4 查找可用的模型可以使用模型列表 API 获取 Azure OpenAI 资源可用于推理和微调的模型列表。3.5 查找适当的模型建议从模型系列中功能最强大的模型开始,以确认模型功能是否满足你的要求。 然后可以继续使用该模型,也可以迁移到功能和成本较低的模型,围绕此模型的功能进行优化。3.6 GPT-3 模型GPT-3 模型可以理解和生成自然语言。 该服务提供四个模型功能,每个都有不同级别的能力以及适用于不同任务的速度。 Davinci 是功能最强大的模型,而 Ada 是速度最快的模型。 模型排序(按功能从高到低的顺序):text-davinci-003text-curie-001text-babbage-001text-ada-001虽然 Davinci 能力最强,但其他模型提供了显着的速度优势。 我们的建议是让用户在试验时从 Davinci 开始,因为它能产生最佳结果并验证 Azure OpenAI 可以提供的价值。 原型正常工作后,就可以优化模型选择,为应用程序实现最佳延迟/性能平衡。3.6.1 Davinci(达芬奇)Davinci 是功能最强大的模型,可以执行其他模型能够执行的任何任务,并且所用的指令通常更少。 对于需要深入理解内容的应用程序(例如面向特定受众的摘要和创意内容的生成),Davinci 将产生最佳结果。 Davinci 提供的这些增加的功能需要更多计算资源,因此 Davinci 的成本更高,并且 Davinci 不如其他模型快。Davinci 擅长的另一个领域是理解文本的意图。 Davinci 擅长解决多种逻辑问题并解释字符动机。 Davinci 已经能够解决一些涉及因果关系的最具挑战性的 AI 问题。用途:复杂的意图、因果关系、受众摘要3.6.2 Curie(居里)Curie 功能强大,但速度很快。 虽然 Davinci 在分析复杂文本方面更强大,但 Curie 可以执行许多精细化的任务,例如情绪分类和摘要。 Curie 也善于回答问题和执行问答,适合用作常规服务聊天机器人。用途:语言翻译、复杂分类、文本情绪、摘要3.6.3 Babbage(巴贝奇)Babbage 可以执行简单的分类等简单任务。 在语义搜索方面,它的功能也很强大,可对文档与搜索查询的匹配程度进行排名。用途:中等分类、语义搜索分类3.6.4 Ada(艾达)Ada 通常是最快的模型,可以执行的任务有分析文本、地址更正和不需要太多细微差别的某些分类任务等等。 Ada 的性能通常可以通过提供更多上下文来改进。用途:分析文本、简单分类、地址更正、关键字3.7 Codex 模型Codex 模型是基模型 GPT-3 的子代,可以理解和生成代码。 它们的训练数据包含自然语言和来自 GitHub 的数十亿行公开代码。它们最擅长 Python,并且精通十几种语言,包括 C#、JavaScript、Go、Perl、PHP、Ruby、Swift、TypeScript、SQL 和 Shell。 Codex 模型排序(按功能从高到低的顺序):code-davinci-002code-cushman-001Davinci类似于 GPT-3,Davinci 是功能最强大的 Codex 模型,可以执行其他模型能够执行的任何任务,并且所用的指令通常更少。 对于需要深入了解内容的应用程序,Davinci 会生成最佳结果。 更强的功能需要更多计算资源,因此 Davinci 的成本更高,并且不如其他模型快。Cushman(库什曼)Cushman 功能强大,但速度很快。 虽然 Davinci 在分析复杂任务方面更强大,但 Cushman 是能够执行许多代码生成任务的模型。 Cushman 通常也比 Davinci 运行速度更快、成本更低。3.8 嵌入模型(搜索&算法&机器学习)3.8.1 嵌入模型系列嵌入是一种特殊的数据表示格式,可由机器学习模型和算法轻松使用。 嵌入是一段文本的语义含义的信息密集表示。 每个嵌入是浮点数的一个向量,向量空间中两个嵌入之间的距离与原始格式的两个输入之间的语义相似性相关。例如,如果两个文本相似,则它们的向量表示形式也应该相似。每个系列都包含某一功能范围的模型。 以下列表根据模型功能指示服务返回的数字向量长度:Ada:1024 个维度Babbage:2048 个维度Curie:4096 个维度Davinci:12288 个维度Davinci 功能最强,但比其他模型更慢更贵。 Ada 功能最弱,但速度更快且更成本更低。3.8.2 相似性嵌入此类模型擅长捕获两个或更多文本片段之间的语义相似性。用例模型聚类分析、回归、异常情况检测、可视化text-similarity-ada-001
text-similarity-babbage-001
text-similarity-curie-001
text-similarity-davinci-001
文本搜索嵌入此类模型有助于度量长文档是否与短搜索查询相关。 此系列支持两种输入类型:doc(用于嵌入要检索的文档)和 query(用于嵌入搜索查询)。用例模型搜索、上下文相关性、信息检索text-search-ada-doc-001
text-search-ada-query-001
text-search-babbage-doc-001
text-search-babbage-query-001
text-search-curie-doc-001
text-search-curie-query-001
text-search-davinci-doc-001
text-search-davinci-query-001
代码搜索嵌入与文本搜索嵌入模型类似,此系列支持两种输入类型:code(用于嵌入要检索的代码片段)和 text(用于嵌入自然语言搜索查询)。用例模型代码搜索和相关性code-search-ada-code-001
code-search-ada-text-001
code-search-babbage-code-001
code-search-babbage-text-001使用嵌入模型时,请注意其限制和风险。3.9 模型摘要表和区域可用性3.9.1 GPT-3 模型模型 ID支持补全支持嵌入基本模型区域微调区域ada是否空值美国东部2、美国中南部、欧洲西部text-ada-001是否美国东部2、美国中南部、欧洲西部空值babbage是否空值美国东部2、美国中南部、欧洲西部text-babbage-001是否美国东部2、美国中南部、欧洲西部空值curie是否空值美国东部2、美国中南部、欧洲西部text-curie-001是否美国东部2、美国中南部、欧洲西部空值davinci1是否空值美国东部2、美国中南部、欧洲西部text-davinci-001是否美国中南部、欧洲西部空值text-davinci-002是否美国东部、美国中南部、欧洲西部空值text-davinci-003是否美国东部空值text-davinci-fine-tune-0021是否空值美国东部、西欧1 仅能通过请求获取该模型。 目前,我们不接受使用该模型的新请求。
2 由于需求高,美国东部区域的新用户目前无法进行微调。 请使用美国中南部区域进行位于美国的训练。3.9.2 Codex 模型模型 ID支持补全支持嵌入基本模型区域微调区域code-cushman-0011是否美国中南部、欧洲西部美国东部2、美国中南部、欧洲西部code-davinci-002是否美国东部、西欧空值code-davinci-fine-tune-0021是否空值美国东部2、西欧1 仅能通过请求将该模型用于微调。 目前,我们不接受微调该模型的新请求。
2 由于需求高,美国东部区域的新用户目前无法进行微调。 请使用美国中南部区域进行位于美国的训练。3.9.3 嵌入模型模型 ID支持补全支持嵌入基本模型区域微调区域text-ada-embeddings-002否是美国东部、美国中南部、欧洲西部空值text-similarity-ada-001否是美国东部、美国中南部、欧洲西部空值text-similarity-babbage-001否是美国中南部、欧洲西部空值text-similarity-curie-001否是美国东部、美国中南部、欧洲西部空值text-similarity-davinci-001否是美国中南部、欧洲西部空值text-search-ada-doc-001否是美国中南部、欧洲西部空值text-search-ada-query-001、否是美国中南部、欧洲西部空值text-search-babbage-doc-001否是美国中南部、欧洲西部空值text-search-babbage-query-001否是美国中南部、欧洲西部空值text-search-curie-doc-001否是美国中南部、欧洲西部空值text-search-curie-query-001否是美国中南部、欧洲西部空值text-search-davinci-doc-001否是美国中南部、欧洲西部空值text-search-davinci-query-001否是美国中南部、欧洲西部空值code-search-ada-code-001否是美国中南部、欧洲西部空值code-search-ada-text-001否是美国中南部、欧洲西部空值code-search-babbage-code-001否是美国中南部、欧洲西部空值code-search-babbage-text-001否是美国中南部、欧洲西部空值四. 定价详细信息:4.1 Language models模型Per 1,000 tokens标准Text-Ada$0.0004Text-Babbage$0.0005Text-Curie$0.002Text-Davinci$0.02Code-Cushman$0.024Code-Davinci$0.10ChatGPT (gpt-3.5-turbo)$0.0024.2 Image models(图片生成模型)模型Per 100 images标准Dall-E$24.3 Fine-tuned models(微调的模型)模型Per 1,000 tokens标准Text-Ada$0.0004Text-Babbage$0.0005Text-Curie$0.002Text-Davinci$0.02Code-Cushman$0.024模型Training per compute hour标准Text-Ada$20Text-Babbage$22Text-Curie$24Text-Davinci$84Code-Cushman$26模型Hosting per hour标准Text-Ada$0.05Text-Babbage$0.08Text-Curie$0.24Text-Davinci$3Code-Cushman$0.544.4 Embedding models模型Per 1,000 tokens标准Ada$0.0004Babbage$0.005Curie$0.02Davinci$0.20备注本文内容来自微软官方,个人只是做了一些简单的整理和标注,顺便分享给有兴趣的同学。
这些人还是失业了?以ChatGPT为代表的人工智能正在改变职场
自从人工智能技术得以广泛应用以来,职业从业人员的种类也逐渐多样化。近来,各大科技公司在人工智能领域的竞争日趋激烈,在ChatGPT和新必应(New Bing)凭借开放式聊天和更复杂的互联网搜索版本进入公众视野后,当地时间3月21日,谷歌宣布放开聊天机器人Bard的部分访问权限,即日起美国和英国用户可通过bard.google.com网址进入候补名单并访问Bard。在此背景下,外界开始担心以聊天机器人为代表的新一代AI会对一些人类工作产生影响,某些特定的应用场景和行业可能受到更大的影响。据美媒VICE 3月21日报道,ChatGPT的开发公司OpenAI表示 ,80% 的美国劳动者的工作将受到GPT模型的影响。OpenAI称,随着像OpenAI的GPT-4这样的大型语言模型变得更加先进,并且能够更准确地写作、编码和做数学运算,用不了多久,人工智能就会作为一种日常使用的工具进入工作场所,OpenAI认为,绝大多数劳动者的工作将至少有一部分由 GPT 模型自动化。那么,进化到现在的ChatGPT究竟能做什么?能回答问题只要你问,它就能答。而且条理清晰,简洁流畅,表达能力胜过很多人。情绪稳定,不管你怎么怼它,都不生气。有人说,如果它从事服务行业,比如当客服,就太好了。能写文章你给它一个主题,再给一些背景信息,它就能给你写邮件。你可以给它一些数据,让它根据这些材料撰写一份结构清晰的报告。还能帮你想创意、提供不同的好点子,最后形成广告方案。给它一个选题,它也能生成大量内容、风格都不同的文章,可以放在不同的平台上,用来做营销。除了这些,有人还在用它写论文。就连考试,它也能和人类旗鼓相当。GPT-4做美国高考SAT试题,满分800分,能拿到700分。能生成代码它还有一个绝活,生成代码能力非常强。将手绘的页面草图输入GPT-4,只等10秒,系统就能返回一段代码,代码输出就是一个网页。能提炼总结它可以从几万字的文字中提炼和总结文章要点,可以帮助律师处理卷宗。也能对一篇文章进行修改润色。图像自动生成用户只需向系统提供文本提示,人工智能就能帮你生成一组与该提示匹配的图像。微软就曾表示 Bing Image Creator 预览版也将在 Microsoft Edge 中提供,使其成为第一个也是唯一一个集成了人工智能图像生成器的浏览器。......你以为这就是全部了吗?NO NO NO就在3月24日,OpenAI 发布 ChatGPT Plugins (ChatGPT 插件集),它能将 ChatGPT 连接到第三方应用程序。这是 AI 的 App Store时刻,AI 经历了「iPhone」时刻后,如今也有了应用商店。这些插件使 ChatGPT 能够与开发人员定义的 API 进行交互,极大增强 ChatGPT 的功能,适应无数广泛的场景。啥?你不知道这代表什么?那带你简要了解为什么这么重磅:1.ChatGPT 成为了一个 AI 计算平台;2.ChatGPT 轻松成为了一个 App Store;3.ChatGPT for Everthing——万物皆可 ChatGPT;4.自然语言交互:OpenAI 的插件集的插件接入方式非常 GPT,开发者只需要像说话一样写清楚你的插件可以做什么,Chat GPT 就可以理解你的插件怎么调用,非常人性化;此外,现在的ChatGPT还能做到:1.连接最新的互联网,检索实时信息;例如,体育比分、股票价格、最新消息等;2.高效的写程序、调试程序的助手;3.上传个人资料,检索知识库信息;例如,公司文件、个人笔记等;4.代表用户执行工作流;例如,订机票、订餐等;除此之外,来自OpenAI和宾夕法尼亚大学的研究人员认为“80%的美国劳动力至少有10%的任务会受到GPT的影响,20个职业或被ChatGPT接管。”其中包括数据录入员、客户服务代表、校对、律师助理、会计、译员、广告文字撰稿人、市场研究分析师、社交平台运营、行程规划者、电话推销员、虚拟助理、转录员、新闻记者、旅行服务人员、教师、技术支持分析师、电子邮件营销人员、网络版主、招聘人员。ChatGPT还在对话中表示,聊天机器人可以在某些重复性和标准化的任务上替代人类,这可能会导致一些低技能的工作被机器人所取代。与此同时,聊天机器人可以提高许多行业的工作效率,如在客服行业,聊天机器人可以减少客户等待时间,快速响应并解决一些常见的问题。不过,据有关专家预估,随着各大厂商纷纷入局ChatGPT和人工智能赛道,除了以上职业或被ChatGPT接管外,受影响最大的还当属设计领域的创意设计者。就在上周Adobe召开的峰会上,Adobe 除了推出自己的创意生成式 AI 模型集:Adobe Firefly,宣布即将在Photoshop、After Effects、Premiere Pro及其客户体验工具中也引入生成式人工智能工具并解决了使用该技术时最棘手的版权和支付两个法律问题。还在数字体验峰会Adobe Summit上发布了Adobe Experience Cloud的全新生成式AI创新服务,其或将重新定义企业提供客户体验的方式。据了解,在Sensei GenAI的支持下,营销人员和其他客户体验团队将如同多了“一双副手”来帮助他们提高生产力,而无需增加个人工作量。新功能将率先原生整合到Adobe Experience Manager、Adobe Journey Optimizer、Adobe Real Time Customer Data Platform、Customer Journey Analytics和Marketo Engage等应用程序,支持从规划和资产创建到个性化和客户旅程管理等使用情境。团队可完整掌控创意,以确保内容和体验符合品牌风格,而Adobe的洞察将帮助他们了解能够引发客户共鸣的关键。Adobe Firefly为Adobe Experience Cloud的图像生成提供支持另一方面,Adobe也将在Adobe Experience Cloud中直接导入全新创意生成式人工智能模型集Adobe Firefly。这是Adobe第一个模型利用Adobe Stock图像、公开授权内容和版权已过期的公共领域内容进行训练,将聚焦图像和文本效果,用来产生可安全使用的商用内容。在Adobe Firefly中,用户能轻松快速地制作无限版本的内容,以及进行符合品牌形象的反复修改。用户未来还可运用品牌自有的内容训练Firefly,产出体现品牌风格和设计语言的内容。Adobe Experience Manager(AEM)Assets是企业用来管理图像、视频和其他内容数据库的数字资产管理系统。品牌可在其中使用Firefly大大加快内容开发速度,大幅提升效率。配置Adobe Firefly的Adobe Express将直接整合至AEM Assets,让团队能实时修改色彩、对象和场景等元素,同时还能自动针对网页、移动端和电子邮件等渠道产生不同内容。Firefly将有助于加速品牌的内容供应链,支持大规模的个性化。目前 Firefly 已正式对公众开放申请,可体验文字生成图片和图形字体两个功能,之后还将图形变体等新功能,可以说 Firefly 的加入将会对影像后期的工作流程产生变革。此外,文心一言作为百度全新一代知识增强大语言模型,文心大模型家族的新成员,也是深深刺痛着不少就业者的心灵!百度CEO李彦宏展示了文心一言的五大能力:文学创作、商业文案创作、数理逻辑推算、中文理解、多模态生成,可见文心大模型家族的新成员,不仅能够与人对话互动,回答问题,协助创作,高效便捷地帮助人们获取信息、知识和灵感。看到这里,相对对于那些稍有研究的小伙伴们来说,便能够明白,人工智能取代部分人类,已经迫在眉睫了。如果你不信......,那么请你接着往下看:人工智能定取代一些低效率、没用含量、重复性及流水线的工作这是没办法改变的事情,就像达尔文进化论里“物竞天择,适者生存”一个道理。在这里就以设计师行业及人群来说,在我国“设计师已经慢慢变成流水线工人”!国内的很多设计,其实还停留在外观设计,改良设计层面,可以理解为换汤不换药。很多企业主为了节省研发成本,缩短资金回笼周期,一般都会找到设计公司,要求快速的提供设计方案,甚至有些甲方公司会采用竞单的方式来获取方案。而这类所谓的设计方案,一般也只是换壳设计,或者往原产品上增加一两个简单的功能。久而久之,众多企业家逐一效仿,慢慢形成了这种风气,从而直接导致设计师有如流水线工人,在设计过程中忽略了很多产品开发设计必要的流程,只追求在最短的时间内出最多的方案,基本不考虑功能创新,只是单纯做外观设计。同样抱有此类观点的还有清华教授柳冠中,其曾痛斥中国设计弊病:80%的设计师,还干着美工的活。中国设计教育-没有从根本上解决问题中国目前的设计教育并没解决这个问题,别看每年开那么多论坛,大部分讲的还是表面东西。真正深入进去,发现知识结构不对,硬件也没有,老师教的就是做方案。最后用参加竞赛代替教学,竞赛做的是什么?概念。在大部分院校, 学生4年下来,从来没有一个产品是从头做到底的,没有。都是在做表面效果,创意,造型,时尚,漂亮,好看。中国80%以上的设计公司只有电脑,没有工具你看国内遍地都是设计公司,我敢说80%以上的设计公司,只有电脑,没有工具,没有自己的车间,都在电脑前面操作。基于此,对于这些不论是流水线上的工人来说,还是所谓的设计美工来说,是否会被人工智能所淘汰,答案明显是已经呼之欲出,那便是:中国企业所谓的设计师肯定是会被淘汰!反之,那如何才能不被淘汰呢?首先!中国设计要沉淀下来,企业家要重新认识设计沉淀,说的大白话一点,就是学到有用的东西,获得有价值的积累,领悟到生活的真谛,这其实就是成长,成熟的过程。而非所谓的把设计叫“时尚”,时尚是什么?短命鬼。乔布斯再伟大,还是被苹果这样的商业集团控制了。苹果4、4s、5、5s,你换吧。设计不该是这样,设计需要被使用,能用5年就不要用4年。这才是真正的绿色和可持续,不然就是在糟蹋资源。当然,沉淀这个东西,人人都需要。尤其是进入社会,开始工作,接触人际以后。要学会正确解读些社会现象,理解背后深层次的原因,内化成我们自己的思想,成为自己能力的一部分,这样我们就得到了成长。其次,中国设计师要奋发图强,始终坚持提高设计师素养每个设计师都应该在设计不断被商业化的进程中不断学习,提升创新意识,敢于创新勇于创新。而非所谓的“物以类聚 人以群分”。这一点可能也是中国90%设计师的通病。就拿再简单不过的“考证”一事来说,设计师要不要考证就然都能成为热点,成为话题。事实上!设计师是否需要考取证书取决于设计师的领域和行业要求。一些设计领域,如建筑设计和室内设计,需要设计师取得相应的资格证书才能从事该领域的工作。其他设计领域,如平面设计和工业设计,证书通常是可选的,但持有证书可以提高设计师的专业声誉和就业机会。对于需要取得证书的设计领域,通常需要完成相关的学历或培训课程,并通过相关的考试才能获得资格证书。例如,美国的建筑设计师需要通过国家考试(NCARB)才能取得建筑师资格证书。而平面设计师资格证也称为Adobe Photoshop 国际认证(简称:Photoshop 国际认证),是Adobe公司CEO签发的权威国际认证体系,面向设计师、学生、教师及企业技能岗位的国际认证及培训体系。无论你持什么态度,都不能否认证书的作用,有人说,能力比证书更加重要,但在快节奏的现代社会中,没有证书,你可能连展示能力的机会都没有,反过来说,证书也能在侧面展示你的个人能力。总之,作为一名设计师,拥有专业资格证书是非常重要的。无论是在室内设计、平面设计、建筑设计还是工业设计等领域,持有相关的证书可以增强设计师的专业素养和职业竞争力。更何况在现代社会,拥有专业证书已经成为了竞争职场的基本要求。同样的,设计师如果想在行业内立足,不被人工智能所取代,拥有相关的证书必会提高自己的职业竞争力,跳出所谓的流水线、美工怪圈。闻道有先后,术业有专攻,考证考多了,并不是拿到证书就可以了,一定是需要自己多学习,多加强反复的练习,把自己的技能提升,做到精益求精。同样,也要时刻明白:任何时候都是需要靠努力、认真的做一些事情,而不是为了拿证而拿证,我们可以选择更加努力的提升自己,并不是只靠考证这一个途径。......当然,从开放 API 到升级 GPT-4,再到开放插件,短短的几个月里 ChatGPT 以应接不暇的速度,一次又一次地改变了人们使用大语言模型的方式。AI 不仅在不断进化,还是在不断地被人类驯化,从而融入我们的日常生活之中,颠覆每一个人体验,兴奋和焦虑的情绪不断交织。就像 iPhone 重新定义了智能手机一样,ChatGPT 也重新定义了 AI ——从此以后,人人都可以是 AI 的主人。但......也许,还有可能是奴隶!深一度Adobe Certified Professional认证培训体系(简称:Adobe国际认证)是Adobe公司CEO 签发的权威国际认证体系,面向设计师、学生、教师及企业技能岗位的国际认证及培训体系。该体系基于Adobe核心技术及岗位实际应用操作能力的测评体系得到国际ISTE协会的认可,并在全球 148 各国家推广,得到行业专家、企业的认可。