一文带你入门开源(建议收藏)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 系列

说在前面

开源兴起

这里说两句就行,1998年2月8日,上面这位 Bruce Perens 发表著名文章“TheOpen Source Definition”,他也是开源促进会发起人之一,让当时很多的开源爱好者(大多是黑客和程序员)对开源这个东西有了一定清晰的认识。在那之后,更多的人开始关注开源所带来的实用意义。随着OSI等各种开源组织的四处游走,一些具备强大影响力的公司也关注开源运动。首当其冲的就是IBM,它在2001年投入了10亿美元扩大 Linux 的应用;微软也在2002年迫于开源世界的压力,宣布了扩大公开源代码的行动。至此,开源运动已经成为了促进行业普遍关注的文化现象。今天你可能需要算力,网盘软件下载,你通过博客分享自己的经验……而这些,都是开源带来的影响。

上面做下了解就行,著名的全球基友网站-Github,可谓无人不知,无人不晓。越来越多的个人和公司纷纷加入到Github的大家族里面来,给开源尽一份绵薄之力。对于个人来讲,你把自己的项目托管到Github上并不表示你参与了Github开源项目,只能说你开源了自己的项目,可以任别人自由下载。再放到国内移动互联网的发展,大中厂像腾讯,阿里都有不错的著名开源项目,如今正处于上升期,同时国人开源也有自己的基金会。

如何参与开源项目?也许是每个程序员需要认真回答。

下面是正文。我的Github地址:https://github.com/Datalong,有自己的项目也有fork的非常优秀的编程资料、编程笔记和计算机优秀论文资料,有兴趣的可以fork下。

开始前,首先要搞明白你想要做的内容,除了贡献代码以外,bug 的发现、新功能的意见、文档的补充、测试用例的完善,甚至可能是错别字的纠正,这些都是参与开源项目的方式。正如上面所说,一个开放的社区,是不会拒绝任何可以提升项目质量的行为的。

流程

1 fork(复制)此存储库

通过单击此页面顶部的分叉按钮来分叉此存储库。这将在您的帐户中创建此存储库的副本,这个不多解释,单击一下鼠标就能做到的事情。

如果没有 remote, 记得你要用 git remote add 添加上游远程库的地址,否则无法追踪远程库更新的。

2 clone(克隆)代码存储库

接下来将复制后的代码仓库克隆到你的电脑上。点击图示中的绿色按钮,接着点击复制到剪切板按钮(将代码仓库地址复制下来)

随后打开命令行窗口,敲入如下 git 命令:

git clone "刚才复制的 url 链接"

"刚才复制的 url 链接"(去掉双引号)就是复制到你账户名下的代码仓库地址。获取这链接地址的方法请见上一步。

比如:

git clone https://github.com/你的Github用户名/first-contributions.git

'你的 Github 用户名' 指的是你的 Github 用户名。这一步,你将复制到你账户名下的 first-contributions 这个代码仓库克隆到本地电脑上。

3 创建你的(分支)branch

这一步非常重要。GitHub的帮助里没有提到创建主题 branch 的必要性,你当然可以直接在原项目的默认branch(如master)上进行工作,但实际上

如果打算为原项目作贡献,强烈建议你为每个相关主题创建一个单独的branch。

举个例:如果需要修复原项目的一个和 Unicode 编码相关的 issue:

$ git branch fix-unicode-error
$ git checkout fix-unicode-error

再回到本地项目目录上

用下面的命令能在命令行窗口中,把目录切换到 first-contributions

cd first-contributions

接下来使用 git checkout 命令新建一个代码分支

git checkout -b <新分支的名称>

比如:

git checkout -b add-myname

(新分支的名称不一定需要有 add 。但是呢,在新分支的名称加入 add 是一件合理的事情,因为这个分支的目的是将你的名字添加到列表中。)

4 对代码进行修改,而后commit(提交)做的修改

打开 Contributors.md 这个文件,更新文件内容,将你的名字加上去,保存修改。git status 这命令会列出被改动的文件。接着 git add 这命令则可以添加你的改动,就像如下这条命令。

git add Contributors.md

现在就可以使用 git commit 命令 commit 你的修改了。

git commit -m "Add <你的名字> to Contributors list"

<你的名字> 替换成你的用户名

5 把改动 Push(发布)到 GitHub

记得 push 相应的 branch 到GitHub上面。
使用 git push 命令发布代码

git push origin <分支的名称>

<分支的名称> 替换为之前新建的分支名称。

(针对贡献者)rebase还是merge?

从实用的角度来讲,当你在 branch 下工作,想要导入来自上游库的(与你当前的工作不冲突的情况下)更新时,请使用git rebase

比如,(假设上游 branch 为upstream/master

$ git rebase upstream/master fix-unicode-error

或者直接(如果当前 branch 已经是fix-unicode-error):

$ git rebase upstream/master

这将把当前 branch 的开发“base(基础)”推进到一个新的起点,而不会引入多余的commits。

当你在某个branch下工作时,git merge可以用来合并来自其他branch的更新。如果merge的 branch来自远程库,一次merge操作会增加一个额外的commit(“Merge branch 'master' of something”)。如果在一个需要发送Pull Request的branch下面进行这种操作,(俺个人觉得)这不是一种干净的方式。

当你在主线branch(例如master)下进行开发时,git merge可以用来吸收其他开发的branch引入的新特性(包括主项目维护者用来直接merge Pull Requests),很恰当。

6 提出 Pull Request 将你的修改供他人审查

GitHub的界面:左边选择base branch,右边选择head branch

  • base branch:相当于target branch,你希望Pull Request被merge到上游项目的哪个branch里。为什么要叫base branch:base可以理解为你在进行git rebase操作时的那个“base”,也就是你的主题branch所基于的开发base(基础)。
  • head branch:相当于source branch,你希望自己开发库里的哪个branch被用来进行Pull Request(当然也就是你的主题branch)。为什么要叫head branch:参见下面关于head的解释。

注意head与HEAD(大写)的区别:

head:简单点理解,就是指向某个commit对象的一个reference。它可以是一个branch的名称(例如,默认的master),也可以是一个tag的名称。一个库可以同时有任意多个head。

HEAD:当前活动的head。在任意时刻,存在且仅存在一个HEAD。它可以是指向当前branch的head(比如,指向master,假如master是当前branch的话);也可以不指向任何特定的branch(这叫做detached HEAD)。


系统会从你选择的head branch(在这里,是branch)的这个head开始匹配所有不包含在base branch中的commits,然后自动视作你的主题branch相对于base所增加的新特性,放进同一个Pull Request中提交。

前往 Github 你的代码仓库,你会看到一个 Compare & pull request 的按钮。点击该按钮。

接着再点击 Create pull request 按钮,正式提交 pull request。

不久之后,便会把你所有的变化合并到这个项目的主分支。更改合并后,你会收到电子邮件通知。

但是如果你从自己的分支branch(例如fix-unicode-error)推送了一条Pull Request,那么在这条Pull Request被关闭之前,再次向这个branch里push代码,所有的commits都会被自动追加到这个Pull Request后面(不需要再另开Pull Request)。

这个功能尤其有用,比如你最初提交的Pull Request里存在有些问题,项目维护者要求你打回去修改;或者要求你给你的新feature添加一条相应的unit test(单元测试),这种情况简直经常有。只要追加commits到你的这个主题branch中即可。

(针对项目维护者)cherry-pick、format-patch与am

这几条命令主要针对项目的维护者,稍微提一下。

git pull和git merge是GitHub上最常用的merge Pull Requests的方式,在命令行下merge之后,GitHub上面的Pull Request也会相应地自动关闭。

如果贡献者一次提交了多条commits,有些是维护者并不想要的,可以用这几条命令来选择性地手动commit。(这也适用于某些项目不是借助于GitHub的Pull Request,而是通过邮件列表和patch文件来进行协作开发的情形)。

所以在这种情况下,GitHub上面的Pull Request并不能自动关闭,需要维护者手工操作。

7 Pull Request关闭之后

如果是已经被merge后关闭的Pull Request,你可以在页面的最下方找到一个“Delete this branch”的蓝色按钮。

这表明这个branch的历史使命已经完成(fix-unicode-error的commit已经被合并到主项目中),可以安全地从远程库中彻底删除了。

在本地库中亦可删除这个branch:

$ git branch -d fix-unicode-error

反之,如果你的主题branch并没有被merge就被维护者关掉的话,你还可以继续再拿它来开新的Pull Request就会骚扰主项目。

下面是一些可能遇到的名词

组织类

The Community(社区):一个项目经常会有一个围绕着它的社区,这个社区由各个承担不同角色的用户组成。

项目的拥有者:在他们账号中创建项目并拥有它的用户或者组织。

维护者和合作者:主要做项目相关的工作和推动项目发展,通常情况下拥有者和维护者是同一个人,他们拥有仓库的写入权限。

贡献者:发起拉取请求 (pull request) 并且被合并到项目里面的人。

社区成员:对项目非常关心,并且在关于项目的特性以及 pull requests 的讨论中非常活跃的人。

文档类

你可能经常出看到的文件有:

Readme:几乎所有的 Github 项目都包含一个 README.md 文件,readme 文件提供了一些项目的详细信息,包括如何使用,如何构建。有时候也会告诉你如何成为贡献者。

Contributing:项目以及项目的维护者各式各样,所以参与贡献的最佳方式也不尽相同。如果你想成为贡献者的话,那么你要先阅读那些有 CONTRIBUTING 标签的文档。Contributing 文档会详细介绍了项目的维护者希望得到哪些补丁或者是新增的特性。文件里也可以包含需要写哪些测试,代码风格,或者是哪些地方需要增加补丁之类的内容,总之对贡献者很详细。

行动守则:行动守则为参与者的相关行为设定了基本准则,并且帮助促进一个友好而热情的环境。虽然不是每个项目都有行动守则文件,但它的存在表明这是一个欢迎做贡献的项目。

讨论板或邮件列表:有些项目可能为会话主题使用这些通道(例如,“我怎样”或“你认为……怎么样”,而不用 bug 报告或请求之类的)。其它项目为所有会话使用 Issue 追踪器。

同步聊天通道:有些项目为临时会话、协作和快速交流使用聊天通道(比如 Slack 或 IRC)。

License:LICENSE 文件就是这个开源项目的许可证。一个开源项目会告知用户他们可以做什么,不可做什么(比如:使用,修改,重新分发),以及贡献者允许其他人做哪些事。开源许可证有多种,你可以在认识各种开源协议及其关系了解更多关于开源许可证的信息。

Documentation:许多大型项目不会只通过自述文件去引导用户如何使用。在这些项目中你经常可以找到通往其他文件的超链接,或者是在仓库中找到一个叫做 docs 的文件夹.Create an Issue
如果你在使用项目中发现了一个 bug,而且你不知道怎么解决这个 bug。或者使用文档时遇到了麻烦。或者有关于这个项目的问题。你可以创建一个 issue。不管你有什么 bug,你提出 bug 后,会对那些和你有同样 bug 的人提供帮助。

看板(issue board):看板在git届算是一个相对新的概念,因为各平台的定位不同,github上是没有的,gitlab和码云都有,但是对于我们来说并不陌生 = =,而且通过英文名可以直观的看出,就是管理各个issue的工具。有评论称它冲击到了部分jira的业务(哈哈),这我是不信的,不过画面简洁明了,可以作为看板的辅助(与电子看板类似),但由于issue是和项目乃至分支相关的,想认真的维护这个看板,成本会随着项目数量的增多大大提升。

操作类

issue:可以翻译为‘问题’,指的是项目待完成的工作,在开源中应用很多,在码云Gitee上大部分项目中并没有使用。issue在项目中可以承担用户反馈的作用,用户可以在这个地方提出bug反馈与优化建议,用于记录待完成的任务。每个issue可以包含该问题的前因后果,对于不了解项目的人员,整理的好的issue列表也有助于把握项目的优化内容。一般来说,可以包含以下类型:

  • 软件的bug
  • 功能优化建议
  • 待完成的任务

以github上的 appche/dubbo 为例,可以看到一共有340个打开的issue和4658个已关闭的issue。

标签(Label):一般来说,标签是其中最为重要的,系统会提供一些常见的标签如bug、question等,也可以新建自定义的标签名。规范的issue可以考虑设置两个标签,一个表示性质,另一个表示优先级。可以看到,标签的展示是非常明显的,合理使用标签可以大幅提高issue使用和阅读的效率,issue中常见标签(Label)定义自己查。

里程碑(Milestone):它的操作也在issue中,一个里程碑可以包含多个issue,它的概念类似于一个版本号或者说是tag,issue在创建时可以设置其关联的里程碑。码云中可以在下图中找到。可以看到已经有两个issue和它关联,当所有issue被关闭,进度就会显示为100%。一般来说,里程碑的命名以版本号为主,图中的命名是以时间来划分,并不是很建议。

Pull Request(简称PR):如果你能解决这个 bug,或者你能够添加其他的功能。并且知道如何成为贡献者,理解 license,已经签过 Contributor Licence Agreement (CLA) 后,请发起 Pull Request。这样维护人员可以将你的分支与现有分支进行比较,来决定是否合并你的更改。

PR 提交之后,请耐心等待维护者进行 Review。目前一般在一到两个工作日内都会进行 Review,如果当前的 PR 堆积数量较多可能回复会比较慢。代码提交后 CI 会执行我们内部的测试,你需要保证所有的单元测试是可以通过的。期间可能有其它的提交会与当前 PR 冲突,这时需要修复冲突。维护者在 Review 过程中可能会提出一些修改意见。修改完成之后如果 reviewer 认为没问题了,你会收到 LGTM(looks good to me) 的回复。当收到两个及以上的 LGTM 后,该 PR 将会被合并。

wiki(维基):有一个公式, git + markdown = wiki, 虽然不是很准确(因为wiki不只是支持markdown), 但却是很直观的解释了什么是wiki, wiki就是利用git来进行文档管理的一种方法, 就好像我们用git管理代码一样。

Actions:是GitHub的持续集成服务。持续集成由很多操作组成,比如登录远程服务器,发布内容到第三方服务等等,GitHub把这些操作称为actions。更加详细描述看这篇

GitHub还有actions的官方市场。

watch:翻译过来可以称之为观察,点击watch可以看到如下的列表。

默认每一个用户都是处于Not watching的状态,当你选择Watching,表示你以后会关注这个项目的所有动态,以后只要这个项目发生变动,如被别人提交了pull request、被别人发起了issue等等情况了。

你都会在自己的个人通知中心,收到一条通知消息,如果你设置了个人邮箱,那么你的邮箱也可能收到相应的邮件。如下,我 watch 了开源项目android-cn/android-discuss,那么以后任何人只要在这个项目下提交了 issue 或者在 issue 下面有任何留言,我的通知中心就会通知我。如果你配置了邮箱,你还可能会因此不断的收到邮件。如果你不想接受这些通知,那么点击 Not Watching 即可。

topic:也许是 github 自己也发现了检索的问题,现在 github 增加了一个类似的功能,可以给自己给自己的项目设置 topic. 如下图所示。

给自己的项目设置 topic 后,相当于自己给自己的项目设置了一个 tag ,这样可以方便别人搜索。比如要搜索所有 topic 为 Java 的项目,你只需要在 GitHub 搜索时输入 topic Java 然后搜索即可。

自荐feature(专题):首先第一步自然要搞清楚自己本次贡献的内容是什么?通常都是解决某个问题或者是提交一个新的 feature ;前者相对起来更加容易一些。当然这个问题可能是自己使用过程中发现的,也可能是 Issues 列表中待解决的问题。Fork 代码并且 clone 到你本地 通过将项目的地址添加为一个 remote,并且经常从 remote 合并更改来保持你的代码最新,以便在提交你的 pull 请求时,尽可能少的发生冲突。创建 branch 来修改你的代码,目前 TiDB 相关的项目默认的 branch 命名规则是 user/name。例如 disksing/grpc,简单明确,一目了然。

描述清楚你的问题 方便其他人能够复现。或者说明你添加的功能有什么作用,并且清楚描述你做了哪些更改。注意测试 如果项目中包含逻辑修改,那么必须包含相应的测试,在 CI 中会包含测试覆盖率的检测,如果测试覆盖率下降,那么是不可以合并到 master 的。要包含截图 如果您的更改包含 HTML/CSS 中的差异,请添加前后的屏幕截图。将图像拖放到您的 pull request 的正文中。假如涉及到系统环境,比如使用什么版本的浏览器,什么版本的库,什么版本的操作系统等其他你运行环境的介绍都要说明清楚。

详细的错误输出或者日志 使用 Gist 贴出你的错误日志。如果你在 issue 中附带错误日志,请使用 来标记你的日志。以便更好的显示。保持良好的代码风格这意味着使用与你自己的代码风格中不同的缩进,分号或注释,但是使维护者更容易合并,其他人将来更容易理解和维护。

Open Pull Requests:一旦你新增一个 pull request,讨论将围绕你的更改开始。其他贡献者和用户可能会进入讨论,但最终决定是由维护者决定的。你可能会被要求对你的 pull request 进行一些更改,如果是这样,请向你的 branch 添加更多代码并推送它们,它们将自动进入现有的 pull request。如果你的 pull request 被合并,这会非常棒。如果没有被合并,不要灰心。也许你的更改不是项目维护者需要的。或者更改已经存在了。发生这种情况时,我们建议你根据收到的任何反馈来修改代码,并再次提出 pull request。或创建自己的开源项目。

检查你的问题是否已经存在 重复的问题会浪费大家的时间,所以请先搜索打开和已经关闭的问题,来确认你的问题是否已经提交过了,清楚描述你的问题就行。

这里有一个关于提交消息的快速说明。拥有一个创建提交并坚持下去的良好指南可以使使用 Git 和与他人协作变得更加容易。Git 项目提供了一个文档,其中列出了一些创建提交以提交补丁的好技巧——您可以在Documentation/SubmittingPatches文件中的 Git 源代码中阅读它

而代码贡献方面,如果有志于贡献高质量的代码、修复 bug 或贡献新功能,在开始时,可以打开 ISSUE,里面有一些打着 good first issue Label 的 ISSUE,这些 ISSUE 通常会使一些小功能的开发或者 bug 的修复,你可以通过完成这个 ISSUE 来踏出你贡献代码的第一步。当然,在该 ISSUE 中的交流时必不可少的,这样可以帮助你更详细的了解该 ISSUE 要解决的问题,从而在开发中少走弯路。

找项目

我们推荐你从已正在使用的或感兴趣的项目开始。这里有个很棒的地方供你参考:

  • GitHub Explore: 受欢迎和热门的项目。
  • GitHub Stars: 被其他人star过的项目(指的是你自己库的项目)。
  • GitHub Showcases: 一个能搜索相关库的方法。
  • LayerVault News: 前端和设计相关的项目。

如何正确处理issues

帮助开发者如何高效,帮助他人快速赶上进度。假如你遇到一个错误,当你正准备做什么和怎么来修复它。如果你现提出一个新主张,解释为什么你认为它对项目有用(不只是对你!)。

张三: “当我做 Y 时 X 没有发生”

李四:“确实没发生,因为 X 坏了!请修好。”

结论是“事先做好功课”。不懂没关系的,但要表现你已试过了。还有,在求助之前,请你务必查看项目的自述文件、文档、 Issue(开放的或关闭的)、邮件列表,并且在谷歌上搜索过答案。当你证明你在试着学习时,人们会表示赞赏。

张三:“我不确定怎么实现 X。我查过了帮助文档,没找到哪里有提到。”

应该说:“我怎么做 X?”

请求要简短而直接。和发送电子邮件很像,每一个贡献,不管多简单或多有帮助,都需要某个其他人的审查。许多项目收到的请求比能提供帮助的人多。简明一点。这样你会提高某人能帮到你的可能性。

交流要对公众可见。但不要私下联系维护者,除非你需要分享敏感信息(比如安全问题或严重的违反行为)。当你使对话对公众可见时,更多的人能从你的交流中学习并受益。讨论本身也可能是一种贡献。

如果要评论记得@其他人,“@-maintainer 你好!我们在这个 pull request 功能上怎么继续?”

如果是一份电子邮件,可以这样说 “你好,抱歉通过电子邮件麻烦你了,但我不知道你有没有可能审查我的 pull request ”

可以提问(但要耐心!)。每个人在某个时刻都曾是项目的新人,而且即使有经验的贡献者查看新项目时也需要赶上进度。由此类推,即使长期贡献者也并非总是对项目的每个部分都熟悉。对他们表现出与你希望他们对你表现出的同样的需要耐心。

正确示范:“谢谢你研究这个错误。我按你的建议做了。这是输出结果。”

错误示范:“为什么你不能解决我的问题?这不是你的项目吗?”

一定尊重团体的决定。你的想法可能与项目的优先考虑或愿景不同。他们可能提供反馈或决定不执行你的想法。你应该讨论并寻求妥协,而维护者必须花比你更长的时间适应你的决定。如果你不同意他们的方向,你觉得可以致力于你自己的 fork 或启动你自己的项目。

正确示范:“我对你不能支持我的用例感到失望,但既然你已经解释了它只影响一小部分用户,我理解为什么了。谢谢倾听。”

错误示范:“为什么你不支持我的用例?这无法接受!”

最重要的是,要得体。开源由来自世界各地的合作者一起组成。上下文在跨越语言、文化、地理和时区时会丢失。另外,书面交流使得传递语调或心情更困难。假设这些对话的意图都是好的。礼貌的把想法推后,要求更多的上下文,或进一步澄清你的态度,这些都是好的做法。使因特网成为比你发现它时更好的地方。

在做任何事之前,做一个快速的检查,确保你的想法没有在其它地方被讨论过。略读项目的自述文件、 Issue (开放的和关闭的)、邮件列表和 Stack Overflow。你不一定要花几个小时检查一切,但对几个关键词的快速搜索会大有帮助。

如果你在其它地方找不到你的想法,你已经准备好开始行动了。如果项目在 GitHub 上,你多半会通过开启一个 Issue 或使用 pull request 来沟通

有什么区别呢

Issues 就像开启一个会话或讨论

使用 Pull requests 是为了开始致力于一个解决方案

对于不重要的交流,比如一个澄清或操作方式问题,试着在 Stack Overflow、IRC、Slack 上提问,或是其它的聊天通道,如果项目有对应渠道的话

在你开启一个 Issue 或 使用 pull request 以前,你也可以检查项目的贡献文档(通常是一个叫做 CONTRIBUTING 的文件,或者在自述文件里),看看你是否需要把特定的东西包含进去。例如,他们可能要求你遵照一个模版,或是要求你使用测试等等。

如果你想做一个实质的贡献,在着手以前先开一个 Issue 提问。一个有帮助的做法是,在着手进行可能不被接受的工作以前,先对项目观察一段时间(在 GitHub 上,你可以点击“Watch”来获取所有会话的通知),并且了解团体成员。

找一个你经常使用的项目,在 GitHub 上“ Watch”它,阅读每个 Issue 和使用 pull request,你能从中学到很多的。

下期再见

有人问我,这情人节怎么过?扯蛋,

当然一笑而过

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
5月前
|
网络协议 数据处理 数据安全/隐私保护
|
7月前
|
前端开发 Java 数据库连接
35个项目,开源,开源!
35个项目,开源,开源!
796 0
35个项目,开源,开源!
|
JavaScript Linux 编译器
c++开源协程库libgo介绍及使用
c++开源协程库libgo介绍及使用
|
人工智能 自动驾驶
MiniGPT4,开源了!
MiniGPT4,开源了!
357 0
|
人工智能 开发者 Python
模型社区实战训练营首开,开源让代码更有趣!
阿里云开发者学堂联合modelscope社区推出了模型实战系列训练营,培养AI开发者从各种模态的模型选择,只需要懂得python,也可以玩转人工智能模型。
|
弹性计算 Dubbo Java
开源领域服务
开源领域服务
135 0
|
程序员
把自己开源了
用文字或视频记录自己的生活和想法,让我突然有种感觉,像是把自己给“开源”了。
181 0
|
关系型数据库 Linux 程序员
关于开源,你必须知道的: "君子协定"
为什么在一个技术论坛里冒出这篇法律和知识产权相关的分享呢? 因为,开源和自由软件是推动社会技术发展的重要力量,作为一个优秀的程序员,你一定会接触,学习和使用到开源软件,所以是一定要知道开源界最基本的游戏规则的
12541 1
|
Web App开发 测试技术 C#
C#开源汇总
原文:C#开源汇总 商业协作和项目管理平台-TeamLab 网络视频会议软件-VMukti 驰骋工作流程引擎-ccflow 【免费】正则表达式测试工具-Regex-Tester Windows-Phone-7-SDK Excel-读写组件-ExcelLibrary .
5432 0
|
大数据 云计算 Cloud Native

热门文章

最新文章