#新闻拍一拍# 微软庆祝 Windows 95 发布 25 周年

Summary: • Chrome 团队正探索 Rust 与 C++ 的互操作性 • WordPress 创始人称苹果阻止其更新 iOS 版本要求拿三成提成

# #新闻拍一拍# 微软庆祝 Windows 95 发布 25 周年

<img src="content_image/album_202008_25_145509riakb5kibzjtuj7n.jpg" alt="" title="">

#### 微软庆祝 Windows 95 发布 25 周年

这款系统对桌面体验的影响是非常深远的，开始菜单和任务栏概念沿用至今，并且全球有数十亿用户使用。在过去 25 年里，Windows 系统不断更迭进化，已经成为很多人日常工作生活中不可或缺的重要组成。

来源：[cnBeta.COM](https://www.cnbeta.com/articles/tech/1019859.htm "https://www.cnbeta.com/articles/tech/1019859.htm")

>
> 拍一拍：Windows 95 是民用计算机的一个里程碑。
>
>
>

#### Chrome 团队正探索 Rust 与 C++ 的互操作性

现阶段，Chrome 工程师很清楚 C++ 是第一位的，并且“在可以预见的将来仍然是代码库的统治者”。他们认为，若使用 Rust，需要令其与 C++ 相适应，而不是让 C++ 反过来配合 Rust。当前 Chrome 团队所探索的，正是 Rust 能否，以及如何调用 C++ 代码。

来源：[开源中国](https://www.oschina.net/news/118148/chrome-rust-and-c-interoperability "https://www.oschina.net/news/118148/chrome-rust-and-c-interoperability")

>
> 拍一拍：眼看这 Rust 大热，你要不要学呢？
>
>
>

#### WordPress 创始人称苹果阻止其更新 iOS 版本要求拿三成提成

WordPress 的 iOS 版本不包含任何应用内购买选项，而是免费应用，只是让用户通过 iPhone 或 iPad 构建和管理网站。苹果声称，它的 App Store 审核指南要求“跨平台运行的 app 可以允许用户访问他们在其他平台上的相应 app 中或您的网站上获取的内容、订阅或功能，包括多平台游戏中的消耗品，前提是这些项目也在 app 中以 App 内购买项目的形式提供”。事件发酵之后，苹果向 WordPress 道歉，表示不强迫免费应用加入付费选项。

来源：[solidot](https://www.solidot.org/story?sid=65323 "https://www.solidot.org/story?sid=65323")

>
> 拍一拍：吃相难看。
>
>
>


《代码英雄》第一季（6）：揭秘云计算

# 《代码英雄》第一季（6）：揭秘云计算

>
> 代码英雄讲述了开发人员、程序员、黑客、极客和开源反叛者如何彻底改变技术前景的真实史诗。
>
>
>

>
> **什么是《代码英雄》**
>
>
> <ruby> 代码英雄 <rt>  Command Line Heroes </rt></ruby>是世界领先的企业开源软件解决方案供应商红帽（Red Hat）精心制作的原创音频播客，讲述开发人员、程序员、黑客、极客和开源反叛者如何彻底改变技术前景的真实史诗。该音频博客邀请到了谷歌、NASA 等重量级企业的众多技术大牛共同讲述开源、操作系统、容器、DevOps、混合云等发展过程中的动人故事。
>
>
>

<img src="content_image/album_202008_25_222508yes5x5mvu5skiekj.png" alt="" title="">

本文是《[代码英雄](https://www.redhat.com/en/command-line-heroes)》系列播客[第一季（6）：揭秘云计算](https://www.redhat.com/en/command-line-heroes/season-1/crack-the-cloud-open)的[音频](https://dts.podtrac.com/redirect.mp3/audio.simplecast.com/83bb194b.mp3)脚本。

“没有什么云。这只是别人的电脑。”确切地说，还是服务器。大型云提供商提供了一种相对简单的方式来扩展工作负载。但真正的成本是什么？

在本期节目中，我们将讨论云中的战斗，说谁是赢家还很早。Major Hayden、微软的 Bridget Kromhout 等人会帮我们了解这场正在酝酿的风暴，以及它给开源开发者带来的影响。

**Saron Yitbarek**：

Ingrid Burrington 想要走进云的世界。不是真实的“一朵云”哟，而是“云计算”的世界。

**Ingrid Burrington**：

我不知道互联网真正的样子，我也不认为互联网是我想象中的那样，所以我想尝试找出它真实的模样。

**00:00:30 - Saron Yitbarek**：

Ingrid 是一名记者。在她为《<ruby> 大西洋 <rt>  Atlantic </rt></ruby>》撰写的系列报道中，她讲述了自己参观一个数据中心的经历，一个我们网络生活越来越依赖的地方。她在那里并不是走马观花逛一圈，而是浸入式的复杂体验。首先，她要拍照登记，申请访客身份卡。然后，要通过安检站，签署一份保密协议。最后，她才能去看机房。机房基本上就像个仓库，就像超市的那样，但比它大得多。

**00:01:00**：

整个机房看起来有种别样的美，所有的东西都整齐陈列着。一堆光鲜靓丽的服务器上，连接着通往世界各地的光缆，光缆沿着天花板上的轨道整齐布线。正在通讯的光电信号闪烁着点点神秘的蓝光，仿佛粒子加速器一样。但本质上，它是一排排如猛兽般动力强劲的服务器。

**00:01:30**：

数据中心每年消耗的能源比整个英国还要多。这就意味着它会释放惊人的巨大热量，这就是为什么当 Ingrid 环顾四周时……

**Ingrid Burrington**：

对的，我发现这座建筑主要的设计理念，是建造最理想最完美的暖通系统（HAVC）。

**00:02:00 - Saron Yitbarek**：

Ingrid 发现围绕数据中心的一切都强调经济实用，简单说就是一堆主机、一摞风扇、一大块租金便宜的地皮、用很多便宜的用来冷却的工业用水。完全没有“云”这个词本身散发的浪漫，但另一方面，我们的生活、我们的工作以及我们的话语，都在这个服务器的仓库里搏动着。

**00:02:30 - Ingrid Burrington**：

是的，这有点超现实主义。并不是说我就知道那台机器里存有某人的电子邮件，这台机器又存有别的东西，而是我意识到周围有很多看不见的事情正在发生，我能听到服务器的呼呼声和大量运算产生的微小噪声。说来奇怪，我开始对工业充满敬畏……

**00:03:00 - Saron Yitbarek**：

时刻要记住，在我们使用服务的时候，它们的基础，这些建筑都在某个隐蔽的角落嗡嗡运作着。以前，当我们谈论在云上存储东西，或创建应用程序时，我们有时会自欺欺人地认为它就像天上的云，是没有人能触碰的存在。但现实恰恰相反，一旦我们认识到云数据中心真实存在于某地，我们就会开始思考谁拥有着云了。那么是谁在控制这些服务器、线缆和风扇呢？

**00:03:30 - Saron Yitbarek**：

它们是如何改变开发者构建未来的方式的呢？云让我们紧密地连接在一起。

我是 Saron Yitbarek，这里是《代码英雄》，一档由红帽公司推出的原创播客栏目，第六集，揭秘云计算。

**Chris Watterston**：

没有所谓的“云”。那只是别人的电脑。

**00:04:00 - Saron Yitbarek**：

Chris Watterston 是一名设计师，他对围绕云产生的误解很是恼火。这个词模糊了数据中心的形象，就像 Ingrid 参观过的那个一样。当 Chris 把这句口号做成贴纸时，他因此成为了网红。“**没有所谓的‘云’，那只是别人的电脑。**”这句话现在出现在 T 恤、帽衫、咖啡杯、海报、杯垫和许多主题演讲上。

**00:04:30 - Chris Watterston**：

人们完全不理解云是什么，还用的很欢乐又心安。他们可能完全误解了云，不明白他们的数据实际上是穿过铜轴电缆、或者光纤，来到某一个实际上由他人管理和拥有的存储设备。显然，对于一些有需要隐藏的私人内容的人来说，这是相当可怕的隐患。

**00:05:00**：

所以，下次你想把东西扔到云上的时候，想想 Chris 的贴纸吧。想想你到底要扔到哪里去。在 App 上工作也是同样道理，声称 App 跟服务器无关的说法都是骗人的，根本没有无服务器的 App。云就是别人的服务器、别人的电脑。不过云这件事情从某种意义上说，是一种成长。说到成长，在整一季节目里，我们会一直追溯开源的成长与变革。

**00:05:30**：

从最初的自由软件运动到 Linux 的诞生，直至今天，开源工具和方法把我们带到了远离家园的云端。可以打个比方，一个人找房东租房，他需要签合同、搬进去、把房子整理成自己的居所。当开发者寻找云供应商时，他们也在做着同样的事情。这就是我们现在所处的情况，全世界的开发者都在转向各种云上线产品，然后开始明白租赁的真实含义。

**00:06:00**：

严肃地发问一句，为什么我们一开始就急着跳上云端呢？

**Brandon Butler**：

因为开发者不想维护 App 运行所需的设备。

**Saron Yitbarek**：

这位是 Brandon Butler，《<ruby> 网络世界 <rt>  Network World </rt></ruby>》的高级编辑，多年来致力于研究云计算。

**00:06:30 - Brandon Butler**：

开发者想要开发 App，部署 App，并只在乎 App 能不能正常运行。我们已经看到云孕育的，越来越多的服务，例如无服务器计算、功能即服务、容器和容器管理平台，如 Kubernetes。

**Saron Yitbarek**：

顺便打个广告，想了解容器和 Kubernetes，请看我们的[上期节目](/article-12535-1.html)。

**Brandon Butler**：

所有的这些成果都有助于抽象化 App 运行时所需要的底层基础设施。这将是一个可以在未来可预见的持续发展的趋势。

**00:07:00 - Saron Yitbarek**：

云拥有巨大吸引力的部分原因，可以用“超大规模”这个词来解释。通过云为你提供的所有基础设施，你可以根据自己的需求，快速创建和定制自己的服务器。你不再需要购买自己的设备，你只需要租赁你想要的规模的云。Brandon 解释了“超大规模”对初创公司的具体帮助。

**00:07:30 - Brandon Butler**：

使用公有云进行 App 开发的整套模型，对开发者来说是一个巨大的进步。它曾经成就了一系列全新的初创公司，这些初创公司也已经成长为大众都喜欢投资的公司。想想 Netflix 这样的公司，它的大部分后端都运行在亚马逊的以及其他的云上。

**00:08:00 - Brandon Butler**：

这些公司现在如此壮大的原因，正是因为他们在使用云。因此，云对开发者的影响是不可轻视的。云已经成为过去十年，App 开发领域的主要转变。

**Saron Yitbarek**：

Nick Bash 是 Meadowbrook 保险公司的一位系统管理员，他还记得在云计算诞生之前，调整基础设施是多么痛苦的事。

**00:08:30 - Nick Bush**：

以前，有些人想出新项目的点子，我们会说，“这需要硬件支持，而我们没有。”他们会问，“那么我们该怎么办？”我们以前总是受到内存的限制，尤其是运行虚拟机软件，通常是最困难的部分。我们经常需要在任意时间启动虚拟机，但能随时启动的虚拟机数量总是不多。所以我们不得不花很多钱买新处理器、新内存、新硬件，或者花 5000 美元加新的东西。一旦我们从几个不同的供应商得到报价，就得报给管理层，他们要花时间审核。这样，仅仅是购买硬件都需要漫长的过程。

**00:09:00**：

更不要说构建虚拟机，再反复考虑和测试等等。所以其实我的意思是，有了云，我们可以在几个小时内完成以往需要几个月完成的前期工作。让虚拟机运行起来，第二天就交付给其他人。所以这是一个很大的转变。

**00:09:30 - Saron Yitbarek**：

在拓展性、速度和价格这些方面，云计算相当吸引人。还是拿租房作比喻，云就像可以让你免费得到一个管家和司机的服务，你很难对云计算说不。如今市场上有主要的四家壮志雄心的云供应商在开疆拓土。他们都想成为你在云上的“新房东”。但是且慢，每个租过房子的人都知道，租房和买房不一样。你不能自己拆掉一堵墙，或者安装一个新的按摩浴缸，你得通过房东来干这些事。

**00:10:00**：

那么 Brandon Butler 先生，我们使用私有云，在某种程度上会受制于一家独资公司。这会不会对我们不利？

**00:10:30 - Brandon Butler**：

当你使用云供应商的私有云时，你有不同的使用方法：你可以拥抱开源标准和开源平台，并且在云上运行开源软件，即便这是个私有云；你也可以使用不是开源的原生工具，这些工具可能在公有云上有更好的集成。因此，这是终端用户必须考虑的一个重大问题：我是想使用云供应商的原生工具，这些工具可能与这个云供应商提供的服务，以及其他服务更好的集成；还是拥抱开源标准，使用一个开源平台，享受更大的自由度，在自己和其他提供商的平台上也能运行？

**00:11:00 - Saron Yitbarek**：

随着我们所依赖的云技术不断发展，四大云供应商相互竞争，我们作为开发者有了新选择。我们是放弃一些独立性，依靠单一的云供应商来保护我们的工作，还是选择另一条路，在保持独立性的同时最大化云的拓展性?

**00:11:30**：

换句话说，我们能否在租房合同上写明，“房客有权任意处置该房 ，例如拆墙或其他装修”？

**00:12:00**：

那么，放弃一点点独立性又有什么问题呢？如果你是一名开发者，可能没受到什么影响。因为大多数时候都有运维团队在背后监督开发者们小心行事，他们格外留心于具体细节。这位是 Major Hayden，他是 Rackspace 的首席架构师。

**00:12:30 - Major Hayden**：

有些时候，开发者经常发现他们有各种不同的需要，比如某些专门化的存储，或者可能想要一定大小的虚拟机，或者想要一种云供应商未能提供的东西。还有一些东西可能开发者没有第一时间想要，但你认为他们需要的，对这些东西你还要进行成本效益分析。好吧，虽然使用公有云我们有很大的灵活性，但我们到底付出了什么代价？

**Saron Yitbarek**：

Major 指出了另一个问题，这个问题超越了实用性，并且触及了像我这样的开发人员所信奉的核心，那就是开源实践。即使云供应商允许你使用自己的开源工具，但云本身并不是开源的

**00:13:00 - Major Hayden**：

因此，开源对于云来说是一个需要处理的有趣议题，因为有大量的开源技术支持用户去高效地利用公有云，但并不是所有公有云都把它们的基础设施开源了。举个例子，如果你使用亚马逊，你无法知道他们使用的什么技术来构建虚拟机和其他服务。所以，你不可能对这些东西做点调整，或者很难了解幕后的机理和运作方法。

**00:13:30 - Saron Yitbarek**：

如果你听过我们之前[关于 DevOps 的节目](/article-12529-1.html)，你会知道打破开发者和运维之间的壁垒会让我们获益良多。架构师 Major 刚给了我们一些真知灼见，接下来的这位是系统管理员 Nick Bush，他所在的团队正准备向云端迁移。开发者们已经厌倦了每五年一次硬件换代，每个人都喜欢尽可能快地扩展，而 Nick 想指出一些开发者可能没有考虑到的东西。

**00:14:00 - Nick Bush**：

是的。我想说的是，云是存在延迟的。举个例子，就像远在蒙大拿的数据库服务器，对比我在街上用着 10-gig 的网络，本地数据库调用还是会花费更长的时间。要达到低延迟的云内数据库调用还有很长的路要走，还有其他的安全问题，因此我们暂时不需要担心物理上的前提。在本地，我们尚可以控制我们的硬件和其他类似的东西。一旦你进入了云端，你就得考虑连接问题。

**00:14:30**：

我认为，你也得稍微担心一下安全问题，虽然这更多也是一个成本问题。你想要按月租一个云端虚拟机，要求网速快并且带有充足的存储空间。每千兆的传输和存储都是要花钱的，以前我们都是一次性买断一个机器，我们只要买好了一个云端虚拟机，就可以存储和使用。只要余额和储存空间都还足够，我们就不用付更多钱。

**00:15:00 - Saron Yitbarek**：

声明一下，Nick 确实认为此事利大于弊。他只是不想让我们认为这是个完美的系统。如果你的云供应商宕机，而你想在其他云中重新部署应用程序，会发生什么情况？或者，如果在不同事务上使用不同的云能带来价格优势呢？运维人员提出的这些问题都可以被总结于一个词汇下，也就是<ruby> 供应商依赖 <rt>  vender lock-in </rt></ruby>。你可能很熟悉这个词。

**00:15:30**：

供应商锁定的意思是，在别人的服务器上构建业务会让你越来越依赖于他们的平台。你被绑定在这个平台了。可能突然之间，你被迫升级系统、付出更多成本、接受新限制，你变得身不由己。你懂的。

**00:16:00**：

当我们都戴上 DevOps 的帽子时，我们开发者和运维就可以一起工作，面对供应商锁定，对症下药，但当我们沉浸在自己的代码中时，我们有时会忘记观览全局。为什么不找个折中方法，同时在公共和私有云上工作呢？终极解决方案可能是混合云，对于两方而言这都是最佳选择。我给 Bridget Kromhout 打了电话，询问她的看法。她是微软员工中的头号云开发提倡者，对这方面非常了解。

**00:16:30**：

如果我们考虑一种混合的解决方案，既包含一些公有云，也包含一些私有云，这是两者之间的完美平衡吗？对于开发者，这是理想的解决方案吗？如果云是混合的，那么我就能想做什么就做什么，想用什么工具就用什么，同时仍然可以从大型公有云提供商那里获得一些好处。

**00:17:00 - Bridget Kromhout**：

当然是的。举个例子，我有朋友在制造业中从事高性能计算研究工作，他们有各种各样的绝密资料，像 NDA 这样的东西，不适合放在公有云上。于是，他们可能会在自己的数据中心跟这些资料打交道，处理客户数据，或者研究数据，等等，也可能有其他的……

**00:17:30**：

他们也有适合放在公有云上的其他工作资料，不过我想这个问题就……有时也会有这样的问题，公有云是否适合某些工作资料，比如，如果你计划使用 InfiniBand 同步你的不同笔记，你能在公有云中做到什么程度呢?

**Saron Yitbarek**：

但这并不一定是完美的解决方案。Bridget 认为混合云也有自身的弊端。

**00:18:00 - Bridget Kromhout**：

混合云的问题在于，有时，人们欺骗自己，认为他们可以接受一些实际上不工作的东西，所以如果他们之前等待两周来获得一个虚拟机，如果有人经历过一个完整的这样的情况，并且这个虚拟机还不能正常工作的话，就会有一堆的人由于失望而开始和他们的公有云提供商谈论信用卡问题了，然后他们会试着把这些东西粘合在一起，但是还是有数据来源和延迟的问题，我不是很确定，脱同步的数据集有很多出错的方式。我认为，如果你和云服务提供商合作，你可以有一些可用的直接沟通这样你就可以更好地同步数据，这样是很有帮助的。

**00:18:30 - Saron Yitbarek**：

是的。当我们在开源的语境下谈到云的时候，我觉得，作为开发者，可能大多数人，都喜欢开源；如果你还在听我们的播客节目，就更是这样。对吧？你希望一切都是开放的，透明的，还向大众共享代码；但我觉得，当我们谈到云计算，因为它不会给人感觉是代码库，不会让人觉得云本身是个项目，它是环境，是可以用来帮助我们运行代码的东西，开发人员们还会坚持要让它像是传统的项目和代码库一样开源、透明吗？

**Bridget Kromhout**：

我觉得这是一个非常合理的问题，我觉得这可能也会归结到你到底要注目于技术栈的哪一部分。想一想，你对芯片的了解有多少？你又能在何种程度上操控它们？

**Saron Yitbarek**：

是的，这是真的。你说得不错。

**Bridget Kromhout**：

他们坐在那里，他们有硅，他们也有秘密。他们不一定会将后者给你。

**00:19:30 - Saron Yitbarek**

是啊，硅和秘密。顺便说一句，这是个好播客的名字。

**Bridget Kromhout**：

对吧？也许问题不在于是否一切都是开放的，而在于你需要开放的一切是否都是开放的，以及，当服务没有完全按照正确的方式运行时，你的服务提供者是否会对你保持信息透明，因为不该出的错误就是不该出。

**00:20:00 - Saron Yitbarek**：

所以，我得到了 Bridget 作为一个公有云提供商的观点，她提出了一个有趣的观点。开发者在云上的控制需要多细？至于我，我的看法不一样。我不想为了一点公有云的优势而牺牲的是什么呢？比如说，一个应用在公有云上运行，然后，等一下，现在我已经扩大了规模，或者有新的合规要求，我的应用在私有云上更合适。

**00:20:30**：

把应用从一个地方迁移到另一个地方之前，我需要知道它在迁移之后仍能工作。我需要知道它是以原先同样的方式打包，以同样的方式配置。换句话说，我需要知道从一个云跳到另一个云总是可能的。

除此之外，我们还有什么选择？仅仅锁定在一家云提供商？一个甚至可能完全垄断整个行业的供应商？不能选择迁移到另一个环境的话，这就像把一只手绑在背后写代码一样。

**00:21:00**：

所以，我们不想欠下任何一朵云的人情，并且被它困住。我们希望在合适的时候能够在云间跳转。用摇滚传奇<ruby> 皇后乐队 <rt>  Queen </rt></ruby>的名言来说，“我想要挣脱束缚”。我们希望能够获得公有云的绝佳拓展性，但又不放弃使用开源工具和方法所带来的自由。

**00:21:30**：

有个好消息。混合云的建设正在顺利进行中。Mike Ferris，红帽公司的的业务架构副总裁，他给出了一个很好的解释，说明了混合云是如何帮助我们保持开源精神的。

**00:22:00 - Mike Ferris**：

开源是世界上几乎每一个云服务的基础，现在即便不是大多数，也有许多世界上应用程序的基础设施和工具是从这里发展出来的，管理能力，以及人们用于构建、部署应用程序（无论是任务关键型，还是非任务关键型应用程序）的工具都是基于开源的。

**00:22:30**：

混合云的概念和这一点非常兼容，这代表着，我们可以在混合云中处处使用开源工具，也可以最大程度地发挥出基础设施的优势。这是基于以下的一点事实：开源通过其在当今的强大影响力，能够在一定程度上定义下一代的开发模式。

**Saron Yitbarek**：

我认为云计算本身具有开放的意愿。在本季节目中，我们花了很多时间讨论开源的起源。你甚至可以证明，某些版本的混合云是这些相同理想的延伸。

**00:23:00 - Mike Ferris**：

在过去几十年里，开源开发活动的变化是越来越多的人参与进来了，包括像微软、IBM 这样的行业巨头。你知道，举个大公司的例子，他们要么使用开源软件来提供产品，要么构建开源软件并将其回馈给社区，或者两项都参与。

**00:23:30**：

这些来自客户的重要需求通过那些大公司涌入，确实帮助了开源世界的发展，使之从最初设想中 Solaris 和 UNIX 的替代方案，发展为不仅是社区和业余爱好者使用，而且肯定也是部分任务关键型企业使用的基础。

**00:24:00 - Saron Yitbarek**：

开源正在快速成长。现在，我们有机会确保我们记住我们从哪里来。当我们跃上云时，我们可以为自己声明开源的部分，以此来保持云的开放。幸运的是，由于有了 OpenStack® 平台这样的工具，在云之间构建开源桥梁变得更加容易了。Rackspace 的首席架构师 Major Hayden 描述了它的起源。

**00:24:30 - Major Hayden**：

OpenStack® 来自于 Rackspace 和 NASA 的合作：“你看，这是一种构建基础设施的新方式，我们应该公开进行。我们应该得到更多的投入，应该和更多的人交流。我们应该得到更多的用例。” OpenStack® 是一组应用，它能很好地协同创建基础设施，并全面管理基础设施。无论你需要复杂的虚拟机、复杂的网络，还是有奇怪的存储要求，OpenStack® 通常可以满足大部分的要求。

**Saron Yitbarek**：

Major 指的是，加入一些开源知道如何提供的东西：也就是适应性。

**00:25:00 - Major Hayden**：

在我看来，OpenStack® 是一组相互连接的开放源码应用程序，它允许你构建你想要的基础设施。如果它不能建立你想要的，那么你可以进入社区，对它做出改变。我喜欢我去和顾客交谈时他们的反应，他们说，“我们想改变这个。我们想要改变这一切。”我们会说，“嗯，你可以。”

**Saron Yitbarek**：

我们如何确保这样的的适应性被包含在明天的云中呢？就像我们在之前的节目中谈到的许多问题一样，这需要强大的社区。有请 Brandon Butler，《网络世界》的高级编辑。

**00:25:30 - Brandon Butler**：

例如，我们已经看到了云原生计算基金会的成立，这个基金会制定标准，推广应用容器的使用，并创造了 Kubernetes。我们也看到了 OpenStack 基金会的成立，好将 OpenStack® 用户聚集在一起，讨论创建开源基础设施服务云时的最佳实践。

**00:26:00**：

支撑这些开源社区的社群对于开发下一波开源工具，学习如何最好地使用这些开源平台的，以及鼓励公有云厂商接受这些开源标准都非常重要。

**Saron Yitbarek**：

一旦我们开始构建混合云，并使其尽可能地开放，潜力似乎真的无穷无尽。Major，请说。

**00:26:30 - Major Hayden**：

最让我兴奋的是看到更多的东西可以聚集在不同的云之上。例如，OpenStack® 提供了一个很好的基础设施基础层，但是你可以在它之上做很多事情。我想有时候不同的公司会采用 OpenStack®，然后说:“伙计，我现在该怎么办？我的自由程度太高了。我不知道该怎么办。”这就像你有一个装满食物的冰箱，你会想，“啊，我不知道该做什么菜。”

**00:27:00 - Saron Yitbarek**：

我喜欢这个问题。Chris Watterson 告诉我们的可能是对的。

**Chris Watterston**：

没有所谓的“云”，那只是别人的电脑。

**00:27:30 - Saron Yitbarek**：

但故事并未在此结束。我们要与混合云一起跨入下一章。创建混合云应用的关键可能还没有被破解。跨多云管理任务，对于今天的代码英雄们来说将是一项艰巨的任务。会有很多尝试和错误，但这是值得的，因为我们知道的唯一的一件事是，保持开源意味着开发人员总是可以构建他们想要工作的世界。这种灵活性正是紧紧抓住开源最擅长的叛逆精神的诀窍。

**00:28:00**：

下一集是我们本季的最后一集，我们将以一种让你惊讶的方式，从宏观角度来看开源作为一种全球现象是什么样的。我们也将展望开源的未来，我们的开发人员如何保持像 Linus Torvalds 这样的英雄的精神，即使当他们正在重塑他们的行业时。

**00:28:30**：

《代码英雄》是一档红帽公司推出的原创播客。想了解更多关于本期和往期节目的信息，请访问 [RedHat.com/CommandLineHeroes](http://RedHat.com/CommandLineHeroes) 。在那里你也可以注册我们的新闻通讯。想免费获得新一期节目推送，请务必订阅我们。只要在苹果播客、Spotify、Google Play、CastBox 和其他播客平台中搜索《代码英雄》，然后点击订阅，你就可以第一时间收听新一期。我是 Saron Yitbarek。感谢你的聆听，编程不止。

>
> OpenStack® 和 OpenStack 标志是 OpenStack 基金会在美国和其他国家的注册商标/服务标志或商标/服务标志，并经 OpenStack 基金会许可使用。我们不是 OpenStack 基金会或 OpenStack 社区的附属机构，也没有得到 OpenStack 基金会或 OpenStack 社区的认可或赞助。
>
>
>

>
> **什么是 LCTT SIG 和 LCTT LCRH SIG**
>
>
> LCTT SIG 是 LCTT <ruby> 特别兴趣小组 <rt>  Special Interest Group </rt></ruby>，LCTT SIG 是针对特定领域、特定内容的翻译小组，翻译组成员将遵循 LCTT 流程和规范，参与翻译，并获得相应的奖励。LCRH SIG 是 LCTT 联合红帽（Red Hat）发起的 SIG，当前专注任务是《代码英雄》系列播客的脚本汉化，已有数十位贡献者加入。敬请每周三、周五期待经过我们精心翻译、校对和发布的译文。
>
>
> 欢迎[加入 LCRH SIG](/article-12436-1.html) 一同参与贡献，并领取红帽（Red Hat）和我们联合颁发的专属贡献者证书。
>
>
>

---

via: <https://www.redhat.com/en/command-line-heroes/season-1/crack-the-cloud-open>

作者：[Red Hat](https://www.redhat.com/en/command-line-heroes) 选题：[bestony](https://github.com/bestony) 译者：[LikChung](https://github.com/likchung) 校对：[acyanbird](https://github.com/acyanbird)

本文由 [LCRH](https://github.com/LCTT/LCRH) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


微软利用 AI 提升服务器部件的重复使用和回收率

Summary: 准备好在提到数据中心设备时，听到更多的“循环”一词。

准备好在提到数据中心设备时，听到更多的“循环”一词。

# 微软利用 AI 提升服务器部件的重复使用和回收率

>
> 准备好在提到数据中心设备时，听到更多的“循环”一词。
>
>
>

<img src="content_image/album_202008_25_234108f8yz3c3la8xw18mn.jpg" alt="" title="">

微软正在将人工智能引入到对数百万台服务器进行分类的任务中，以确定哪些部件可以回收，在哪里回收。

新计划要求在微软全球各地的数据中心建立所谓的“<ruby> 循环中心 <rt>  Circular Center </rt></ruby>”，在那里，人工智能算法将用于从退役的服务器或其他硬件中分拣零件，并找出哪些零件可以在园区内重新使用。

微软表示，它的数据中心有超过 300 万台服务器和相关硬件，一台服务器的平均寿命约为 5 年。另外，微软正在全球范围内扩张，所以其服务器数量应该会增加。

循环中心就是要快速整理库存，而不是让过度劳累的员工疲于奔命。微软计划到 2025 年将服务器部件的重复使用率提高 90%。微软总裁 Brad Smith 在宣布这一举措的一篇[博客](https://blogs.microsoft.com/blog/2020/08/04/microsoft-direct-operations-products-and-packaging-to-be-zero-waste-by-2030/)中写道：“利用机器学习，我们将对退役的服务器和硬件进行现场处理。我们会将那些可以被我们以及客户重复使用和再利用的部件进行分类，或者出售。”

Smith 指出，如今，关于废物的数量、质量和类型，以及废物的产生地和去向，都没有一致的数据。例如，关于建造和拆除废物的数据并不一致，我们要一个标准化的方法，有更好的透明度和更高的质量。

他写道：“如果没有更准确的数据，几乎不可能了解运营决策的影响，设定什么目标，如何评估进展，以及废物去向方法的行业标准。”

根据微软的说法，阿姆斯特丹数据中心的一个循环中心试点减少了停机时间，并增加了服务器和网络部件的可用性，供其自身再利用和供应商回购。它还降低了将服务器和硬件运输到处理设施的成本，从而降低了碳排放。

“<ruby> 循环经济 <rt>  circular economy </rt></ruby>”一词正在科技界流行。它是基于服务器硬件的循环利用，将那些已经使用了几年但仍可用的设备重新投入到其他地方服务。ITRenew 是[我在几个月前介绍过](https://www.networkworld.com/article/3543810/for-sale-used-low-mileage-hyperscaler-servers.html)的一家二手超大规模服务器的转售商，它对这个词很感兴趣。

该公司表示，首批微软循环中心将建在新的主要数据中心园区或地区。它计划最终将这些中心添加到已经存在的园区中。

微软曾明确表示要在 2030 年之前实现“碳负排放”，而这只是其中几个项目之一。近日，微软宣布在其位于盐湖城的系统开发者实验室进行了一项测试，用一套 250kW 的氢燃料电池系统为一排服务器机架连续供电 48 小时，微软表示这是以前从未做过的事情。

微软首席基础设施工程师 Mark Monroe 在一篇[博客](https://news.microsoft.com/innovation-stories/hydrogen-datacenters/)中写道：“这是我们所知道的最大的以氢气运行的计算机备用电源系统，而且它的连续测试时间最长。”他说，近年来氢燃料电池的价格大幅下降，现在已经成为柴油发电机的可行替代品，但燃烧更清洁。

---

via: <https://www.networkworld.com/article/3570451/microsoft-uses-ai-to-boost-its-reuse-recycling-of-server-parts.html>

作者：[Andy Patrizio](https://www.networkworld.com/author/Andy-Patrizio/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Summary: • 基于浏览器的加密劫持在 2020 年第二季度活动量突然激增 • 游戏商 Epic 起诉苹果垄断初审，法院裁决“各打五十”

# #新闻拍一拍# 微软逐渐将经典版 Edge 的诸多优秀特性迁移到新版 Edge 浏览器中

<img src="content_image/album_202008_26_083734akxr8jv2c8rhapsc.jpg" alt="" title="">

#### 微软逐渐将经典版 Edge 的诸多优秀特性迁移到新版 Edge 浏览器中

Media Foundation 是随 Windows Vista 引入的底层多媒体技术，微软已经确定该技术即将引入到新版 Edge 中。零拷贝视频捕捉是基于它的功能，在 Windows 10 系统上可以利用 GPU 内存缓冲区减少过多的电力消耗。

来源：[cnBeta.COM](https://www.cnbeta.com/articles/tech/1020375.htm "https://www.cnbeta.com/articles/tech/1020375.htm")

>
> 拍一拍：所以，Edge 当时到底失败在哪里？
>
>
>

#### 基于浏览器的加密劫持在 2020 年第二季度活动量突然激增

基于浏览器的加密货币挖矿，也就是所谓的加密劫持，在今年早些时候，也就是 6 月份，出人意料地卷土重来。赛门铁克表示，与前几个季度相比，加密劫持的检测次数增加了 163%。加密劫持检测量的突然激增很可能是由路由器僵尸网络引起的。但预计不会全面卷土重来。大多数过去尝试过加密劫持行动的网络犯罪集团通常在几周后就放弃了。

来源：[zdnet](https://www.zdnet.com/article/browser-based-cryptojacking-sees-sudden-spike-in-activity-in-q2-2020/ "https://www.zdnet.com/article/browser-based-cryptojacking-sees-sudden-spike-in-activity-in-q2-2020/")

>
> 拍一拍：这主要是因为最近加密货币又重新热起来了。
>
>
>

#### 游戏商 Epic 起诉苹果垄断初审，法院裁决“各打五十”

法庭裁定苹果公司不得关闭游戏开发商 Epic Games 公司的开发者账户且立即生效，同时裁定苹果无需让《堡垒之夜》重回应用商店。裁决中写道：“Epic Games 和苹果公司完全可以相互起诉对方，但他们的纠纷不应该对旁观者造成影响。”

来源：[网易科技](https://tech.163.com/20/0826/07/FKUKD35C00097U7T.html "https://tech.163.com/20/0826/07/FKUKD35C00097U7T.html")

>
> 拍一拍：“你们继续打，别影响 Unreal 引擎就行。”
>
>
>


在 Linux 上创建并调试转储文件

Summary: 了解如何处理转储文件将帮你找到应用中难以重现的 bug。

了解如何处理转储文件将帮你找到应用中难以重现的 bug。

# 在 Linux 上创建并调试转储文件

>
> 了解如何处理转储文件将帮你找到应用中难以重现的 bug。
>
>
>

崩溃转储、内存转储、核心转储、系统转储……这些全都会产生同样的产物：一个包含了当应用崩溃时，在那个特定时刻应用的内存状态的文件。

这是一篇指导文章，你可以通过克隆示例的应用仓库来跟随学习：

```
git clone https://github.com/hANSIc99/core_dump_example.git

```

### 信号如何关联到转储

信号是操作系统和用户应用之间的进程间通讯。Linux 使用 [POSIX 标准](https://en.wikipedia.org/wiki/POSIX)中定义的信号。在你的系统上，你可以在 `/usr/include/bits/signum-generic.h` 找到标准信号的定义。如果你想知道更多关于在你的应用程序中使用信号的信息，这有一个信息丰富的 [signal 手册页](https://man7.org/linux/man-pages/man7/signal.7.html)。简单地说，Linux 基于预期的或意外的信号来触发进一步的活动。

当你退出一个正在运行的应用程序时，应用程序通常会收到 `SIGTERM` 信号。因为这种类型的退出信号是预期的，所以这个操作不会创建一个内存转储。

以下信号将导致创建一个转储文件（来源：[GNU C库](https://www.gnu.org/software/libc/manual/html_node/Program-Error-Signals.html#Program-Error-Signals)）:

* `SIGFPE`：错误的算术操作
* `SIGILL`：非法指令
* `SIGSEGV`：对存储的无效访问
* `SIGBUS`：总线错误
* `SIGABRT`：程序检测到的错误，并通过调用 `abort()` 来报告
* `SIGIOT`：这个信号在 Fedora 上已经过时，过去在 [PDP-11](https://en.wikipedia.org/wiki/PDP-11) 上用 `abort()` 时触发，现在映射到 SIGABRT

### 创建转储文件

导航到 `core_dump_example` 目录，运行 `make`，并使用 `-c1` 开关执行该示例二进制：

```
./coredump -c1

```

该应用将以状态 4 退出，带有如下错误：

“Abgebrochen (Speicherabzug geschrieben) ”（LCTT 译注：这是德语，应该是因为本文作者系统是德语环境）大致翻译为“分段故障（核心转储）”。

是否创建核心转储是由运行该进程的用户的资源限制决定的。你可以用 `ulimit` 命令修改资源限制。

检查当前创建核心转储的设置：

```
ulimit -c

```

如果它输出 `unlimited`，那么它使用的是（建议的）默认值。否则，用以下方法纠正限制：

```
ulimit -c unlimited

```

要禁用创建核心转储，可以设置其大小为 0：

```
ulimit -c 0

```

这个数字指定了核心转储文件的大小，单位是块。

### 什么是核心转储？

内核处理核心转储的方式定义在：

```
/proc/sys/kernel/core_pattern

```

我运行的是 Fedora 31，在我的系统上，该文件包含的内容是：

```
/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h

```

这表明核心转储被转发到 `systemd-coredump` 工具。在不同的 Linux 发行版中，`core_pattern` 的内容会有很大的不同。当使用 `systemd-coredump` 时，转储文件被压缩保存在 `/var/lib/systemd/coredump` 下。你不需要直接接触这些文件，你可以使用 `coredumpctl`。比如说：

```
coredumpctl list

```

会显示系统中保存的所有可用的转储文件。

使用 `coredumpctl dump`，你可以从最后保存的转储文件中检索信息：

```
[stephan@localhost core_dump_example]$ ./coredump
Application started…

(…….)

Message: Process 4598 (coredump) of user 1000 dumped core.

Stack trace of thread 4598:
#0 0x00007f4bbaf22625 __GI_raise (libc.so.6)
#1 0x00007f4bbaf0b8d9 __GI_abort (libc.so.6)
#2 0x00007f4bbaf664af __libc_message (libc.so.6)
#3 0x00007f4bbaf6da9c malloc_printerr (libc.so.6)
#4 0x00007f4bbaf6f49c _int_free (libc.so.6)
#5 0x000000000040120e n/a (/home/stephan/Dokumente/core_dump_example/coredump)
#6 0x00000000004013b1 n/a (/home/stephan/Dokumente/core_dump_example/coredump)
#7 0x00007f4bbaf0d1a3 __libc_start_main (libc.so.6)
#8 0x000000000040113e n/a (/home/stephan/Dokumente/core_dump_example/coredump)
Refusing to dump core to tty (use shell redirection or specify — output).

```

这表明该进程被 `SIGABRT` 停止。这个视图中的堆栈跟踪不是很详细，因为它不包括函数名。然而，使用 `coredumpctl debug`，你可以简单地用调试器（默认为 [GDB](https://www.gnu.org/software/gdb/)）打开转储文件。输入 `bt`（<ruby> 回溯 <rt>  backtrace </rt></ruby>的缩写）可以得到更详细的视图：

```
Core was generated by `./coredump -c1'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50  return ret;
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007fc37a9aa8d9 in __GI_abort () at abort.c:79
#2  0x00007fc37aa054af in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7fc37ab14f4b "%s\n") at ../sysdeps/posix/libc_fatal.c:181
#3  0x00007fc37aa0ca9c in malloc_printerr (str=str@entry=0x7fc37ab130e0 "free(): invalid pointer") at malloc.c:5339
#4  0x00007fc37aa0e49c in _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:4173
#5  0x000000000040120e in freeSomething(void*) ()
#6  0x0000000000401401 in main ()

```

与后续帧相比，`main()` 和 `freeSomething()` 的内存地址相当低。由于共享对象被映射到虚拟地址空间末尾的区域，可以认为 `SIGABRT` 是由共享库中的调用引起的。共享对象的内存地址在多次调用之间并不是恒定不变的，所以当你看到多次调用之间的地址不同时，完全可以认为是共享对象。

堆栈跟踪显示，后续的调用源于 `malloc.c`，这说明内存的（取消）分配可能出了问题。

在源代码中，（即使没有任何 C++ 知识）你也可以看到，它试图释放一个指针，而这个指针并没有被内存管理函数返回。这导致了未定义的行为，并导致了 `SIGABRT`。

```
void freeSomething(void *ptr){
    free(ptr);
}
int nTmp = 5;
int *ptrNull = &nTmp;
freeSomething(ptrNull);

```

systemd 的这个 `coredump` 工具可以在 `/etc/systemd/coredump.conf` 中配置。可以在 `/etc/systemd/systemd-tmpfiles-clean.timer` 中配置轮换清理转储文件。

你可以在其[手册页](https://man7.org/linux/man-pages/man1/coredumpctl.1.html)中找到更多关于 `coredumpctl` 的信息。

### 用调试符号编译

打开 `Makefile` 并注释掉第 9 行的最后一部分。现在应该是这样的：

```
CFLAGS =-Wall -Werror -std=c++11 -g

```

`-g` 开关使编译器能够创建调试信息。启动应用程序，这次使用 `-c2` 开关。

```
./coredump -c2

```

你会得到一个浮点异常。在 GDB 中打开该转储文件：

```
coredumpctl debug

```

这一次，你会直接被指向源代码中导致错误的那一行：

```
Reading symbols from /home/stephan/Dokumente/core_dump_example/coredump…
[New LWP 6218]
Core was generated by `./coredump -c2'.
Program terminated with signal SIGFPE, Arithmetic exception.
#0 0x0000000000401233 in zeroDivide () at main.cpp:29
29 nRes = 5 / nDivider;
(gdb)

```

键入 `list` 以获得更好的源代码概览：

```
(gdb) list
24      int zeroDivide(){
25          int nDivider = 5;
26          int nRes = 0;
27          while(nDivider > 0){
28              nDivider--;
29              nRes = 5 / nDivider;
30          }
31          return nRes;
32      }

```

使用命令 `info locals` 从应用程序失败的时间点检索局部变量的值：

```
(gdb) info locals
nDivider = 0
nRes = 5

```

结合源码，可以看出，你遇到的是零除错误：

```
nRes = 5 / 0

```

### 结论

了解如何处理转储文件将帮助你找到并修复应用程序中难以重现的随机错误。而如果不是你的应用程序，将核心转储转发给开发人员将帮助她或他找到并修复问题。

---

via: <https://opensource.com/article/20/8/linux-dump>

作者：[Stephan Avenwedde](https://opensource.com/users/hansic99) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


一个用 Java 实现的超轻量级 RESTful Web 服务示例

Summary: 通过管理一套图书的完整代码示例，来探索轻量级的 RESTful 服务。

通过管理一套图书的完整代码示例，来探索轻量级的 RESTful 服务。

# 一个用 Java 实现的超轻量级 RESTful Web 服务示例

>
> 通过管理一套图书的完整代码示例，来探索轻量级的 RESTful 服务。
>
>
>

<img src="content_image/album_202008_27_071808tt9zlno3b6lmbgl8.jpg" alt="" title="">

Web 服务，以这样或那样的形式，已经存在了近二十年。比如，[XML-RPC 服务](http://xmlrpc.com/)出现在 90 年代后期，紧接着是用 SOAP 分支编写的服务。在 XML-RPC 和 SOAP 这两个开拓者之后出现后不久，REST 架构风格的服务在大约 20 年前也出现了。[REST](https://www.redhat.com/en/topics/integration/whats-the-difference-between-soap-rest) 风格（以下简称 Restful）服务现在主导了流行的网站，比如 eBay、Facebook 和 Twitter。尽管分布式计算的 Web 服务有很多替代品（如 Web 套接字、微服务和远程过程调用的新框架），但基于 Restful 的 Web 服务依然具有吸引力，原因如下：

* Restful 服务建立在现有的基础设施和协议上，特别是 Web 服务器和 HTTP/HTTPS 协议。一个拥有基于 HTML 的网站的组织可以很容易地为客户添加 Web 服务，这些客户对数据和底层功能更感兴趣，而不是对 HTML 的表现形式感兴趣。比如，亚马逊就率先通过网站和 Web 服务（基于 SOAP 或 Restful）提供相同的信息和功能。
* Restful 服务将 HTTP 当作 API，因此避免了复杂的软件分层，这种分层是基于 SOAP 的 Web 服务的明显特征。比如，Restful API 支持通过 HTTP 命令（POST-GET-PUT-DELETE）进行标准的 CRUD（增加-读取-更新-删除）操作；通过 HTTP 状态码可以知道请求是否成功或者为什么失败。
* Restful Web 服务可以根据需要变得简单或复杂。Restful 是一种风格，实际上是一种非常灵活的风格，而不是一套关于如何设计和构造服务的规定。（伴随而来的缺点是，可能很难确定哪些服务不能算作 Restful 服务。）
* 作为使用者或者客户端，Restful Web 服务与语言和平台无关。客户端发送 HTTP(S) 请求，并以适合现代数据交换的格式（如 JSON）接收文本响应。
* 几乎每一种通用编程语言都至少对 HTTP/HTTPS 有足够的（通常是强大的）支持，这意味着 Web 服务的客户端可以用这些语言来编写。

这篇文章将通过一段完整的 Java 代码示例来探讨轻量级的 Restful 服务。

### 基于 Restful 的“小说” Web 服务

基于 Restful 的“小说” web 服务包含三个程序员定义的类：

* `Novel` 类代表一个小说，只有三个属性：机器生成的 ID、作者和标题。属性可以根据实际情况进行扩展，但我还是想让这个例子看上去更简单一些。
* `Novels` 类包含了用于各种任务的工具类：将一个 `Novel` 或者它们的列表的纯文本编码转换成 XML 或者 JSON；支持在小说集合上进行 CRUD 操作；以及从存储在文件中的数据初始化集合。`Novels` 类在 `Novel` 实例和 servlet 之间起中介作用。
* `NovelsServlet` 类是从 `HttpServlet` 中继承的，`HttpServlet` 是一段健壮且灵活的代码，自 90 年代末的早期企业级 Java 就已经存在了。对于客户端的 CRUD 请求，servlet 可以当作 HTTP 的端点。 servlet 代码主要用于处理客户端的请求和生成相应的响应，而将复杂的细节留给 `Novels` 类中的工具类进行处理。

一些 Java 框架，比如 Jersey（JAX-RS）和 Restlet，就是为 Restful 服务设计的。尽管如此，`HttpServlet` 本身为完成这些服务提供了轻量、灵活、强大且充分测试过的 API。我会通过下面的“小说”例子来说明。

### 部署“小说” Web 服务

当然，部署“小说” Web 服务需要一个 Web 服务器。我的选择是 [Tomcat](http://tomcat.apache.org/)，但是如果该服务托管在 Jetty 或者甚至是 Java 应用服务器上，那么这个服务应该至少可以工作（著名的最后一句话！）。[在我的网站上](https://condor.depaul.edu/mkalin)有总结了如何安装 Tomcat 的 README 文件和代码。还有一个附带文档的 Apache Ant 脚本，可以用来构建“小说”服务（或者任何其他服务或网站），并且将它部署在 Tomcat 或相同的服务。

Tomcat 可以从它的[官网](https://tomcat.apache.org/download-90.cgi)上下载。当你在本地安装后，将 `TOMCAT_HOME` 设置为安装目录。有两个子目录值得关注：

* `TOMCAT_HOME/bin` 目录包含了类 Unix 系统（`startup.sh` 和 `shutdown.sh`）和 Windows（`startup.bat` 和 `shutdown.bat`） 的启动和停止脚本。Tomcat 作为 Java 应用程序运行。Web 服务器的 servlet 容器叫做 Catalina。（在 Jetty 中，Web 服务器和容器的名字一样。）当 Tomcat 启动后，在浏览器中输入 `http://localhost:8080/`可以查看详细文档，包括示例。
* `TOMCAT_HOME/webapps` 目录是已部署的 Web 网站和服务的默认目录。部署网站或 Web 服务的直接方法是复制以 `.war` 结尾的 JAR 文件（也就是 WAR 文件）到 `TOMCAT_HOME/webapps` 或它的子目录下。然后 Tomcat 会将 WAR 文件解压到它自己的目录下。比如，Tomcat 会将 `novels.war` 文件解压到一个叫做 `novels` 的子目录下，并且保留 `novels.war` 文件。一个网站或 Web 服务可以通过删除 WAR 文件进行移除，也可以用一个新版 WAR 文件来覆盖已有文件进行更新。顺便说一下，调试网站或服务的第一步就是检查 Tomcat 已经正确解压 WAR 文件；如果没有的话，网站或服务就无法发布，因为代码或配置中有致命错误。
* 因为 Tomcat 默认会监听 8080 端口上的 HTTP 请求，所以本机上的 URL 请求以 `http://localhost:8080/` 开始。

通过添加不带 `.war` 后缀的 WAR 文件名来访问由程序员部署的 WAR 文件：

```
http://locahost:8080/novels/

```

如果服务部署在 `TOMCAT_HOME` 下的一个子目录中（比如，`myapps`），这会在 URL 中反映出来：

```
http://locahost:8080/myapps/novels/

```

我会在靠近文章结尾处的测试部分提供这部分的更多细节。

如前所述，我的主页上有一个包含 Ant 脚本的 ZIP 文件，这个文件可以编译并且部署网站或者服务。（这个 ZIP 文件中也包含一个 `novels.war` 的副本。）对于“小说”这个例子，命令的示例（`%` 是命令行提示符）如下：

```
% ant -Dwar.name=novels deploy

```

这个命令首先会编译 Java 源代码，并且创建一个可部署的 `novels.war` 文件，然后将这个文件保存在当前目录中，再复制到 `TOMCAT_HOME/webapps` 目录中。如果一切顺利，`GET` 请求（使用浏览器或者命令行工具，比如 `curl`）可以用来做一个测试：

```
% curl http://localhost:8080/novels/

```

默认情况下，Tomcat 设置为 <ruby> 热部署 <rt>  hot deploys </rt></ruby>：Web 服务器不需要关闭就可以进行部署、更新或者移除一个 web 应用。

### “小说”服务的代码

让我们回到“小说”这个例子，不过是在代码层面。考虑下面的 `Novel` 类：

#### 例 1：Novel 类

```
package novels;

import java.io.Serializable;

public class Novel implements Serializable, Comparable<Novel> {
    static final long serialVersionUID = 1L;
    private String author;
    private String title;
    private int id;

    public Novel() { }

    public void setAuthor(final String author) { this.author = author; }
    public String getAuthor() { return this.author; }
    public void setTitle(final String title) { this.title = title; }
    public String getTitle() { return this.title; }
    public void setId(final int id) { this.id = id; }
    public int getId() { return this.id; }

    public int compareTo(final Novel other) { return this.id - other.id; }
}

```

这个类实现了 `Comparable` 接口中的 `compareTo` 方法，因为 `Novel` 实例是存储在一个线程安全的无序 `ConcurrentHashMap` 中。在响应查看集合的请求时，“小说”服务会对从映射中提取的集合（一个 `ArrayList`）进行排序；`compareTo` 的实现通过 `Novel` 的 ID 将它按升序排序。

`Novels` 类中包含多个实用工具函数：

#### 例 2：Novels 实用工具类

```
package novels;

import java.io.IOException;
import java.io.File;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.nio.file.Files;
import java.util.stream.Stream;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.Collections;
import java.beans.XMLEncoder;
import javax.servlet.ServletContext; // not in JavaSE
import org.json.JSONObject;
import org.json.XML;

public class Novels {
    private final String fileName = "/WEB-INF/data/novels.db";
    private ConcurrentMap<Integer, Novel> novels;
    private ServletContext sctx;
    private AtomicInteger mapKey;

    public Novels() {
        novels = new ConcurrentHashMap<Integer, Novel>();
        mapKey = new AtomicInteger();
    }

    public void setServletContext(ServletContext sctx) { this.sctx = sctx; }
    public ServletContext getServletContext() { return this.sctx; }

    public ConcurrentMap<Integer, Novel> getConcurrentMap() {
        if (getServletContext() == null) return null; // not initialized
        if (novels.size() < 1) populate();
        return this.novels;
    }

    public String toXml(Object obj) { // default encoding
        String xml = null;
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            XMLEncoder encoder = new XMLEncoder(out);
            encoder.writeObject(obj);
            encoder.close();
            xml = out.toString();
        }
        catch(Exception e) { }
        return xml;
    }

    public String toJson(String xml) { // option for requester
        try {
            JSONObject jobt = XML.toJSONObject(xml);
            return jobt.toString(3); // 3 is indentation level
        }
        catch(Exception e) { }
        return null;
    }

    public int addNovel(Novel novel) {
        int id = mapKey.incrementAndGet();
        novel.setId(id);
        novels.put(id, novel);
        return id;
    }

    private void populate() {
        InputStream in = sctx.getResourceAsStream(this.fileName);
        // Convert novel.db string data into novels.
        if (in != null) {
            try {
                InputStreamReader isr = new InputStreamReader(in);
                BufferedReader reader = new BufferedReader(isr);

                String record = null;
                while ((record = reader.readLine()) != null) {
                    String[] parts = record.split("!");
                    if (parts.length == 2) {
                        Novel novel = new Novel();
                        novel.setAuthor(parts[0]);
                        novel.setTitle(parts[1]);
                        addNovel(novel); // sets the Id, adds to map
                    }
                }
                in.close();
            }
            catch (IOException e) { }
        }
    }
}

```

最复杂的方法是 `populate`，这个方法从一个包含在 WAR 文件中的文本文件读取。这个文本文件包括了“小说”的初始集合。要打开此文件，`populate` 方法需要 `ServletContext`，这是一个 Java 映射类型，包含了关于嵌入在 servlet 容器中的 servlet 的所有关键信息。这个文本文件有包含了像下面这样的记录：

```
Jane Austen!Persuasion

```

这一行被解析为两部分（作者和标题），由感叹号（`!`）分隔。然后这个方法创建一个 `Novel` 实例，设置作者和标题属性，并且将“小说”加到容器中，保存在内存中。

`Novels` 类也有一些实用工具函数，可以将“小说”容器编码为 XML 或 JSON，取决于发出请求的人所要求的格式。默认是 XML 格式，但是也可以请求 JSON 格式。一个轻量级的 XML 转 JSON 包提供了 JSON。下面是关于编码的更多细节。

#### 例 3：NovelsServlet 类

```
package novels;

import java.util.concurrent.ConcurrentMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.beans.XMLEncoder;
import org.json.JSONObject;
import org.json.XML;

public class NovelsServlet extends HttpServlet {
    static final long serialVersionUID = 1L;
    private Novels novels; // back-end bean

    // Executed when servlet is first loaded into container.
    @Override
    public void init() {
        this.novels = new Novels();
        novels.setServletContext(this.getServletContext());
    }

    // GET /novels
    // GET /novels?id=1
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        String param = request.getParameter("id");
        Integer key = (param == null) ? null : Integer.valueOf((param.trim()));

        // Check user preference for XML or JSON by inspecting
        // the HTTP headers for the Accept key.
        boolean json = false;
        String accept = request.getHeader("accept");
        if (accept != null && accept.contains("json")) json = true;

        // If no query string, assume client wants the full list.
        if (key == null) {
            ConcurrentMap<Integer, Novel> map = novels.getConcurrentMap();
            Object list = map.values().toArray();
            Arrays.sort(list);

            String payload = novels.toXml(list);        // defaults to Xml
            if (json) payload = novels.toJson(payload); // Json preferred?
            sendResponse(response, payload);
        }
        // Otherwise, return the specified Novel.
        else {
            Novel novel = novels.getConcurrentMap().get(key);
            if (novel == null) { // no such Novel
                String msg = key + " does not map to a novel.\n";
                sendResponse(response, novels.toXml(msg));
            }
            else { // requested Novel found
                if (json) sendResponse(response, novels.toJson(novels.toXml(novel)));
                else sendResponse(response, novels.toXml(novel));
            }
        }
    }

    // POST /novels
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) {
        String author = request.getParameter("author");
        String title = request.getParameter("title");

        // Are the data to create a new novel present?
        if (author == null || title == null)
            throw new RuntimeException(Integer.toString(HttpServletResponse.SC_BAD_REQUEST));

        // Create a novel.
        Novel n = new Novel();
        n.setAuthor(author);
        n.setTitle(title);

        // Save the ID of the newly created Novel.
        int id = novels.addNovel(n);

        // Generate the confirmation message.
        String msg = "Novel " + id + " created.\n";
        sendResponse(response, novels.toXml(msg));
    }

    // PUT /novels
    @Override
    public void doPut(HttpServletRequest request, HttpServletResponse response) {
        /\* A workaround is necessary for a PUT request because Tomcat does not
 generate a workable parameter map for the PUT verb. \*/
        String key = null;
        String rest = null;
        boolean author = false;

        /\* Let the hack begin. \*/
        try {
            BufferedReader br =
                new BufferedReader(new InputStreamReader(request.getInputStream()));
            String data = br.readLine();
            /\* To simplify the hack, assume that the PUT request has exactly
 two parameters: the id and either author or title. Assume, further,
 that the id comes first. From the client side, a hash character
 # separates the id and the author/title, e.g.,

 id=33#title=War and Peace
 \*/
            String[] args = data.split("#");      // id in args[0], rest in args[1]
            String[] parts1 = args[0].split("="); // id = parts1[1]
            key = parts1[1];

            String[] parts2 = args[1].split("="); // parts2[0] is key
            if (parts2[0].contains("author")) author = true;
            rest = parts2[1];
        }
        catch(Exception e) {
            throw new RuntimeException(Integer.toString(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
        }

        // If no key, then the request is ill formed.
        if (key == null)
            throw new RuntimeException(Integer.toString(HttpServletResponse.SC_BAD_REQUEST));

        // Look up the specified novel.
        Novel p = novels.getConcurrentMap().get(Integer.valueOf((key.trim())));
        if (p == null) { // not found
            String msg = key + " does not map to a novel.\n";
            sendResponse(response, novels.toXml(msg));
        }
        else { // found
            if (rest == null) {
                throw new RuntimeException(Integer.toString(HttpServletResponse.SC_BAD_REQUEST));
            }
            // Do the editing.
            else {
                if (author) p.setAuthor(rest);
                else p.setTitle(rest);

                String msg = "Novel " + key + " has been edited.\n";
                sendResponse(response, novels.toXml(msg));
            }
        }
    }

    // DELETE /novels?id=1
    @Override
    public void doDelete(HttpServletRequest request, HttpServletResponse response) {
        String param = request.getParameter("id");
        Integer key = (param == null) ? null : Integer.valueOf((param.trim()));
        // Only one Novel can be deleted at a time.
        if (key == null)
            throw new RuntimeException(Integer.toString(HttpServletResponse.SC_BAD_REQUEST));
        try {
            novels.getConcurrentMap().remove(key);
            String msg = "Novel " + key + " removed.\n";
            sendResponse(response, novels.toXml(msg));
        }
        catch(Exception e) {
            throw new RuntimeException(Integer.toString(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
        }
    }

    // Methods Not Allowed
    @Override
    public void doTrace(HttpServletRequest request, HttpServletResponse response) {
        throw new RuntimeException(Integer.toString(HttpServletResponse.SC_METHOD_NOT_ALLOWED));
    }

    @Override
    public void doHead(HttpServletRequest request, HttpServletResponse response) {
        throw new RuntimeException(Integer.toString(HttpServletResponse.SC_METHOD_NOT_ALLOWED));
    }

    @Override
    public void doOptions(HttpServletRequest request, HttpServletResponse response) {
        throw new RuntimeException(Integer.toString(HttpServletResponse.SC_METHOD_NOT_ALLOWED));
    }

    // Send the response payload (Xml or Json) to the client.
    private void sendResponse(HttpServletResponse response, String payload) {
        try {
            OutputStream out = response.getOutputStream();
            out.write(payload.getBytes());
            out.flush();
        }
        catch(Exception e) {
            throw new RuntimeException(Integer.toString(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
        }
    }
}

```

上面的 `NovelsServlet` 类继承了 `HttpServlet` 类，`HttpServlet` 类继承了 `GenericServlet` 类，后者实现了 `Servlet` 接口：

```
NovelsServlet extends HttpServlet extends GenericServlet implements Servlet

```

从名字可以很清楚的看出来，`HttpServlet` 是为实现 HTTP(S) 上的 servlet 设计的。这个类提供了以标准 HTTP 请求动词（官方说法，<ruby> 方法 <rt>  methods </rt></ruby>）命名的空方法：

* `doPost` （Post = 创建）
* `doGet` （Get = 读取）
* `doPut` （Put = 更新）
* `doDelete` （Delete = 删除）

其他一些 HTTP 动词也会涉及到。`HttpServlet` 的子类，比如 `NovelsServlet`，会重载相关的 `do` 方法，并且保留其他方法为<ruby> 空 <rt>  no-ops </rt></ruby>。`NovelsServlet` 重载了七个 `do` 方法。

每个 `HttpServlet` 的 CRUD 方法都有两个相同的参数。下面以 `doPost` 为例：

```
public void doPost(HttpServletRequest request, HttpServletResponse response) {

```

`request` 参数是一个 HTTP 请求信息的映射，而 `response` 提供了一个返回给请求者的输出流。像 `doPost` 的方法，结构如下：

* 读取 `request` 信息，采取任何适当的措施生成一个响应。如果该信息丢失或者损坏了，就会生成一个错误。
* 使用提取的请求信息来执行适当的 CRUD 操作（在本例中，创建一个 `Novel`），然后使用 `response` 输出流为请求者编码一个适当的响应。在 `doPost` 例子中，响应就是已经成功生成一个新“小说”并且添加到容器中的一个确认。当响应被发送后，输出流就关闭了，同时也将连接关闭了。

### 关于方法重载的更多内容

HTTP 请求的格式相对比较简单。下面是一个非常熟悉的 HTTP 1.1 的格式，注释由双井号分隔：

```
GET /novels              ## start line
Host: localhost:8080     ## header element
Accept-type: text/plain  ## ditto
...
[body]                   ## POST and PUT only

```

第一行由 HTTP 动词（在本例中是 `GET`）和以名词（在本例中是 `novels`）命名目标资源的 URI 开始。报头中包含键-值对，用冒号分隔左面的键和右面的值。报头中的键 `Host`（大小写敏感）是必须的；主机名 `localhost` 是当前机器上的本地符号地址，`8080` 端口是 Tomcat web 服务器上等待 HTTP 请求的默认端口。（默认情况下，Tomcat 在 8443 端口上监听 HTTP 请求。）报头元素可以以任意顺序出现。在这个例子中，`Accept-type` 报头的值是 MIME 类型 `text/plain`。

一些请求（特别是 `POST` 和 `PUT`）会有报文，而其他请求（特别是 `GET` 和 `DELETE`）没有。如果有报文（可能为空），以两个换行符将报头和报文分隔开；HTTP 报文包含一系列键-值对。对于无报文的请求，比如说查询字符串，报头元素就可以用来发送信息。下面是一个用 ID 2 对 `/novels` 资源的 `GET` 请求：

```
GET /novels?id=2

```

通常来说，查询字符串以问号开始，并且包含一个键-值对，尽管这个键-值可能值为空。

带有 `getParameter` 和 `getParameterMap` 等方法的 `HttpServlet` 很好地回避了有报文和没有报文的 HTTP 请求之前的差异。在“小说”例子中，`getParameter` 方法用来从 `GET`、`POST` 和 `DELETE` 方法中提取所需的信息。（处理 `PUT`请求需要更底层的代码，因为 Tomcat 没有提供可以解析 `PUT` 请求的参数映射。）下面展示了一段在 `NovelsServlet`中被重载的 `doPost` 方法：

```
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {
   String author = request.getParameter("author");
   String title = request.getParameter("title");
   ...

```

对于没有报文的 `DELETE` 请求，过程基本是一样的：

```
@Override
public void doDelete(HttpServletRequest request, HttpServletResponse response) {
   String param = request.getParameter("id"); // id of novel to be removed
   ...

```

`doGet` 方法需要区分 `GET` 请求的两种方式：一种是“获得所有”，而另一种是“获得某一个”。如果 `GET` 请求 URL 中包含一个键是一个 ID 的查询字符串，那么这个请求就被解析为“获得某一个”：

```
http://localhost:8080/novels?id=2  ## GET specified

```

如果没有查询字符串，`GET` 请求就会被解析为“获得所有”：

```
http://localhost:8080/novels       ## GET all

```

### 一些值得注意的细节

“小说”服务的设计反映了像 Tomcat 这样基于 Java 的 web 服务器是如何工作的。在启动时，Tomcat 构建一个线程池，从中提取请求处理程序，这种方法称为 “<ruby> 每个请求一个线程 <rt>  one thread per request </rt></ruby>” 模型。现在版本的 Tomcat 使用非阻塞 I/O 来提高个性能。

“小说”服务是作为 `NovelsServlet` 类的单个实例来执行的，该实例也就维护了一个“小说”集合。相应的，也就会出现竞态条件，比如出现两个请求同时被处理：

* 一个请求向集合中添加一个新“小说”。
* 另一个请求获得集合中的所有“小说”。

这样的结果是不确定的，取决与 *读* 和 *写* 的操作是以怎样的顺序进行操作的。为了避免这个问题，“小说”服务使用了线程安全的 `ConcurrentMap`。这个映射的关键是生成了一个线程安全的 `AtomicInteger`。下面是相关的代码片段：

```
public class Novels {
    private ConcurrentMap<Integer, Novel> novels;
    private AtomicInteger mapKey;
    ...

```

默认情况下，对客户端请求的响应被编码为 XML。为了简单，“小说”程序使用了以前的 `XMLEncoder` 类；另一个包含更丰富功能的方式是使用 JAX-B 库。代码很简单：

```
public String toXml(Object obj) { // default encoding
   String xml = null;
   try {
      ByteArrayOutputStream out = new ByteArrayOutputStream();
      XMLEncoder encoder = new XMLEncoder(out);
      encoder.writeObject(obj);
      encoder.close();
      xml = out.toString();
   }
   catch(Exception e) { }
   return xml;
}

```

`Object` 参数要么是一个有序的“小说” `ArraList`（用以响应“<ruby> 获得所有 <rt>  get all </rt></ruby>”请求），要么是一个 `Novel` 实例（用以响应“<ruby> 获得一个 <rt>  get one </rt></ruby>”请求），又或者是一个 `String`（确认消息）。

如果 HTTP 请求报头指定 JSON 作为所需要的类型，那么 XML 就被转化成 JSON。下面是 `NovelsServlet` 中的 `doGet` 方法中的检查：

```
String accept = request.getHeader("accept"); // "accept" is case insensitive
if (accept != null && accept.contains("json")) json = true;

```

`Novels`类中包含了 `toJson` 方法，可以将 XML 转换成 JSON：

```
public String toJson(String xml) { // option for requester
   try {
      JSONObject jobt = XML.toJSONObject(xml);
      return jobt.toString(3); // 3 is indentation level
   }
   catch(Exception e) { }
   return null;
}

```

`NovelsServlet`会对各种类型进行错误检查。比如，`POST` 请求应该包含新“小说”的作者和标题。如果有一个丢了，`doPost` 方法会抛出一个异常：

```
if (author == null || title == null)
   throw new RuntimeException(Integer.toString(HttpServletResponse.SC_BAD_REQUEST));

```

`SC_BAD_REQUEST` 中的 `SC` 代表的是 <ruby> 状态码 <rt>  status code </rt></ruby>，`BAD_REQUEST` 的标准 HTTP 数值是 400。如果请求中的 HTTP 动词是 `TRACE`，会返回一个不同的状态码：

```
public void doTrace(HttpServletRequest request, HttpServletResponse response) {
   throw new RuntimeException(Integer.toString(HttpServletResponse.SC_METHOD_NOT_ALLOWED));
}

```

### 测试“小说”服务

用浏览器测试 web 服务会很不顺手。在 CRUD 动词中，现代浏览器只能生成 `POST`（创建）和 `GET`（读取）请求。甚至从浏览器发送一个 `POST` 请求都有点不好办，因为报文需要包含键-值对；这样的测试通常通过 HTML 表单完成。命令行工具，比如说 [curl](https://curl.haxx.se/)，是一个更好的选择，这个部分展示的一些 `curl` 命令，已经包含在我网站的 ZIP 文件中了。

下面是一些测试样例，没有展示相应的输出结果：

```
% curl localhost:8080/novels/
% curl localhost:8080/novels?id=1
% curl --header "Accept: application/json" localhost:8080/novels/

```

第一条命令请求所有“小说”，默认是 XML 编码。第二条命令请求 ID 为 1 的“小说”，XML 编码。最后一条命令通过 `application/json` 添加了 `Accept` 报头元素，作为所需要的 MIME 类型。“<ruby> 获得一个 <rt>  get one </rt></ruby>”命令也可以用这个报头。这些请求用了 JSON 而不是 XML 编码作为响应。

下面两条命令在集合中创建了一个新“小说”，并且确认添加了进去：

```
% curl --request POST --data "author=Tolstoy&title=War and Peace" localhost:8080/novels/
% curl localhost:8080/novels?id=4

```

`curl` 中的 `PUT` 命令与 `POST` 命令相似，不同的地方是 `PUT` 的报文没有使用标准的语法。在 `NovelsServlet` 中关于 `doPut` 方法的文档中有详细的介绍，但是简单来说，Tomcat 不会对 `PUT` 请求生成合适的映射。下面是一个 `PUT` 命令和确认命令的的例子：

```
% curl --request PUT --data "id=3#title=This is an UPDATE" localhost:8080/novels/
% curl localhost:8080/novels?id=3

```

第二个命令确认了集合已经更新。

最后，`DELETE` 命令会正常运行：

```
% curl --request DELETE localhost:8080/novels?id=2
% curl localhost:8080/novels/

```

这个请求是删除 ID 为 2 的“小说”。第二个命令会显示剩余的“小说”。

### web.xml 配置文件

尽管官方规定它是可选的，`web.xml` 配置文件是一个生产级别网站或服务的重要组成部分。这个配置文件可以配置独立于代码的路由、安全性，或者网站或服务的其他功能。“小说”服务的配置通过为该服务的请求分配一个 URL 模式来配置路由：

```
<xml version = "1.0" encoding = "UTF-8">
<web-app>
   <servlet>
     <servlet-name>novels</servlet-name>
     <servlet-class>novels.NovelsServlet</servlet-class>
   </servlet>
   <servlet-mapping>
     <servlet-name>novels</servlet-name>
     <url-pattern>/*</url-pattern>
   </servlet-mapping>
</web-app>

```

`servlet-name` 元素为 servlet 全名（`novels.NovelsServlet`）提供了一个缩写（`novels`），然后这个名字在下面的 `servlet-mapping` 元素中使用。

回想一下，一个已部署服务的 URL 会在端口号后面有 WAR 文件的文件名：

```
http://localhost:8080/novels/

```

端口号后斜杠后的 URI，是所请求资源的“路径”，在这个例子中，就是“小说”服务。因此，`novels` 出现在了第一个单斜杠后。

在 `web.xml` 文件中，`url-patter` 被指定为 `/*`，代表 “以 `/novels` 为起始的任意路径”。假设 Tomcat 遇到了一个不存在的 URL，像这样：

```
http://localhost:8080/novels/foobar/

```

`web.xml` 配置也会指定这个请求被分配到“小说” servlet 中，因为 `/*` 模式也包含 `/foobar`。因此，这个不存在的 URL 也会得到像上面合法路径的相同结果。

生产级别的配置文件可能会包含安全相关的信息，包括<ruby> 连接级别 <rt>  wire-level </rt></ruby>和<ruby> 用户角色 <rt>  users-roles </rt></ruby>。即使在这种情况下，配置文件的大小也只会是这个例子中的两到三倍大。

### 总结

`HttpServlet` 是 Java web 技术的核心。像“小说”这样的网站或 web 服务继承了这个类，并且根据需求重载了相应的 `do` 动词方法。像 Jersay（JAX-RS）或 Restlet 这样的 Restful 框架通过提供定制的 servlet 完成了基本相同的功能，针对框架中的 web 应用程序的请求，这个 servlet 扮演着 HTTP(S) <ruby> 终端 <rt>  endpoint </rt></ruby>的角色。

当然，基于 servlet 的应用程序可以访问 web 应用程序中所需要的任何 Java 库。如果应用程序遵循<ruby> 关注点分离 <rt>  separation-of-concerns </rt></ruby>原则，那么 servlet 代码仍然相当简单：代码会检查请求，如果存在缺陷，就会发出适当的错误；否则，代码会调用所需要的功能（比如，查询数据库，以特定格式为响应编码），然后向请求这发送响应。`HttpServletRequest` 和 `HttpServletReponse` 类型使得读取请求和编写响应变得简单。

Java 的 API 可以从非常简单变得相当复杂。如果你需要用 Java 交付一些 Restful 服务的话，我的建议是在做其他事情之前先尝试一下简单的 `HttpServlet`。

---

via: <https://opensource.com/article/20/7/restful-services-java>

作者：[Marty Kalin](https://opensource.com/users/mkalindepauledu) 选题：[lujun9972](https://github.com/lujun9972) 译者：[Yufei-Yan](https://github.com/Yufei-Yan) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Summary: • 跨平台桌面应用开发工具 Electron 10.0.0 发布 • Chrome 85 启用新技术提升 10% 性能

为chrome点赞。<br />
考虑换成Firefox了。

# #新闻拍一拍# Linux 基金会考虑放弃采用电子邮件列表的 Linux 内核的贡献方式

<img src="content_image/album_202008_27_080225c9y88k7u3y3g02g9.jpg" alt="" title="">

#### Linux 基金会考虑放弃采用电子邮件列表的 Linux 内核的贡献方式

多年以来，Linux 内核邮件列表一直作为内核开发人员之间进行协作的主要工具而存在，纯文本电子邮件是内核开发的入门门槛。电子邮件机制确实是有效的，但它对新的贡献者来说也确实是一项障碍。Linux 基金会目前的想法是，从现有的基于文本的电子邮件系统迁移，或在此基础上拓展一个新近成长起来的开发者更为熟悉的方式。

来源：[开源中国](https://www.oschina.net/news/118169/linux_kernel_email "https://www.oschina.net/news/118169/linux_kernel_email")

>
> 拍一拍：当年能创新出 Git 的 Linux 内核开发者们，却一直守着上世纪的电子邮件列表不放，是 Linus 老了还是成长为大型软件组织的 Linux 内核开发者们僵化了？
>
>
>

#### 跨平台桌面应用开发工具 Electron 10.0.0 发布

根据项目的支持政策， Electron 7.xy 已终止支持。鼓励开发人员和应用程序升级到新版本的 Electron。

来源：[开源中国](https://www.oschina.net/news/118185/electron-10-0-0-released "https://www.oschina.net/news/118185/electron-10-0-0-released")

>
> 拍一拍：比较有意思的是，原本为了跨平台应用而开发的 Java，在这方面越来越不受欢迎了。
>
>
>

#### Chrome 85 启用新技术提升 10% 性能

Google 释出了 Chrome 85。新版的一个重要变化是在编译时启用了名为 Profile Guided Optimization 的技术优化性能。Google 称，页面加载速度提升了 10%。Chrome 85 的其它特性包括标签组支持折叠和展开，改进 PDF，新的开发者特性。

来源：[solidot](https://www.solidot.org/story?sid=65356 "https://www.solidot.org/story?sid=65356")

>
> 拍一拍：Chrome 形成压倒性优势的背后，与他们不断进取采用新技术也有很大关系。
>
>
>


《代码英雄》第一季（7）：开启未来

# 《代码英雄》第一季（7）：开启未来

>
> 代码英雄讲述了开发人员、程序员、黑客、极客和开源反叛者如何彻底改变技术前景的真实史诗。
>
>
>

>
> **什么是《代码英雄》**
>
>
> <ruby> 代码英雄 <rt>  Command Line Heroes </rt></ruby>是世界领先的企业开源软件解决方案供应商红帽（Red Hat）精心制作的原创音频播客，讲述开发人员、程序员、黑客、极客和开源反叛者如何彻底改变技术前景的真实史诗。该音频博客邀请到了谷歌、NASA 等重量级企业的众多技术大牛共同讲述开源、操作系统、容器、DevOps、混合云等发展过程中的动人故事。
>
>
>

<img src="content_image/album_202008_27_231305dtt15415mb6mwke6.jpg" alt="" title="">

本文是《[代码英雄](https://www.redhat.com/en/command-line-heroes)》系列播客[第一季（7）：开启未来](https://www.redhat.com/en/command-line-heroes/season-1/days-of-future-open)的[音频](https://dts.podtrac.com/redirect.mp3/audio.simplecast.com/8a8244c8.mp3)脚本。

想象一下，在这个世界上，开源从来没有流行过，没有人认为将源代码提供给别人是个好主意。在本期节目中，我们将想象这种奇异的可能性。而我们也会庆祝那些让我们走到今天的开源工具和方法论。

加入我们，我们将对第一季进行总结，高屋建瓴地来了解开源世界是如何形成的。下一季，我们将把镜头放大，聚焦于当今的代码英雄们的史诗般的奋斗。

**配音**：

在一个没有开源的世界里，来自未来的执法者穿越时空去摧毁 Linus Torvalds 的计算机。

**Saron Yitbarek**：

天啊。我又做了那个噩梦。在梦里，我有一些很棒的想法，但我不能上手开发，因为没有相应的开源技术可以使用。

**Tristram Oaten**：

我认为一个没有开源的世界几乎注定是邪恶的。

**00:00:30 - Saron Yitbarek**：

我想，如果软件（LCTT 译注：这里的软件指 MINIX）在 20 世纪 80 年代遭到闭源，而源代码再也没有被打开过，肯定会少很多创新。

**Steven Vaughan-Nichols**：

那将是一个落后的世界。

**Hannah Cushman**：

我认为智能冰箱肯定会变得更少。

**配音**：

在一个没有智能冰箱的世界中。

**00:01:00 - Saron Yitbarek**：

好吧，好吧。你懂的。我们正在想象一个没有开放源代码技术的世界，这并不特别美好。想象一下：你的在线生活由一些大型私有公司管理，为此你得向它们缴费。网络中的每一处都被它们看守着。对于我们开发人员来说，没有开源的世界意味着更少的自由和影响力。

**00:01:30**：

在整整一季中，我们一直在纪录开发人员在开源世界中的角色。随着开源技术与工具的不断涌现，我们的工作也不断演进和扩展。无论是敏捷宣言，DevOps 的兴起，还是容器编排，我们宣称的力量和自由都与开源哲学紧密相关。

在本季的最后一集，我们将会回顾前几集中的内容。随着世界走向开源，这个词的原始含义能剩下多少呢？而我们，接下来，则将何去何从？

**00:02:00**：

我是 Saron Yitbarek，这里是《代码英雄》，一款红帽公司原创的播客节目。第 7 集：开启未来。

**Steven Vaughan-Nichols**：

没有开源的世界不是我想要的世界，也不是绝大多数人想在其中生活的世界。

**00:02:30 - Saron Yitbarek**：

这位是 Steven Vaughan-Nichols。你可能在[第一集](/article-12494-1.html)和[第二集](/article-12508-1.html)里谈论操作系统战争的时候记住了他。他是<ruby> 哥伦比亚广播集团互动媒体公司 <rt>  CBS Interactive </rt></ruby>的特约编辑，从快速调制解调器的速度还是 300 比特每秒时以来，他就一直关注着科技。

**Steven Vaughan-Nichols**：

除了 Linux 之外，你可能无法叫出任何一个开源程序的名字，但是你当前的生活是建立在开源之上的。

**00:03:00 - Saron Yitbarek**：

如果不使用开源技术，绝大多数人甚至无法上网。开源技术几乎存在于地球上的每台超级计算机中。它运行在<ruby> 物联网 <rt>  Internet of Things </rt></ruby>（IoT）中。它存在于你的手机、你的 Web 服务器，你的社交媒体———以及，大型强子对撞机中。而且，并非只有我们开发人员了解开源的诸多益处。开源态度现在已经超越了技术的范畴，影响了其它行业，例如经济学、音乐、科学和新闻业。

**00:03:30**：

如果建筑师以我们分享代码的同样方式分享建筑的蓝图会发生什么？如果一个记者打开她的档案，让任何人不仅可以检查她发表的文章，还能检查她的研究和采访记录，会发生什么？我们不应为此而惊讶，因为开发人员培育这份哲学已有多年。每个人都可以看到代码、注释代码、复制代码、提供补丁，这实际上是一件非常基础的事情，对吧？这就是分享。

**00:04:00**：

自最早的人类分享膳食食谱以来，我们就知道公开分享指令集，或者说算法，对人类有净收益。在某些方面，开源技术现在能使我们重温这个基本事实。

**Hannah Cushman**：

我认为，使更多的事物开源会促进和鼓励人们查阅原始资源，这总是很好的。

**00:04:30 - Saron Yitbarek**：

这位是 Hannah Cushman，她是 DataMade 的一位开发人员，他们一直在努力使城市变得更加开放。将来自政府的大量公开数据进行整理并合理地处理，就可以让普通市民使用它来采取行动。他们使用的技术是开源的，同时他们对政治的态度也是如此。

**00:05:00 - Hannah Cushman**：

我们在芝加哥与一个叫做 City Bureau 的组织进行了一个项目，和他们一起为公立学校测试铅含量。我们测试了这些学校中几乎全部的供水设备。这些全部公布的测试结果有 500 份 PDF 文件之多。

**Saron Yitbarek**：

是的，这太好了。但这并不完全是一种使数据公开的有效方式。

**00:05:30 - Hannah Cushman**：

在整个系统中，很难看到例如哪里发现了铅，以及哪里的铅含量更高。我们使用了另一个叫做 Tablua 的开源工具，可以在终端上运行；它能从 500 多个 PDF 文件中提取数据并将其放在一起，帮助我们把巨量信息转储到一个对人们有用的上下文中。

我认为查询源数据是一种非常有效的方式，这使人们可以了解信息的来源并验证其正确性。

**00:06:00 - Saron Yitbarek**：

市民可以访问健康报告的详细信息，获取游说者的数据，还可以查看城市政治的整个组织结构，DataMade 为此提供了浏览门户。这使芝加哥人有更多机会对市政的方方面面作出改变。

<ruby> 加州州立理工大学 <rt>  Cal Poly </rt></ruby>的研究软件工程师 Carol Willing 认为，这种不断扩展的开源态度将给世界带来更广泛的变化。

**00:06:30 - Carol Willing**：

就个人而言，我认为开源将从开源软件发展到开放硬件、开放政府、开放教育、开放协作、开放创新等等。开源会不断进化。

**Saron Yitbarek**：

现在，开源逐渐变得更像是自然法则，而不仅仅是科技界的产物。

**00:07:00 - Carol Willing**：

人们慷慨奉献自己时间的事迹古而有之。但令人耳目一新的是，开源深刻地改变了世界，因为它使不同的小群体联合起来，一起致力于他们中任何一组都无法单独处理的大型项目。

**00:07:30 - Saron Yitbarek**：

“用全新的技术来践行古老的理念”——这个主意我喜欢。但先别急着高兴。随着开源这个词被越来越广泛地使用，它的定义可能会变得模糊。在某些场合下，它开始意味着“免费”，或者“众包”，甚至仅仅是“可定制”。

例如，如果我只是允许你选择在冰淇淋上哪撒些糖粉，这不代表我的冰淇淋是开源甜点。但是，如果我告诉你如何制作糖粉，让你改进我的糖粉配方——然后，如果你也想与他人分享糖粉制作的秘密，那么，恭喜你，我们得到了一些美味的开源。

**00:08:00**：

那么，开源的原始定义又是什么？它很简单，但我们应当恪守。要实现真正的开源，你需要公开代码，或者蓝图，或者你的菜谱。换句话说，就是使任何人都可以随意研究、修改和重新分发原始数据。这种哲学将带来变革，不过对于命令行外的世界，一切才刚刚开始。

**00:08:30 - Thomas Cameron**：

这是一种非常惊人的技术开发方式。无论是它的成功，还是我已经参与其中的这一事实，都让我感到震惊。

**Saron Yitbarek**：

Thomas Cameron 在 1998 年“开源”这个词被发明之前就一直从事开源工作。今天，他是 Red Hat 的高级首席云推广人员。他完全有资格谈论开源在如今的进展，以及其发展的过程中发究竟生了多少斗争。

**00:09:00 - Thomas Cameron**：

你知道，经理们不想承担风险，这是巨大的阻力。因为它是免费的，所以他们会想，“我没办法打电话寻求技术支持”，“我不得不依靠特定的开源软件”之类。这一类斗争还算简单，在部门服务器、群组服务器、小型 Web 服务器、小型文件服务器和打印服务器上，我们也赢过不少。随着时间的推移，在赢得这些简单的战斗之后，更艰难的战斗出现了。在每次“作战”中，你会发现，系统管理员和系统工程师对开源越来越着迷。

**00:09:30 - Saron Yitbarek**：

尽管有这些斗争，你也无法否认一直以来的进展。

**00:10:00 - Thomas Cameron**：

我目睹了开源给 IT 行业带来的改变，它最开始时用在某些系统管理员办公桌下私搭乱建的服务器里，并最终传播到家喻户晓的大公司之中——英特尔、IBM、AMD，每个你能想到的组织都开始为开源项目做出贡献。这绝对是一场斗争，我在不同的企业职位上都参加过如此多的相关争论；我曾说过，“我们需要把 Linux，或其他开源技术，引入数据中心。”

**00:10:30 - Saron Yitbarek**：

Thomas 观察到，开源软件开发正逐步占据市场。但对于某些人来说，这很令人不安。

**Thomas Cameron**：

我们能够分享信息与分析结果，这让那些一直占有信息并从中牟利的人感到害怕。这种模式使他们无法轻易获取利润，也难以哪怕得到对一个组织的完全控制，这是巨大的变化，随之而来的是恐惧。

**00:11:00 - Saron Yitbarek**：

我们在本季开始时描述的支持开源的反叛者们现在领导着这个行业。但从更长远的角度来看，故事绝不会在这里结束。Christopher Tozzi 是 Fixate IO 的高级编辑。他将开源带来的颠覆视为某种根本性转变的开始，这种转变将使世界各地的人们都能协同合作——而不仅是在软件开发行业中。

**00:11:30 - Christopher Tozzi**：

我认为，在过去的二十年里，开源变得如此强大的原因之一就是人们对去中心化一直保有兴趣。我认为，这也解释了开源如何影响其它技术创新。比如，区块链也建立在这样的思想上：如果我们摆脱集中的生产方式，去中心化的数据库或交易方式可能会更高效、更安全。重申一次，我认为今天的开源，自从 Torvalds 出现以来，就与开发工作的去中心化息息相关。

**00:12:00 - Saron Yitbarek**：

全面的分权意味着整个世界都在走向开源。体现了这一理念的开发人员，他们是最能想象未来的人。

这是 Tristram Oaten，他是伦敦的一位开发者，他肯定在考虑这场漫长的比赛。

**00:12:30 - Tristram Oaten**：

就像是 3D 打印机将通过在家生产零件来使我们的生活更轻松——而且多半能更环保一样。无论什么时候有东西坏了，你都可以在家里新制造一个。这是<ruby> 星际迷航 <rt>  Star Trek </rt></ruby>式的未来的复制器，就和理想中一模一样。希望这样的生产方式能真正投入使用，这样，说不定，整座房子都能变得开源了。

**Saron Yitbarek**：

Tristram 设想了一个世界，在这个世界上，开源是各个领域都遵守的规则。这意味着，开发者即使不是大师，至少也会成为人们的向导——这种向导是至关重要的。

**00:13:00 - Tristram Oaten**：

在未来，我们作为开发人员的角色将越加重要，我们会变得越来越像“魔法师”——如果我们现在还不够像的话。

**Saron Yitbarek**：

好吧，魔法师。我们会成为魔法师。

**00:13:30 - Tristram Oaten**：

我们能用奇怪的语言驱使机器做奇妙的事，于是，我们会被高薪雇来做宫廷魔法师，或者公司魔法师。当每个人的身体中都有设备，并且无处不在的设备都可以通过互联网访问，还能被远程控制时，我们则需要作为一个团体，一个行会，以最好的信念行事，就像医疗行业要有不伤害他人的宪章等等。这非常重要。

我认为，开发人员需要共同决定不要制造杀手机器人，也不要在每个人的路由器和每个人的助听器中安置间谍软件。我们需要彼此确认，并向所有人保证，我们将为更大的利益而努力，而非为了伤害人类。

**00:14:00 - Saron Yitbarek**：

让我们现在保证不会造机器人杀手，对吧？好。在此之上，我确实认为 Tristram 说得对。在某些方面，我们开发者已经看到了未来，这代表我们有机会在塑造未来上出一份力。

10 年后，开源开发的道德标准将会是什么样子的？

**00:14:30 - Tristram Oaten**：

我们现在有着极大的特权，因此，我们有责任做正确的事。

**Saron Yitbarek**：

那么，魔法师们，我们将去向何方？我们能为开源创造一个健康的未来吗？我想和一个对这一切进行了深入思考的人谈谈，于是，我找到了这一位。Safia Abdalla 是一名软件工程师，她一直在为<ruby> 交互计划 <rt>  Interact Project </rt></ruby>做开源贡献。我们将会讨论，真正的“可持续的、广泛的开源”会是什么样子。听听看。

在你心里，未来的开源会是怎么样的，和现在有什么不同之处？

**00:15:00 - Safia Abdalla**：

嗯，我想，我所看到的最大的新兴趋势之一就是对开源可持续性的高度关注，也就是关于如何让开源项目一直得到良好维护和更新的讨论。有一些项目对整个技术界生态都至关重要，讨论也集中于它们。我认为，在该领域，已经有了许多有趣的进展。

**00:15:30 - Saron Yitbarek**：

Safia 让我思考，如果我们能够建立她所描述的可持续发展的方法，如果公司能够贡献时间、代码和资源，我们的工作能够得到多少改善？又会发生多少变化？所以我问她，这样可持续的方式会给我们所创造的产品，和我们建构的工具，带来怎么样的改变？

**00:16:00 - Safia Abdalla**：

可悲的现实是，当你没有精力，时间和金钱来为每个人打造好东西时，你就会倾向于只为自己做好它。

**Saron Yitbarek**：

嗯，确实。

**Safia Abdalla**：

在这种情况下，你构建的产品会将把很多人排除在用户之外。因此，我相信，如果我们发现开放源代码的更具可持续性的模型，那么我们实际上将开始构建可供盲人、听障者或以其它方式残障的个人使用的软件。

**00:16:30 - Saron Yitbarek**：

有趣，我喜欢。考虑到开放源代码的原则、流程、文化和社区，以及你提到的所有这些内容该如何适用于技术之外、软件开发之外的行业时，你认为真正可以从开源中受益的领域是哪些？你认为接下来开源可能会出现在哪里？

**00:17:00 - Safia Abdalla**：

喔，这是个有趣的角度。我第一个想到的是，开源思维可以被用于科学界，使科学变得更加开放。之所以我会想到这一点，是因为，当你以开放方式分享软件时，你所分享的并不是一行行的代码 —— 好吧，你确实在分享代码 —— 但，更重要的是，你在分享知识和细节，在与其他人交流该如何做事。因此，你真正分享的是知识。

**00:17:30**：

开源的方式可以相当直接地应用于科学界，因为研究人员也会花费大量的时间来探究特定课题，随后就此课题发表论文。而且，我认为，我们需要向科学界倡议更加开放的科研方式，以确保科研成果能够对所有人开放，使所有人都能理解、分享和参与，这将会提高社会对科学的理解，并在一定程度上促进科学研究本身。

**00:18:00 - Saron Yitbarek**：

当我上大学时，我从事生物化学研究；我非常习惯于带着热情进行实验、研究、尝试新事物。然而，同时，你也不能让人随意插手研究，因为你需要做通讯作者。你需要信誉。这是学术界进步的一个很重要、很重要的组成部分。

**00:18:30**：

因此，开源的原则——即分享原始数据、贡献劳动，以及将未完成的产品公之于众，依靠集体智慧将其完工的这些原则——和某些更具保护意识的行业必然发生冲突。你如何看待这种冲突？

**00:19:00 - Safia Abdalla**：

这是个好问题。我认为这涉及一个更大、更复杂的问题。为了成功地将开源引入其他行业，外在的动机和鼓励在很大程度上是必要的。你不能依赖于鼓励人们只专注于自己的目标的现有体系，因为那样会牺牲他人的利益和社会的更大利好。

**00:19:30**：

我认为，我们必须根本地改变我们看待很多事情的方式，并更改许多体系的运作方式，以使它们关注集体利益而非单一利益。很难撤销像终身教职这样对大学有很多负面影响的制度。很难消除其它可能损害生态、损害他人，或者阻碍社会进步的激励机制。不管是采用开源的思维方式，还是主动取消这些体系，我们都有极长的路要走。

**00:20:00 - Saron Yitbarek**：

确实。如果你可以从头重新创造开源，那么，属于你的开源版本又会是什么样的？

**00:20:30 - Safia Abdalla**：

哇噻。关于开源，我要改变的第一件事是它的公共关系和形象。我可能会尝试建立一种开源文化或社区，让人们认识到，你即使不是精英，或者精湛的开发人员，也能活跃并取得成功。现有开源文化中的精英倾向使我感到震慑。

**00:21:00**：

另外，我也要重点关注开源的可持续性，增加公司的责任感和开源体系的健康程度。我认为很多人没有意识到的事情之一是，许多受欢迎的技术公司和平台都包含了开源要素。例如，有很多 Rails Web 应用程序是极其成功的，盈利能力可观。而且，我认为，对我们来说，重要的是确保这些公司对开源社区有管理权，认识到其价值所在，并给予回馈。

**00:21:30 - Saron Yitbarek**：

好的，在 Safia 的开源中，企业将会负起责任，并对开源的可持续性做出贡献。项目的贡献者和维护者可能会因为自己所做的工作而获得报酬。这样的开源多半会是更加开放、更具有关怀之心的模式。

**Safia Abdalla**：

是的。

**Saron Yitbarek**：

听起来像是一个很棒的开源的版本，我喜欢它。

**Safia Abdalla**：

谢谢。

**00:22:00 - Saron Yitbarek**：

Safia Abdalla 是<ruby> 交互计划 <rt>  Interact Project </rt></ruby>的软件工程师和贡献者。她是一位新一代开发人员。而她在平时也对开源抱有自己的期望。所以，我想向这支新的代码英雄军队大声呼喊：“你们都将会向我们展示未来，因为你们现在正生活在未来之中，而你们也将负责领导我们走向明天。”

**00:22:30**：

现在，尽管我对开源革命心怀热情，但我也不想成为一个盲目乐观的人。开源也将会受到挑战。开源的存在越广泛，我们就越需要确保它的可持续性。我们找到了一种可扩展的方式来维护开源项目吗？我的意思是，虽然 Linux 内核的贡献者中有一些是全职员工，但是大多数的开源项目仍然是由志愿者维护的。

**00:23:00**：

开源的工作并不会因为我们不再“反叛”而终结。市值数十亿美元的公司都在运行 Linux，而开源先锋们现在是技术领袖。我们需要跟随这条道路，并试着想象接下来会发生什么。

尤其是，可能会出现什么问题？Christopher Tozzi 告诉我们，曾经作为规则破坏者的开源并不对破坏本身免疫。

**00:23:30 - Christopher Tozzi**：

开源革命尚未结束，因为挑战并没有停止。即使今天基本上地球上每个使用计算机的人都在以这样或那样的方式使用开源软件，但这并不代表开源必然是绝对安全的。尤其是从致力于开源社区最初目标的人们的角度来看，诸如云计算之类的事物确实使情况变得复杂了。

**00:24:00 - Saron Yitbarek**：

开源能有多开源呢？Christopher 提到了云计算，而在[第六集](/article-12551-1.html)中，我们描述了依赖于别人的数据中心肯定会使开源最初的目标复杂化。

这是一个棘手的领域，我们仍在了解这个领域的情况。在前进的过程中，我们必须不忘初心。

**00:24:30**：

每个年轻的反叛者都需要<ruby> 欧比旺·克诺比 <rt>  Obi Wan </rt></ruby>的原力全息仪。他们会从过去吸取经验教训吗？<ruby> 林纳斯·托瓦兹 <rt>  Linus Torvalds </rt></ruby>曾经说过，“在真正的开源中，你有权掌握自己的命运。” 如果开发人员能够在更大的世界中宣扬这种精神，那么，干得漂亮。

**00:25:00**：

到此为止，这是第一季的最后一集，真不敢相信。这一季过得很快。在着手编写这一系列播客之前，我从没有想过，是谁创造了 DevOps、敏捷开发和云计算；我从没有想过它们从何而来。我从没想过它们会有自己的家，有团队贡献才能、照顾它们，帮助它们成长。它们只是我工具箱里的一堆工具。但我现在不是这样看待它们的。

**00:25:30**：

它们不仅仅是随机的工具，而是我生活环境的一部分。在我之前，开发者们已经花了几十年的时间来塑造这一局面。现在，我要致力于塑造未来。真是棒极了。

**00:26:00**：

第一季即将结束，但好消息是，我们已经在准备第二季了。在这七集中，我们专注于开源工具和方法论，这些工具和方法使我们有了今天。这有点像是从 3 万英尺的高度看开源世界的形成史。在第二季中，我们将着眼于细节，并关注当今代码英雄们史诗般的奋斗。我们将跟随每一集，看看开发者如何挑战常规。这些都是塑造我们行业未来的真实故事。

**00:26:30**：

当我们寻找这些故事的时候，我们很希望收到您的来信。告诉我们，你的代码故事是什么？你参与过哪些史诗般的开源战役？访问 [redhat.com/command-line-heroes](http://redhat.com/command-line-heroes) 留下你的故事。我们正在倾听。

**00:27:00**：

如果现在你还在听的话，你可能想要看看将于 5 月 8 日至 10 日在旧金山举行的 2018 红帽峰会的阵容。峰会包括为期三天的分组会议、动手实验和主题演讲，其中包括了有关开源的主题演讲，而你也可以参与其中。希望能在那里见到你。

**00:27:30**：

代码英雄是红帽的原创播客。请确保你订阅了该节目，以在您的设备上免费获取第一季中的所有剧集，并在第二季开始时收到通知。只要在苹果播客、Spotify、Google Play、CastBox 和其他播客平台中搜索《代码英雄》，然后点击订阅，你就可以第一时间收听新一期。我是 Saron Yitbarek。感谢你的聆听，编程不止。

>
> **什么是 LCTT SIG 和 LCTT LCRH SIG**
>
>
> LCTT SIG 是 LCTT <ruby> 特别兴趣小组 <rt>  Special Interest Group </rt></ruby>，LCTT SIG 是针对特定领域、特定内容的翻译小组，翻译组成员将遵循 LCTT 流程和规范，参与翻译，并获得相应的奖励。LCRH SIG 是 LCTT 联合红帽（Red Hat）发起的 SIG，当前专注任务是《代码英雄》系列播客的脚本汉化，已有数十位贡献者加入。敬请每周三、周五期待经过我们精心翻译、校对和发布的译文。
>
>
> 欢迎[加入 LCRH SIG](/article-12436-1.html) 一同参与贡献，并领取红帽（Red Hat）和我们联合颁发的专属贡献者证书。
>
>
>

---

via: <https://www.redhat.com/en/command-line-heroes/season-1/days-of-future-open>

作者：[Red Hat](https://www.redhat.com/en/command-line-heroes) 选题：[bestony](https://github.com/bestony) 译者：[LaingKe](https://github.com/laingke) 校对：[Northurland](https://github.com/Northurland)

本文由 [LCRH](https://github.com/LCTT/LCRH) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


如何将文本文件在 Unix 和 DOS（Windows）格式之间转换

Summary: 有很多方法可以将 DOS 文本文件转换为 Unix 格式。

vim 也行

有很多方法可以将 DOS 文本文件转换为 Unix 格式。

# 如何将文本文件在 Unix 和 DOS（Windows）格式之间转换

<img src="content_image/album_202008_27_235550klfnz34lzpnchf7g.jpg" alt="" title="">

作为一名 Linux 管理员，你可能已经注意到了一些开发者请求将文件从 DOS 格式转换为 Unix 格式，反之亦然。

这是因为这些文件是在 Windows 系统上创建的，并由于某种原因被复制到 Linux 系统上。

这本身没什么问题，但 Linux 系统上的一些应用可能不能理解这些新的换行符，所以在使用之前，你需要转换它们。

DOS 文本文件带有回车（`CR` 或 `\r`）和换行（`LF` 或 `\n`）一对字符作为它们的换行符，而 Unix 文本只有换行（`LF`）符。

有很多方法可以将 DOS 文本文件转换为 Unix 格式。

但我推荐使用一个名为 `dos2unix` / `unix2dos` 的特殊工具将文本在 DOS 和 Unix 格式之间转换。

* `dos2unix` ：将文本文件从 DOS 格式转换为 Unix 格式。
* `unix2dos` ：将文本文件从 Unix 格式转换为 DOS 格式。
* `tr`、`awk` 和 [sed 命令](https://www.2daygeek.com/linux-sed-to-find-and-replace-string-in-files/)：这些可以用于相同的目的。

使用 `od`（<ruby> 八进制转储 <rt>  octal dump </rt></ruby>）命令可以很容易地识别文件是 DOS 格式还是 Unix 格式，如下图所示：

```
# od -bc windows.txt
0000000 125 156 151 170 040 151 163 040 141 040 146 162 145 145 040 157
U n i x i s a f r e e o
0000020 160 145 156 163 157 165 162 143 145 040 157 160 145 162 141 164
p e n s o u r c e o p e r a t
0000040 151 156 147 040 163 171 163 164 145 155 015 012 123 165 160 145
i n g s y s t e m \r \n S u p e
0000060 162 040 143 157 155 160 165 164 145 162 163 040 141 162 145 040
r c o m p u t e r s a r e
0000100 162 165 156 156 151 156 147 040 157 156 040 125 116 111 130 015
r u n n i n g o n U N I X \r
0000120 012 071 065 045 040 157 146 040 167 145 142 163 151 164 145 163
\n 9 5 % o f w e b s i t e s
0000140 040 141 162 145 040 162 165 156 156 151 156 147 040 157 156 040
a r e r u n n i n g o n
0000160 114 151 156 165 170 040 117 123 015 012 101 156 171 164 150 151
L i n u x O S \r \n A n y t h i
0000200 156 147 040 143 141 156 040 142 145 040 144 157 156 145 040 157
n g c a n b e d o n e o
0000220 156 040 114 151 156 165 170 015 012
n L i n u x \r \n
0000231

```

上面的输出清楚地表明这是一个 DOS 格式的文件，因为它包含了转义序列 `\r\n`。

同时，当你在终端上打印文件输出时，你会得到下面的输出：

```
# cat windows.txt
Unix is a free opensource operating system
Super computers are running on UNIX
95% of websites are running on Linux OS
Anything can be done on Linux

```

### 如何在 Linux 上安装 dos2unix？

`dos2unix` 可以很容易地从发行版的官方仓库中安装。

对于 RHEL/CentOS 6/7 系统，使用 [yum 命令](https://www.2daygeek.com/linux-yum-command-examples-manage-packages-rhel-centos-systems/) 安装 `dos2unix`。

```
$ sudo yum install -y dos2unix

```

对于 RHEL/CentOS 8 和 Fedora 系统，使用 [dnf 命令](https://www.2daygeek.com/linux-dnf-command-examples-manage-packages-fedora-centos-rhel-systems/) 安装 `dos2unix`。

```
$ sudo yum install -y dos2unix

```

对于基于 Debian 的系统，使用 [apt 命令](https://www.2daygeek.com/apt-command-examples-manage-packages-debian-ubuntu-systems/) 或 [apt-get 命令](https://www.2daygeek.com/apt-get-apt-cache-command-examples-manage-packages-debian-ubuntu-systems/) 来安装 `dos2unix`。

```
$ sudo apt-get update
$ sudo apt-get install dos2unix

```

对于 openSUSE 系统，使用 [zypper命令](https://www.2daygeek.com/zypper-command-examples-manage-packages-opensuse-system/) 安装 `dos2unix`。

```
$ sudo zypper install -y dos2unix

```

### 1）如何将 DOS 文件转换为 UNIX 格式？

以下命令将 `windows.txt` 文件从 DOS 转换为 Unix 格式。

对该文件的修改是删除文件每行的 `\r`。

```
# dos2unix windows.txt
dos2unix: converting file windows.txt to Unix format …

```

```
# cat windows.txt
0000000 125 156 151 170 040 151 163 040 141 040 146 162 145 145 040 157
U n i x i s a f r e e o
0000020 160 145 156 163 157 165 162 143 145 040 157 160 145 162 141 164
p e n s o u r c e o p e r a t
0000040 151 156 147 040 163 171 163 164 145 155 012 123 165 160 145 162
i n g s y s t e m \n S u p e r
0000060 040 143 157 155 160 165 164 145 162 163 040 141 162 145 040 162
c o m p u t e r s a r e r
0000100 165 156 156 151 156 147 040 157 156 040 125 116 111 130 012 071
u n n i n g o n U N I X \n 9
0000120 065 045 040 157 146 040 167 145 142 163 151 164 145 163 040 141
5 % o f w e b s i t e s a
0000140 162 145 040 162 165 156 156 151 156 147 040 157 156 040 114 151
r e r u n n i n g o n L i
0000160 156 165 170 040 117 123 012 101 156 171 164 150 151 156 147 040
n u x O S \n A n y t h i n g
0000200 143 141 156 040 142 145 040 144 157 156 145 040 157 156 040 114
c a n b e d o n e o n L
0000220 151 156 165 170 012
i n u x \n
0000225

```

上面的命令将覆盖原始文件。

如果你想保留原始文件，请使用以下命令。这将把转换后的输出保存为一个新文件。

```
# dos2unix -n windows.txt unix.txt
dos2unix: converting file windows.txt to file unix.txt in Unix format …

```

#### 1a）如何使用 tr 命令将 DOS 文件转换为 UNIX 格式。

正如文章开头所讨论的，你可以如下所示使用 `tr` 命令将 DOS 文件转换为 Unix 格式。

```
Syntax: tr -d '\r' < source_file > output_file

```

下面的 `tr` 命令将 DOS 格式的文件 `windows.txt` 转换为 Unix 格式文件 `unix.txt`。

```
# tr -d '\r' < windows.txt >unix.txt

```

注意：不能使用 `tr` 命令将文件从 Unix 格式转换为 Windows（DOS）。

#### 1b）如何使用 awk 命令将 DOS 文件转换为 UNIX 格式。

使用以下 `awk` 命令格式将 DOS 文件转换为 Unix 格式。

```
Syntax: awk '{ sub("\r$", ""); print }' source_file.txt > output_file.txt

```

以下 `awk` 命令将 DOS 文件 `windows.txt` 转换为 Unix 格式文件 `unix.txt`。

```
# awk '{ sub("\r$", ""); print }' windows.txt > unix.txt

```

### 2）如何将 UNIX 文件转换为 DOS 格式？

当你把一个文件从 UNIX 转换为 DOS 格式时，它会在每一行中添加一个回车（`CR` 或 `\r`）。

```
# unix2dos unix.txt
unix2dos: converting file unix.txt to DOS format …

```

该命令将保留原始文件。

```
# unix2dos -n unix.txt windows.txt
unix2dos: converting file unix.txt to file windows.txt in DOS format …

```

#### 2a）如何使用 awk 命令将 UNIX 文件转换为 DOS 格式？

使用以下 `awk` 命令格式将 UNIX 文件转换为 DOS 格式。

```
Syntax: awk 'sub("$", "\r")' source_file.txt > output_file.txt

```

下面的 `awk` 命令将 `unix.txt` 文件转换为 DOS 格式文件 `windows.txt`。

```
# awk 'sub("$", "\r")' unix.txt > windows.txt

```

---

via: <https://www.2daygeek.com/how-to-convert-text-files-between-unix-and-dos-windows-formats/>

作者：[Magesh Maruthamuthu](https://www.2daygeek.com/author/magesh/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


#新闻拍一拍# 美国 AI 战机击败人类空军飞行员

Summary: • 全球比特币挖矿电力消耗突破 7 千兆瓦 • AI 从 NASA 的旧数据里识别出 50 颗新行星

# #新闻拍一拍# 美国 AI 战机击败人类空军飞行员

<img src="content_image/album_202008_28_081805p9cld0od809lou9o.jpg" alt="" title="">

#### 美国 AI 战机击败人类空军飞行员

近日，美国军事研究部门 DARPA 举办了一场人工智能 VS 人类的 “模拟空战比赛”，该比赛借助美国空军使用的飞行模拟器进行。最终，一个被称为 Falco 的人工智能战斗机在一系列虚拟空战中击败了一名战场经验丰富的美国空军教官。 Heron Systems 公司则表示，他们的 AI 空战模型通过模拟训练，已经积累了相当于一名人类飞行员 30 年的飞行经验。

来源：[开源中国](https://www.oschina.net/news/118195/ai-beats-f16-pilot "https://www.oschina.net/news/118195/ai-beats-f16-pilot")

>
> 拍一拍：AI 会逐渐在许多方面超越人类，令人担忧的“天网”或许不远了。
>
>
>

#### 全球比特币挖矿电力消耗突破 7 千兆瓦

今年与比特币相关的电力消耗达到了历史新高，全球挖矿业使用了超过 7 千兆瓦（7 GW）的电力（约 63.32太瓦时）。这个功率大致相当于 7 座核电站或 2180 万块太阳能电池板的功率。中国处于领先地位，为全球平均每月哈希值贡献了 65.08%。

来源：[cnBeta.COM](https://www.cnbeta.com/articles/tech/1021267.htm "https://www.cnbeta.com/articles/tech/1021267.htm")

>
> 拍一拍：希望中国不仅仅是“矿产”大国，也在区块链技术和理论上取得更大成就。
>
>
>

#### AI 从 NASA 的旧数据里识别出 50 颗新行星

华威大学的天文学家和计算机科学家构建了一个机器学习算法，用 NASA 开普勒太空望远镜收集的数据进行训练，一旦算法学会区分真实行星和假阳性，他们将其用于分析尚未证实的旧数据集，识别了 50 颗新的系外行星。

来源：[solidot](https://www.solidot.org/story?sid=65372 "https://www.solidot.org/story?sid=65372")

>
> 拍一拍：说不得可以利用 AI 进行更多的“变废为宝”。
>
>
>


把 Linux 上的文件列表和排序玩出花来

# 把 Linux 上的文件列表和排序玩出花来

<img src="content_image/album_202008_28_213742y8cxnbnjpopzd5j0.jpg" alt="" title="">

>
> Linux 命令可以提供文件的详细信息，也可以自定义显示的文件列表，甚至可以深入到文件系统的目录中，只要你愿意看。
>
>
>

在 Linux 系统上，有许多方法可以列出文件并显示它们的信息。这篇文章回顾了一些提供文件细节的命令，并提供了自定义文件列表的选项，以满足你的需求。

大多数命令都会列出单个目录中的文件，而其他命令则可以深入到文件系统的目录中，只要你愿意看。

当然，最主要的文件列表命令是 `ls`。然而，这个命令有大量的选项，可以只查找和列出你想看的文件。另外，还有 `find` 可以帮助你进行非常具体的文件搜索。

### 按名称列出文件

最简单的方法是使用 `ls` 命令按名称列出文件。毕竟，按名称（字母数字顺序）列出文件是默认的。你可以选择 `ls`（无细节）或 `ls -l`（大量细节）来决定你看到什么。

```
$ ls | head -6
8pgs.pdf
Aesthetics_Thank_You.pdf
alien.pdf
Annual_Meeting_Agenda-20190602.pdf
bigfile.bz2
bin
$ ls -l | head -6
-rw-rw-r--  1 shs     shs      10886 Mar 22  2019 8pgs.pdf
-rw-rw-r--  1 shs     shs     284003 May 11  2019 Aesthetics_Thank_You.pdf
-rw-rw-r--  1 shs     shs      38282 Jan 24  2019 alien.pdf
-rw-rw-r--  1 shs     shs      97358 May 19  2019 Annual_Meeting_20190602.pdf
-rw-rw-r--  1 shs     shs   18115234 Apr 16 17:36 bigfile.bz2
drwxrwxr-x  4 shs     shs    8052736 Jul 10 13:17 bin

```

如果你想一次查看一屏的列表，可以将 `ls` 的输出用管道送到 `more` 命令中。

### 按相反的名字顺序排列文件

要按名称反转文件列表，请添加 `-r`（<ruby> 反转 <rt>  Reverse </rt></ruby>）选项。这就像把正常的列表倒过来一样。

```
$ ls -r
$ ls -lr

```

### 按文件扩展名列出文件

`ls` 命令不会按内容分析文件类型，它只会处理文件名。不过，有一个命令选项可以按扩展名列出文件。如果你添加了 `-X` （<ruby> 扩展名 <rt>  eXtension </rt></ruby>）选项，`ls` 将在每个扩展名类别中按名称对文件进行排序。例如，它将首先列出没有扩展名的文件（按字母数字顺序），然后是扩展名为 `.1`、`.bz2`、`.c` 等的文件。

### 只列出目录

默认情况下，`ls` 命令将同时显示文件和目录。如果你想只列出目录，你可以使用 `-d`（<ruby> 目录 <rt>  Directory </rt></ruby>）选项。你会得到一个像这样的列表：

```
$ ls -d */
1/     backups/     modules/       projects/     templates/
2/     html/        patches/       public/       videos/
bin/   new/         private/       save/

```

### 按大小排列文件

如果你想按大小顺序列出文件，请添加 `-S`（<ruby> 大小 <rt>  Size </rt></ruby>）选项。但请注意，这实际上不会显示文件的大小（以及其他文件的细节），除非你还添加 `-l`（<ruby> 长列表 <rt>  Long listing </rt></ruby>）选项。当按大小列出文件时，一般来说，看到命令在按你的要求做事情是很有帮助的。注意，默认情况下是先显示最大的文件。添加 `-r` 选项可以反过来（即 `ls -lSr`）。

```
$ ls -lS
total 959492
-rw-rw-r--  1 shs   shs  357679381 Sep 19  2019 sav-linux-free-9.tgz
-rw-rw-r--  1 shs   shs  103270400 Apr 16 17:38 bigfile
-rw-rw-r--  1 shs   shs   79117862 Oct  5  2019 Nessus-8.7.1-ubuntu1110_amd64.deb

```

### 按属主列出文件

如果你想按属主列出文件（例如，在一个共享目录中），你可以把 `ls` 命令的输出传给 `sort`，并通过添加 `-k3` 来按第三个字段排序，从而挑出属主一栏。

```
$ ls -l | sort -k3 | more
total 56
-rw-rw-r-- 1 dory  shs      0 Aug 23 12:27 tasklist
drwx------ 2 gdm   gdm   4096 Aug 21 17:12 tracker-extract-files.121
srwxr-xr-x 1 root  root     0 Aug 21 17:12 ntf_listenerc0c6b8b4567
drwxr-xr-x 2 root  root  4096 Aug 21 17:12 hsperfdata_root
              ^
              |

```

事实上，你可以用这种方式对任何字段进行排序（例如，年份）。只是要注意，如果你要对一个数字字段进行排序，则要加上一个 `n`，如 `-k5n`，否则你将按字母数字顺序进行排序。这种排序技术对于文件内容的排序也很有用，而不仅仅是用于列出文件。

### 按年份排列文件

使用 `-t`（<ruby> 修改时间 <rt>  Time modified </rt></ruby>）选项按年份顺序列出文件 —— 它们的新旧程度。添加 `-r` 选项，让最近更新的文件在列表中最后显示。我使用这个别名来显示我最近更新的文件列表。

```
$ alias recent='ls -ltr | tail -8'

```

请注意，文件的更改时间和修改时间是不同的。`-c`（<ruby> 更改时间 <rt>  time Changed </rt></ruby>）和 `-t`（修改时间）选项的结果并不总是相同。如果你改变了一个文件的权限，而没有改变其他内容，`-c` 会把这个文件放在 `ls` 输出的顶部，而 `-t` 则不会。如果你想知道其中的区别，可以看看 `stat` 命令的输出。

```
$ stat ckacct
  File: ckacct
  Size: 200             Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d      Inode: 829041      Links: 1
Access: (0750/-rwxr-x---)  Uid: ( 1000/     shs)   Gid: ( 1000/     shs)
Access: 2020-08-20 16:10:11.063015008 -0400
Modify: 2020-08-17 07:26:34.579922297 -0400 <== content changes
Change: 2020-08-24 09:36:51.699775940 -0400 <== content or permissions changes
 Birth: -

```

### 按组别列出文件

要按关联的组别对文件进行排序，你可以将一个长列表的输出传给 `sort` 命令，并告诉它在第 4 列进行排序。

```
$ ls -l | sort -k4

```

### 按访问日期列出文件

要按访问日期（最近访问的日期在前）列出文件，使用 `-ltu` 选项。`u` 强制“按访问日期”排列顺序。

```
$ ls -ltu
total 959500
-rwxr-x---  1 shs     shs        200 Aug 24 09:42 ckacct  <== most recently used
-rw-rw-r--  1 shs     shs       1335 Aug 23 17:45 lte

```

### 单行列出多个文件

有时，精简的文件列表更适合手头的任务。`ls` 命令甚至有这方面的选项。为了在尽可能少的行上列出文件，你可以使用 `--format=comma` 来用逗号分隔文件名，就像这个命令一样：

```
$ ls --format=comma
1, 10, 11, 12, 124, 13, 14, 15, 16pgs-landscape.pdf, 16pgs.pdf, 17, 18, 19,
192.168.0.4, 2, 20, 2018-12-23_OoS_2.pdf, 2018-12-23_OoS.pdf, 20190512_OoS.pdf,
'2019_HOHO_application working.pdf' …

```

喜欢用空格？使用 `--format=across` 代替。

```
$ ls --format=across z*
z              zip            zipfiles      zipfiles1.bat   zipfiles2.bat
zipfiles3.bat  zipfiles4.bat  zipfiles.bat  zoom_amd64.deb  zoomap.pdf
zoom-mtg

```

### 增加搜索的深度

虽然 `ls` 一般只列出单个目录中的文件，但你可以选择使用 `-R` 选项（<ruby> 递归 <rt>  Recursively </rt></ruby>）地列出文件，深入到整个目录的深处。

```
$ ls -R zzzzz | grep -v "^$"
zzzzz:
zzzz
zzzzz/zzzz:
zzz
zzzzz/zzzz/zzz:
zz
zzzzz/zzzz/zzz/zz:
z
zzzzz/zzzz/zzz/zz/z:
sleeping

```

另外，你也可以使用 `find` 命令，对深度进行限制或不限制。在这个命令中，我们指示 `find` 命令只在三个层次的目录中查找：

```
$ find zzzzz -maxdepth 3
zzzzz
zzzzz/zzzz
zzzzz/zzzz/zzz
zzzzz/zzzz/zzz/zz

```

### 选择 ls 还是 find

当你需要列出符合具体要求的文件时，`find` 命令可能是比 `ls` 更好的工具。

与 `ls` 不同的是，`find` 命令会尽可能地深入查找，除非你限制它。它还有许多其他选项和一个 `-exec` 子命令，允许在找到你要找的文件后采取一些特定的行动。

### 总结

`ls` 命令有很多用于列出文件的选项。了解一下它们。你可能会发现一些你会喜欢的选项。

---

via: <https://www.networkworld.com/article/3572590/11-ways-to-list-and-sort-files-on-linux.html>

作者：[Sandra Henry-Stocker](https://www.networkworld.com/author/Sandra-Henry_Stocker/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


对开放的价值观持开放态度

Summary: 开放管理可能会让人感到恐惧。一位经理人解释了为什么值得冒这个风险。

开放管理可能会让人感到恐惧。一位经理人解释了为什么值得冒这个风险。

# 对开放的价值观持开放态度

>
> 开放管理可能会让人感到恐惧。一位经理人解释了为什么值得冒这个风险。
>
>
>

<img src="content_image/album_202008_28_234546lssm47dit4ti0lbi.png" alt="Open Lego CAD" title="Open Lego CAD">

在本期的“[用开放的价值观管理](https://opensource.com/open-organization/managing-with-open-values)”系列中，我和美国一家全国性保险公司的定价总监、人事经理 Braxton 聊了聊。

2018 年 6 月，Braxton 联系到了开放组织社区的红帽人员。他想了解更多关于他*和*他的团队如何使用开放的价值观，以不同的方式工作。我们很乐意提供帮助。于是我帮助 Braxton 和他的团队组织了一个关于[开放组织原则](https://github.com/open-organization/open-org-definition)的研讨会，并在之后还保持着联系，这样我就可以了解他在变得更加开放的过程中的风险。

最近我们采访了 Braxton，并和他一起坐下来听了事情的进展。[产业/组织心理学家和员工参与度专家](https://opensource.com/open-organization/20/5/commitment-engagement-org-psychology) Tracy Guiliani 和 [Bryan Behrenshausen](https://opensource.com/users/bbehrens) 一起加入了采访。我们的谈话范围很广，探讨了了解开源价值观后的感受，如何利用它们来改变组织，以及它们如何帮助 Braxton 和他的团队更好地工作和提高参与度。

与 Braxton 合作是一次异常有意义的经历。它让我们直接见证了一个人如何将开放组织社区驱动的研讨会材料融入动态变化，并使他、他的团队和他的组织受益。开放组织大使*一直*在寻求帮助人们获得关于开放价值的见解和知识，使他们能够理解文化变革和[自己组织内的转型](https://opensource.com/open-organization/18/4/rethinking-ownership-across-organization)。

他和他的团队正在以对他们有效的方式执行他们独特的开放价值观，并且让团队实现的利益超过了提议变革在时间和精力上的投入。

Braxton 对开放组织原则的*解释*和使组织更加开放的策略，让我们深受启发。

Braxton 承认，他的更开放的目标并不包括“制造另一个红帽”。相反，他和他的团队是在以对他们有效的方式，以及让团队实现的利益超过提议的变革所带来的时间和精力投入，来执行他们独特的开放价值观。

在我们采访的第一部分，你还会听到 Braxton 描述：

1. 在了解了透明性、协作性、适应性、社区性和包容性这五种开放式组织价值观之后，“开放式管理”对他意味着什么？
2. 他的一些开放式管理做法。
3. 他如何在他的团队中倡导开放文化，如何在后来者中鼓励开源价值观，以及他所体验到的好处。
4. 当人们试图改造自己的组织时，对开源价值观最大的误解是什么？

[收听对 Braxton 的采访：](https://opensource.com/sites/default/files/images/open-org/braxton_1.ogg)

---

via: <https://opensource.com/open-organization/20/8/being-open-to-open-values>

作者：[Heidi Hess von Ludewig](https://opensource.com/users/heidi-hess-von-ludewig) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Summary: • 恶意 npm 软件包试图窃取敏感的 Discord 和浏览器文件 • 苹果阻止了 Facebook 应用更新，要求征收内购的 30% 销售税

# #新闻拍一拍# Safari 将采用 Chrome/Firefox 相同的 WebExtensions API

<img src="content_image/album_202008_29_083053jfxbmionznj2cnk0.jpg" alt="" title="">

#### Safari 将采用 Chrome/Firefox 相同的 WebExtensions API

Chrome 有着庞大的扩展生态系统，而随着所有主流浏览器都采用 WebExtensions API，这一扩展技术已成为事实上的标准，这也方便用户从一个浏览器切换到另一个浏览器。Firefox 是从 v57 开始正式采用 WebExtensions API 的。

来源：[solidot](https://www.solidot.org/story?sid=65376 "https://www.solidot.org/story?sid=65376")

>
> 拍一拍：主要浏览器能支持一致的扩展 API，这是一件大好事。
>
>
>

#### 恶意 npm 软件包试图窃取敏感的 Discord 和浏览器文件

该恶意包是一个名为 `fallguys` 的 JavaScript 库，它声称提供了一个《Fall Guys: Ultimate Knockout》游戏 API 的接口。这段代码会试图访问 5 个本地文件，读取它们的内容，然后将数据发布在 Discord 频道里面。npm 安全团队已经从 npm 门户网站上删除了它。

来源：[zdnet](https://www.zdnet.com/article/malicious-npm-package-caught-trying-to-steal-sensitive-discord-and-browser-files/ "https://www.zdnet.com/article/malicious-npm-package-caught-trying-to-steal-sensitive-discord-and-browser-files/")

>
> 拍一拍：即便是开源的软件包，也不能轻易相信一定经过了审查，也不一定有人替你做过审查。
>
>
>

#### 苹果阻止了 Facebook 应用更新，要求征收内购的 30% 销售税

Facebook 表示，这次更新是“一种新的货币化在线直播活动的方式，通过一次性的访问费用，在客人注册参加时收取”。但苹果以“不相关”信息为由拒绝了这一更新。该公司要求苹果免除 iOS 应用内购买费 30%，这样所有收入就可以归活动主办方所有。然而，苹果拒绝了。

来源：[zdnet](https://www.zdnet.com/article/apple-stops-facebook-update-calling-out-30-sales-tax/ "https://www.zdnet.com/article/apple-stops-facebook-update-calling-out-30-sales-tax/")

>
> 拍一拍：“甭管是谁，在我苹果上的地盘都得听我的！”
>
>
>


去中心化的消息应用 Riot 改名为 Element

微软附体啊

# 去中心化的消息应用 Riot 改名为 Element

Riot 曾经是，现在也是一款基于开源 Matrix 协议的去中心化即时通讯应用。

6 月底，Riot 即时通讯客户端宣布将改名。他们透露，他们的新名字是 [Element](https://element.io/)。让我们来看看 Riot 为什么要改名，还有哪些要改。

### 为什么从 Riot 改名为 Element？

在说到最新的公告之前，我们先来看看他们当初为什么要改名。

根据 6 月 23 日的一篇[博客文章](https://element.io/blog/the-world-is-changing/)，该组织改名有三个原因。

首先，他们表示“某大型游戏公司”曾多次阻止他们注册 Riot 和 [Riot.im](http://Riot.im) 产品名称的商标。如果要我猜的话，他们可能指的就是这家[“游戏公司”](https://en.wikipedia.org/wiki/Riot_Games)）。

其次，他们选择 Riot 这个名字的初衷是为了“唤起一些破坏性和活力的东西”。他们担心人们反而认为这个应用是“专注于暴力”。我想，当前的情形下，这个名字并不算好。

第三，他们希望澄清 Riot 涉及的众多品牌名称所造成的混乱。例如，Riot 是由一家名为 New Vector 的公司创建的，而 Riot 是托管在 Modular 上，Modular 也是 New Vector 的产品。他们希望简化他们的命名系统，以避免混淆潜在客户。当人们寻找消息解决方案时，他们希望他们只需要寻找一个名字：Element。

### 元素即一切

从 7 月 15 日开始，该应用的名称和公司的名称已经改为 Element（元素）。他们的 Matrix 托管服务现在将被称为 Element Matrix Services。他们的公告很好地总结了这一点。

>
> “对于那些第一次发现我们的人来说，Element 是 Matrix 通信网络中的旗舰级安全协作应用。Element 让你拥有自己的端到端加密聊天服务器，同时还能与更广泛的 Matrix 网络中的其他人连接。”
>
>
>

他们之所以选择 Element 这个名字，是因为它“反映了我们在设计 RiotX 时对简单和清晰的强调；这个名字突出了我们一心一意将 Element 打造成可以想象的最优雅和最实用的主流通讯应用的使命”。他们还说，他们想要一个“能唤起数据所有权和自我主权的概念”的名字。他们还认为这是一个很酷的名字。

### 除了改个名之外

最近的公告也表明，此举不仅仅是简单的改名。Element 还发布了“新一代安卓版 Matrix 客户端”。该客户端的前身是 RiotX，现在改名为 Element。（还有呢？）它对以前的客户端进行了彻底的重写，现在支持 VoIP 通话和小部件。Element 还将在 iOS 上推出，支持 iOS 13，并提供“全新的推送通知支持”。

Element Web 客户端也得到了一些关爱，更新了 UI 和新的更容易阅读的字体。他们还“重写了房间列表控件 —— 增加了房间预览（!!）、按字母顺序排列、可调整列表大小、改进的通知用户界面等”。他们还开始努力改进端到端加密。

### 最后思考

Element 公司的人迈出了一大步，做出了这样的重大改名。他们可能会在短期内失去一些客户。（这可能主要是由于出于某种原因没有意识到名称的改变，或者不喜欢改变）。然而从长远来看，品牌简化将帮助他们脱颖而出。

我唯一要提到的负面说明是，这是他们在该应用历史上的第三次改名。在 2016 年发布时，它最初被命名为 Vector。当年晚些时候改名为 Riot。希望 Element 能一直用下去。

---

via: <https://itsfoss.com/riot-to-element/>

作者：[John Paul](https://itsfoss.com/author/john/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OnionShare：一个安全共享文件的开源工具

# OnionShare：一个安全共享文件的开源工具

>
> OnionShare 是一个自由开源工具，它利用 Tor 网络安全和匿名地共享文件。
>
>
>

已经有很多在线服务可以安全地共享文件，但它可能不是完全匿名的。

此外，你必须依靠一个集中式服务来共享文件，如果服务决定像 [Firefox Send](https://itsfoss.com/firefox-send/) 那样关闭，那你不能真正依靠它来一直安全地共享文件。

考虑到这些，OnionShare 是一个让人惊叹的开源工具，它让你使用 [Tor Onion 服务](https://community.torproject.org/onion-services/)来共享文件。它应该是所有云端文件共享服务的一个很好的替代品。

让我们来看看它提供了什么以及它是如何工作的。

### OnionShare: 通过 Tor 匿名分享文件

[OnionShare](https://onionshare.org/) 是一款有趣的开源工具，可用于 Linux、Windows 和 macOS。

它可以让你安全地将文件直接从你的电脑分享给接收者，而不会在这个过程中暴露你的身份。你不必注册任何帐户，它也不依赖于任何集中式存储服务。

它基本上是在 Tor 网络上的点对点服务。接收者只需要有一个 [Tor 浏览器](https://itsfoss.com/install-tar-browser-linux/)就可以下载/上传文件到你的电脑上。如果你好奇的话，我也建议你去看看我们的 [Tor 指南](https://itsfoss.com/tor-guide/)来探索更多关于它的内容。

让我们来看看它的功能。

### OnionShare 的功能

对于一个只想要安全和匿名的普通用户来说，它不需要调整。不过，如果你有需要，它也有一些高级选项。

* 跨平台支持（Windows、macOS和 Linux）。
* 发送文件
* 接收文件
* 命令行选项
* 发布洋葱站点
* 能够使用桥接（如果你的 Tor 连接不起作用）
* 能够使用持久 URL 进行共享（高级用户）。
* 隐身模式（更安全）

你可以通过 GitHub 上的[官方用户指南](https://github.com/micahflee/onionshare/wiki)来了解更多关于它们的信息。

### 在 Linux 上安装 OnionShare

你应该可以在你的软件中心找到 OnionShare 并安装它。如果没有，你可以在 Ubuntu 发行版上使用下面的命令添加 PPA：

```
sudo add-apt-repository ppa:micahflee/ppa
sudo apt update
sudo apt install -y onionshare

```

如果你想把它安装在其他 Linux 发行版上，你可以访问[官方网站](https://onionshare.org/)获取 Fedora 上的安装说明以及构建说明。

* [下载 OnionShare](https://onionshare.org/)

### OnionShare 如何工作？

当你安装好后，一切都很明了且易于使用。但是，如果你想开始，让我告诉你它是如何工作的。

完成后，它加载并连接到 Tor 网络。

#### 共享文件

你只需要在电脑上添加你要分享的文件，然后点击 “**Start sharing**”。

完成后，右下角的状态应该是 “**Sharing**”，然后会生成一个 **OnionShare 地址**（自动复制到剪贴板），如下图所示。

现在接收方需要的是 OnionShare 的地址，它看上去是这样的。

```
http://onionshare:xyz@jumbo2127k6nekzqpff2p2zcxcsrygbnxbitsgnjcfa6v47wvyd.onion

```

接着 Tor 浏览器开始下载文件。

值得注意的是，下载完成后（文件传输完成），文件共享就会停止。到时候也会通知你。

所以，如果你要再次分享或与他人分享，你必须重新分享，并将新的 OnionShare 地址发送给接收者。

#### 允许接收文件

如果你想生成一个 URL，让别人直接上传文件到你的电脑上（要注意你与谁分享），你可以在启动 OnionShare 后点击 **Receive Files** 标签即可。

你只需要点击 “**Start Receive Mode**” 按钮就可以开始了。接下来，你会得到一个 OnionShare 地址（就像共享文件时一样）。

接收者必须使用 Tor 浏览器访问它并开始上传文件。它应该像下面这样：

虽然当有人上传文件到你的电脑上时，你会收到文件传输的通知，但完成后，你需要手动停止接收模式。

#### 下载/上传文件

考虑到你已经安装了 Tor 浏览器，你只需要在 URL 地址中输入 OnionShare 的地址，确认登录（按 OK 键），它看上去像这样。

同样，当你得到一个上传文件的地址时，它看上去是这样的。

#### 发布洋葱站点

如果你想的话，你可以直接添加文件来托管一个静态的洋葱网站。当然，正因为是点对点的连接，所以在它从你的电脑上传输每个文件时，加载速度会非常慢。

我试着用[免费模板](https://www.styleshout.com/free-templates/kards/)测试了一下，效果很好（但很慢）。所以，这可能取决于你的网络连接。

### 总结

除了上面提到的功能，如果需要的话，你还可以使用命令行进行一些高级的调整。

OnionShare 的确是一款令人印象深刻的开源工具，它可以让你轻松地匿名分享文件，而不需要任何特殊的调整。

你尝试过 OnionShare 吗？你知道有类似的软件么？请在下面的评论中告诉我！

---

via: <https://itsfoss.com/onionshare/>

作者：[Ankush Das](https://itsfoss.com/author/ankush/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


#新闻拍一拍# 建行短暂测试数字货币

Summary: • PyPy 和软件自由保护组织（SFC）终止双方长达十年的合作关系 • Fedora 34 计划通过提升压缩率减少安装媒介体积

# #新闻拍一拍# 建行短暂测试数字货币

<img src="content_image/album_202008_30_114417c3dsnvms7nm3smm9.jpg" alt="" title="">

#### 建行短暂测试数字货币

8 月 29 日，中国建设银行在其官方 App 开通“数字人民币钱包”。建行客服称，“数字货币相关产品目前仍处于研发阶段，当天下午仅受邀客户体验测试。对于已开通钱包的账户，系统自动注销处理，用户转入的款项将在8 月 30 日之前退回原储蓄账户”。目前的试点测试，还只是研发过程中的常规性工作，并不意味着数字人民币正式落地发行，何时正式推出尚没有时间表。

来源：[网易科技](https://tech.163.com/20/0830/08/FL924VN100097U7R.html "https://tech.163.com/20/0830/08/FL924VN100097U7R.html")

>
> 拍一拍：对于数字货币（不是加密货币），外界关注度非常高，但是我认为，目前不必寄予太高的期望，或许这是个生不逢时的产物。
>
>
>

#### PyPy 和软件自由保护组织（SFC）终止双方长达十年的合作关系

PyPy 是用 Python 实现的 Python 解释器。SFC 是一个旨在为自由开源软件项目提供支持和基础设施的非营利组织，它代表成员项目接受捐赠，并提供财政监督。Git、phpMyAdmin、QEMU 和 Wine 等项目都是 SFC 的成员。PyPy 接着发公告，正式宣布成为同样是为社区提供财务支持的组织 Open Collective 的会员。

来源：[开源中国](https://www.oschina.net/news/118248/pypy-from-sfc-to-open-collective "https://www.oschina.net/news/118248/pypy-from-sfc-to-open-collective")

>
> 拍一拍：看来 Open Collective 赢得了更多信任。要是中国开源社区也有类似的服务项目就好了。
>
>
>

#### Fedora 34 计划通过提升压缩率减少安装媒介体积

目前的计划是提升安装媒介上 SquashFS 文件系统的压缩率。红帽 Bohdan Khomutskyi 的方案是考虑使用 XZ 压缩、块大小设置为 1MB，并且不使用 BCJ 过滤器。安装时间应大约会延长 6.5%（24 秒），但对于 Fedora 安装媒介来说，可节省大约 142MiB 的空间。

来源：[开源中国](https://www.oschina.net/news/118226/fedora-34-install-compress "https://www.oschina.net/news/118226/fedora-34-install-compress")

>
> 拍一拍：每减少的一个字节都是为这个世界节约一份能源。
>
>
>


九个用来构建容错系统的开源工具

Summary: 这些开源工具可以最大化延长运行时间并且在最大程度上减少问题。

这些开源工具可以最大化延长运行时间并且在最大程度上减少问题。

# 九个用来构建容错系统的开源工具

>
> 这些开源工具可以最大化延长运行时间并且在最大程度上减少问题。
>
>
>

我一直对 Web 开发和软件体系结构很感兴趣，因为我喜欢看到一个工作系统的宏观视图。无论是构建一个移动应用程序还是一个 Web 应用程序，都必须连接到互联网，在不同的模块中交换数据，这意味着你需要 Web 服务。

如果选择云系统作为应用程序的后端，则可以利用更强大的计算能力，因为后端服务将会在水平和垂直方向上进行扩展并编排不同的服务。但无论你是否使用云后端，建造一个灵活、稳定、快速又安全的容错系统是必不可少的。

要了解容错系统，让我们以脸书、亚马逊、谷歌和奈飞为例。数以亿计的用户会同时接入这些平台并通过对等网络和用户-服务器网络传输大量数据，你可以肯定这其中还存在许多的带有不法目的的恶意用户，例如黑客攻击和拒绝服务（DoS）攻击。即使如此，这些平台无需停机也可以全年无休地运转。

虽然机器学习和智能算法是这些系统的基础，但它们实现持续的服务而不停机一分钟的事实值得称赞。它们昂贵的硬件设备和巨大的数据中心当然十分重要，但是支持服务的精密软件设计也同样重要。而且容错系统是一个构建如此精密系统的法则之一。

### 生产过程中导致错误的两种行为

这是考虑容错系统的另一种方法。当你在本地运行应用程序服务时，每件事似乎都很完美。棒极了！但当你提升服务到生产环境时，一切都会变得一团糟。在这种情况下，容错系统通过解决两个问题来提供帮助：故障停止行为和拜占庭行为。

#### 故障停止行为

故障停止行为是运行中系统突然停止运行或者系统中的某些部分发生了故障。服务器停机时间和数据库不可访问都属于此种类型。举个例子，在下图中，由于服务 2 无法访问，因此服务 1 无法与服务 2 进行通信。

但是，如果服务之间存在网络问题，也会出现此问题，如下图所示：

#### 拜占庭行为

拜占庭行为是指系统在持续运行，但并没有产生预期行为（例如：错误的数据或者无效的数据）。

如果服务 2 的数据（值）已损坏则可能会发生拜占庭故障，即使服务看起来运行得很好，比如下面的例子:

或者，可能存在恶意的中间人在服务之间进行拦截，并注入了不需要的数据：

无论是故障停止和拜占庭行为，都不是理想的情况，因此我们需要一些预防或修复它们的手段。这里容错系统就起作用了。以下是可以帮助你解决这些问题的 8 个开源工具。

### 构建容错系统的工具

尽管构建一个真正实用的容错系统涉及到深入的“分布式计算理论”和复杂的计算机科学原理，但有许多的软件工具（其中许多是开源软件）通过构建容错系统来减轻不良后果的影响。

#### 断路模式：Hystrix 和 Resilience4j

[断路模式](https://martinfowler.com/bliki/CircuitBreaker.html)是一种技术，它有助于在服务失败时返回准备好的虚拟回应或者简单回应。

奈飞开源的 [Hystrix](https://github.com/Netflix/Hystrix/wiki) 是断路模式中最流行的应用。

我之前工作过的很多家公司都在用这款出色的工具。令人意外的是，奈飞宣布将不再更新 Hystrix（是的，我知道了）。相反，奈飞建议使用另一种支持 Java 8 和函数式编程的 [Resilence4j](https://github.com/resilience4j/resilience4j) 之类的替代解决方案，或者类似于 [Adaptive Concurrency Limit](https://medium.com/@NetflixTechBlog/performance-under-load-3e6fa9a60581) 的替代解决方案。

#### 负载均衡：Nginx 和 HaProxy

负载均衡是分布式系统中最基本的概念之一，要想拥有一个生产质量的环境，必须有负载均衡的存在。要理解负载均衡器，首先我们需要明白冗余的概念。每个生产级的 Web 服务都有多个服务器在某个服务器宕机时提供冗余来接管和维持服务。

想想现代飞机：它们的双引擎提供冗余，使它们即使在一个引擎着火的情况下也能安全的着陆。（这也有助于大多数商用飞机拥有最先进的自动化系统）。但是，拥有多引擎（或者多服务器）也意味着必须存在一些调度机制在故障发生时有效地对系统进行路由。

负载均衡器是一种通过平衡多个服务节点来优化大流量事务的设备或者软件。举个例子，当数以千计的请求涌入时，负载均衡器可以作为中间层在不同的服务器间进行路由和平均分配流量。如果一台服务器宕机，负载均衡器会将请求转发给其它运行良好的服务器。

有许多可用的负载均衡器，但其中最出名的两个就是 Nginx 和 HaProxy。

[Nginx](https://www.nginx.com) 不仅仅是一个负载均衡器，它还是 HTTP 和反向代理服务器、邮件代理服务器和通用 TCP/UDP 代理服务器。Groupon、Capital One、Adobe 和 NASA 等公司都在使用它。

[HaProxy](https://www.haproxy.org) 也很受欢迎，因为它是一个免费的、非常快且可靠的解决方案，它为基于 TCP 和 HTTP 的应用程序提供高可用性、负载平衡和代理。许多大型网络公司，包括 Github、Reddit、Twitter 和 Stack Overflow 都使用 HaProxy。是的，Red Hat Enterprise Linux 同样支持 HaProxy 设置。

#### 参与者模型：Akka

[参与者模型](https://en.wikipedia.org/wiki/Actor_model)是一种并发设计模式，当作为基本计算单位的“参与者”接收到消息时，它会分派责任。一个参与者可以创建更多的参与者，并将消息委派给他们。

[Akka](https://akka.io) 是最著名的参与者模型实现之一。该框架同时支持基于 JVM 的 Java 和 Scala。

#### 使用消息队列的异步、非阻塞 I/O：Kafka 和 RabbitMQ

多线程开发在过去很流行，但是现在已经不鼓励这种做法了，取而代之的是异步的、非阻塞的 I/O 模式。对于 Java，这一点在 [EnterpriseJavaBean（EJB）规范](https://jcp.org/aboutJava/communityprocess/final/jsr220/index.html)中得到了明确的规定：

>
> “企业 bean 一定不能使用线程同步原语来同步多个实例的执行。”
>
>
> “企业 bean 不得试图去管理线程。企业 bean 不得试图启动、停止、挂起或恢复线程，或者去更改线程的优先级或者名称。企业 bean 不得试图管理线程组。”
>
>
>

如今，虽然还有其他做法，如流 API 和参与者模型，但像 [Kafka](https://kafka.apache.org) 和[RabbitMQ](https://www.rabbitmq.com) 之类的消息队列为异步和非阻塞 I/O 功能提供了开箱即用的支持，同时它们也是功能强大的开源工具，通过处理并发进程可以替代线程。

#### 其他的选择：Eureka 和 Chaos Monkey

用于容错系统其它有用的工具包括奈飞的 [Eureka](https://github.com/Netflix/eureka) 之类的监控工具，以及像 [Chaos Monkey](https://github.com/Netflix/chaosmonkey) 这样的压力测试工具。它们旨在通过在较低环境中的测试，如集成（INT）、质量保障（QA）和用户接受测试（UAT）来早早发现潜在问题以防止在转移到生产环境之前出现潜在问题。

你在使用什么开源工具来构建一个容错系统呢？请在评论中分享你的最爱。

---

via: <https://opensource.com/article/19/3/tools-fault-tolerant-system>

作者：[Bryant Son](https://opensource.com/users/brson) 选题：[lujun9972](https://github.com/lujun9972) 译者：[chenmu-kk](https://github.com/chenmu-kk) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


Glances：多功能 Linux 系统监控工具

Summary: Glances 是一个系统监控工具，它把这些都联系在一起，并提供了更多的功能。

有用!

Glances 是一个系统监控工具，它把这些都联系在一起，并提供了更多的功能。

# Glances：多功能 Linux 系统监控工具

Linux 上最常用的[命令行进程监控工具](https://itsfoss.com/linux-system-monitoring-tools/)是 `top` 和它那色彩斑斓、功能丰富的表弟 [htop](https://hisham.hm/htop/)。

要[监控 Linux 上的温度](https://itsfoss.com/monitor-cpu-gpu-temp-linux/)，可以使用 [lm-sensors](https://github.com/lm-sensors/lm-sensors)。同样，还有很多实用工具可以监控其他实时指标，如磁盘 I/O、网络统计等。

[Glances](https://nicolargo.github.io/glances/) 是一个系统监控工具，它把这些都联系在一起，并提供了更多的功能。我最喜欢的是，你可以在远程 Linux 服务器上运行 Glances 来监控本地系统的系统资源，也可以通过 Web 浏览器监控。

下面是它的外观。下面截图中的终端已经[用 Pywal 工具美化过，可以根据壁纸自动改变颜色](https://itsfoss.com/pywal/)。

你也可以将它集成到像 [Grafana](https://grafana.com/) 这样的工具中，在一个直观的仪表盘中监控统计数据。

它是用 Python 编写的，这意味着它的绝大多数功能都可以在大多数平台上使用。

### Glances 的功能

让我们快速浏览一下 Glances 提供的主要功能：

* 可以监控系统上的 15 个之多的指标（包括 Docker 容器）。
* 灵活的使用模式：单机模式、客户端-服务器模式、通过 SSH 和 Web 模式。
* 可用于集成的各种 REST API 和 XML-RPC API。
* 支持将数据轻松导出到不同的服务和数据库。
* 高度的可配置性和适应不同的需求。
* 非常全面的文档。

### 在 Ubuntu 和其他 Linux 发行版上安装 Glances

Glances 在许多 Linux 发行版的官方软件库中都有。这意味着你可以使用你的发行版的软件包管理器来轻松安装它。

在基于 Debian/Ubuntu 的发行版上，你可以使用以下命令：

```
sudo apt install glances

```

你也可以使用 snap 包安装最新的 Glances：

```
sudo snap install glances

```

由于 Glances 是基于 Python 的，你也可以使用 PIP 在大多数 Linux 发行版上安装它。先[安装 PIP](https://itsfoss.com/install-pip-ubuntu/)，然后用它来安装 Glances：

```
sudo pip3 install glances

```

如果没有别的办法，你还可以使用 Glances 开发者提供的自动安装脚本。虽然我们不建议直接在你的系统上随便运行脚本，但这完全取决于你自己：

```
curl -L https://bit.ly/glances | /bin/bash

```

你可以从他们的[文档](https://github.com/nicolargo/glances/blob/master/README.rst#installation)中查看其他安装 Glances 的方法，甚至你还可以把它作为一个 Docker 容器来安装。

### 使用 Glances 监控本地系统上的 Linux 系统资源（独立模式）

你可以通过在终端上运行这个命令，轻松启动 Glances 来监控你的本地机器：

```
glances

```

你可以立即观察到，它将很多不同的信息整合在一个屏幕上。我喜欢它在顶部显示电脑的公共和私人 IP：

Glances 也是交互式的，这意味着你可以在它运行时使用命令与它互动。你可以按 `s` 将传感器显示在屏幕上；按 `k` 将 TCP 连接列表显示在屏幕上；按 `1` 将 CPU 统计扩展到显示单个线程。

你也可以使用方向键在进程列表中移动，并按不同的指标对表格进行排序。

你可以通过各种命令行选项来启动 Glances。此外，它还有很多交互式命令。你可以在他们的[丰富的文档](https://glances.readthedocs.io/en/latest/cmds.html)中找到完整的列表。

按 `Ctrl+C` 键退出 Glances。

### 使用 Glances 监控远程 Linux 系统（客户端-服务器模式）

要监控远程计算机，你可以在客户端-服务器模式下使用 Glances。你需要在两个系统上都安装 Glances。

在远程 Linux 系统上，使用 `-s` 选项在服务器模式下启动 Glances：

```
glances -s

```

在客户端系统中，使用下面的命令在客户端模式下启动 Glances 并连接到服务器：

```
glances -c server_ip_address

```

你也可以通过 SSH 进入任何一台电脑，然后启动 Glances，它可以完美地工作。更多关于客户端-服务器模式的信息请看[这里](https://glances.readthedocs.io/en/latest/quickstart.html#central-client)。

### 使用 Glances 在 Web 浏览器中监控 Linux 系统资源（Web 模式）

Glances 也可以在 Web 模式下运行。这意味着你可以使用 Web 浏览器来访问 Glances。与之前的客户端-服务器模式不同，你不需要在客户端系统上安装 Glances。

要在 Web 模式下启动 Glances，请使用 `-w` 选项：

```
glances -w

```

请注意，即使在 Linux 服务器上，它也可能显示 “Glances Web User Interface started on <http://0.0.0.0:61208>”，而实际上它使用的是服务器的 IP 地址。

最主要的是它使用的是 61208 端口号，你可以用它来通过网络浏览器访问 Glances。只要在服务器的 IP 地址后面输入端口号，比如 <http://123.123.123.123:61208>。

你也可以在本地系统中使用 <http://0.0.0.0:61208/> 或 <https://localhost:61208/> 访问。

Web 模式也模仿终端的样子。网页版是根据响应式设计原则打造的，即使在手机上也很好看。

你可能想用密码来保护 Web 模式，这样只有授权的人才能使用它。默认的用户名是 `glances`。

```
root@localhost:~# glances -w --password
Define the Glances webserver password (glances username):
Password (confirm):
Do you want to save the password? [Yes/No]: n
Glances Web User Interface started on http://0.0.0.0:61208/

```

你可以在[快速入门指南](https://glances.readthedocs.io/en/stable/quickstart.html)中找到关于配置密码的更多信息。

### 导出 Glances 数据到不同的服务

使用 Glances 最大的优势之一就是开箱即用，它支持将数据导出到各种数据库、服务，并无缝集成到各种数据管道中。

你可以在监控的同时用这个命令导出到 CSV：

```
glances --export csv --export-csv-file /tmp/glances.csv

```

`/tmp/glances.csv` 是文件的位置。数据以时间序列的形式整齐地填入。

你也可以导出到其它大型应用程序，如 [Prometheus](https://prometheus.io/)，以启用条件触发器和通知。

它可以直接插入到消息服务（如 RabbitMQ、MQTT）、流媒体平台（如 Kafka），并将时间序列数据导出到数据库（如 InfluxDB），并使用 Grafana 进行可视化。

你可以在[这里](https://glances.readthedocs.io/en/latest/gw/index.html)查看服务和导出选项的整个列表。

### 使用 REST API 将 Glances 与其他服务进行整合

这是整个栈中我最喜欢的功能。Glances 不仅可以将各种指标汇集在一起，还可以通过 API 将它们暴露出来。

这个简单而强大的功能使得为任何特定的用例构建自定义应用程序、服务和中间件应用程序变得非常容易。

当你在 Web 模式下启动 Glances 时，REST API 服务器会自动启动。要在 API 服务器模式下启动它，你可以使用以下命令：

```
glances -w --disable-webui

```

[REST API](https://github.com/nicolargo/glances/wiki/The-Glances-RESTFULL-JSON-API) 的文档很全面，其响应也很容易与 Web 应用集成。这使得使用类似 [Node-RED](https://nodered.org/) 这样的工具可以很容易地构建一个统一的仪表盘来监控多个服务器。

Glances 也提供了一个 XML-RPC 服务器，你可以在[这里](https://github.com/nicolargo/glances/wiki)查看文档。

### 关于 Glances 的结束语

Glances 使用 [psutil](https://pypi.org/project/psutil/) Python 库来访问不同的系统统计数据。早在 2017 年，我就曾使用相同的库构建了一个简单的 API 服务器来检索 CPU 的使用情况。我能够使用 Node-RED 构建的仪表盘监控一个集群中的所有树莓派。

Glances 可以为我节省一些时间，同时提供更多的功能，可惜我当时并不知道它。

在写这篇文章的时候，我确实尝试着在我的树莓派上安装 Glances，可惜所有的安装方法都出现了一些错误，失败了。当我成功后，我会更新文章，或者可能再写一篇文章，介绍在树莓派上安装的步骤。

我希望 Glances 能提供一种顶替 `top` 或 `htop` 等的方法。让我们希望在即将到来的版本中得到它。

我希望这能给你提供大量关于 Glances 的信息。你们使用什么系统监控工具呢，请在评论中告诉我。

---

via: <https://itsfoss.com/glances/>

作者：[Chinmay](https://itsfoss.com/author/chinmay/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


#新闻拍一拍# 可通过用户的浏览历史精确跟踪用户

Summary: • 微软 Linux 软件集合将不再支持 TLS 1.0/1.1 • CenturyLink 中断导致全球网络流量下降 3.5％

# #新闻拍一拍# 可通过用户的浏览历史精确跟踪用户

<img src="content_image/album_202008_31_094141vy44ihwdldu6690i.jpg" alt="" title="">

#### 可通过用户的浏览历史精确跟踪用户

Mozilla 的研究人员使用的数据集包含了 5.2 万名 Firefox 用户在两周内的浏览历史，分析显示了 48,919 个可区分的浏览资料，即 99% 的浏览历史是独一无二的。超过八成用户可通过浏览历史重新识别身份。研究人员还发现，只需要考虑 50 个最流行网站就足以获得独特指纹。研究人员称他们发现大量第三方在收集用户浏览历史将其作为标识符使用。

来源：[solidot](https://www.solidot.org/story?sid=65389 "https://www.solidot.org/story?sid=65389")

>
> 拍一拍：又一个可以精确跟踪用户的方式，要保持隐私可真难。
>
>
>

#### 微软 Linux 软件集合将不再支持 TLS 1.0/1.1

微软为 Linux 系统构建和支持各种软件产品托管在 [package.microsoft.com](http://package.microsoft.com/ "http://package.microsoft.com")，将不再允许使用 TLS 1.0/1.1，将强制使用 TLS 1.2。换句话说，在 9 月 24 日之后不使用 TLS 1.2 的客户将不再被允许从微软下载 Linux 软件包。

来源：[cnBeta.COM](https://www.cnbeta.com/articles/tech/1022355.htm "https://www.cnbeta.com/articles/tech/1022355.htm")

>
> 拍一拍：其实大部分人对 TLS 什么的都无感。
>
>
>

#### CenturyLink 中断导致全球网络流量下降 3.5％

美国 ISP CenturyLink 在周日遭遇了一次重大的技术故障，因为其一个数据中心的错误配置在整个互联网上造成了破坏。该故障涉及防火墙和 BGP 路由，从它的网络向外扩散，影响了其他 ISP，最终导致更多其他公司的连接问题。导致全球互联网流量下降了 3.5%，这将是有史以来最大的互联网中断事件之一。CenturyLink 最终重置了所有设备，并从干净的 BGP 路由表开始，花了七个小时才修复这次事故。

来源：[zdnet](https://www.zdnet.com/article/centurylink-outage-led-to-a-3-5-drop-in-global-web-traffic/ "https://www.zdnet.com/article/centurylink-outage-led-to-a-3-5-drop-in-global-web-traffic/")

>
> 拍一拍：BGP 故障何时休？我觉得天网也不用干啥，只要能掌握 BGP 广播就够了。
>
>
>


AI 系统向自动化编码迈进

又开始了又开始了

# AI 系统向自动化编码迈进

>
> 来自 Intel、MIT 和佐治亚理工学院的研究人员正在研究一个 AI 引擎，它可以分析代码的相似性，以确定代码的实际作用，为自动化软件编写奠定了基础。
>
>
>

<img src="content_image/album_202008_31_231333fklk447gw4w4b4vk.jpg" alt="" title="">

随着人工智能（AI）的快速发展，我们是否会进入计算机智能到足以编写自己的代码并和人类一起完成工作？新的研究表明，我们可能正在接近这个里程碑。

来自 MIT 和佐治亚理工学院的研究人员与 Intel 合作开发了一个人工智能引擎，被称为机器推断代码相似性（MISIM），它旨在分析软件代码并确定它与其他代码的相似性。最有趣的是，该系统有学习代码的潜力，然后利用这种智能来改变软件的编写方式。最终，人们可以解释希望程序做什么，然后机器编程（MP）系统可以拿出一个已经编写完的应用。

Intel 首席科学家兼机器编程研究总监/创始人 Justin Gottschlich 在该公司的[新闻稿](https://newsroom.intel.com/news/intel-mit-georgia-tech-machine-programming-code-similarity-system/#gs.d8qd40)中说：“当完全实现时，MP 能让每个人都能以任何最适合自己的方式 —— 无论是代码、自然语言还是其他东西 —— 来表达自己的意图以创建软件。这是一个大胆的目标，虽然还有很多工作要做，但 MISIM 是朝着这个目标迈出的坚实一步。”

### 它是如何工作的

Intel 解释说，神经网络“根据它们被设计执行的作业”给代码片段打出相似度分数。例如，两个代码样本可能看起来完全不同，但由于它们执行相同的功能，因此被评为相同。然后，该算法可以确定哪个代码片段更有效率。

例如，代码相似性系统的原始版本被用于抄袭检测。然而，有了 MISIM，该算法会查看代码块，并试图根据上下文确定这些代码段是否具有相似的特征，或者是否有相似的目标。然后，它可以提供性能方面的改进，例如说，总体效率的改进。

MISIM 的关键是创造者的意图，它标志着向基于意图的编程的进步，它可以使软件的设计基于非程序员创造者想要实现的目标。通过基于意图的编程，算法会借助于一个开源代码池，而不是依靠传统的、手工的方法，编译一系列类似于步骤的编程指令，逐行告诉计算机如何做某件事。

Intel 解释说：“MISIM 与现有代码相似性系统的核心区别在于其新颖的上下文感知语义结构 （CASS），其目的是将代码的实际作用提炼出来。与其他现有的方法不同，CASS 可以根据特定的上下文进行配置，使其能够捕捉到更高层次的代码描述信息。CASS 可以更具体地洞察代码的作用，而不是它是如何做的。”

这是在没有编译器（编程中的一个阶段，将人类可读代码转换为计算机程序）的情况下完成的。方便的是，可以执行部分片段，只是为了看看那段代码中会发生什么。另外，该系统摆脱了软件开发中一些比较繁琐的部分，比如逐行查找错误。更多细节可以在该小组的论文（[PDF](https://arxiv.org/pdf/2006.05265.pdf)）中找到。

Intel 表示，该团队的 MISIM 系统比之前的代码相似性系统识别相似代码的准确率高 40 倍。

一个 Redditor，Heres\_your\_sign [对 MISIM 报道](https://www.reddit.com/r/technology/comments/i2dxed/this_ai_could_bring_us_computers_that_can_write/)的评论中有趣地指出，幸好计算机不写需求。这位 Redditor 认为，那是自找麻烦。

---

via: <https://www.networkworld.com/article/3570389/ai-system-analyzes-code-similarities-makes-progress-toward-automated-coding.html>

作者：[Patrick Nelson](https://www.networkworld.com/author/Patrick-Nelson/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


铜豌豆：给中文 Debian 社区的礼物

大哥，你这就是个脚本啊。<br />
还是挺有心的。

# 铜豌豆：给中文 Debian 社区的礼物

Debian Linux 作为颇受 Linux 爱好者青睐的老牌发行版，无论在服务器领域、嵌入式环境，还是个人作为桌面计算机操作系统使用，都有一大片铁杆粉丝。

不过就中文使用环境而言，普遍遇到的一个现状是针对中文、中国人使用习惯打造的软件比较少，也缺乏整理，很多人不知道在哪里可以找到。

前两天，老王在群内偶尔发现有朋友在分享一款名为“铜豌豆 Linux”的 Debian 定制版，颇感兴趣，下面将它分享给大家。

---

### 铜豌豆 Linux 是什么？

[铜豌豆 Linux](https://www.atzlinux.com/) 是一款基于 Debian 的 Linux 中文桌面操作系统。

Debian 是一款非常优秀的 Linux 操作系统，但由于版权限制等多方面的原因，其默认安装缺少中国人常用的软件。 将一个原生 Debian 安装好后，再修改配置为中国人可以使用的日常操作系统，就是对一个对 Debian 比较了解的技术人员来讲，也需要不少时间。

铜豌豆 Linux 操作系统在 Debian 基础上，优化安装步骤，收集整理制作中文常用软件、一键安装脚本，搭建软件源，一次性安装完成常用中文应用，节省大家定制 Debian 的时间，可以做到“开箱即用”。

### 你是否在爱着 Debian 的同时，也感受到了这些困扰？

* 由于 Debian 严格遵循源代码开放的自由协议，硬件厂家的闭源驱动固件默认是不会放在 Debian 官方 iso 里面。
* 目前笔记本电脑一般默认集成有无线网卡，但这类无线网卡的驱动，在原生 Debian 的安装过程中，需要自己先确认无线网卡芯片型号，手工用 U 盘拷贝对应固件文件，再进行加载。
* 由于受到 Debian iso 文件大小的限制，在安装的时候，即使安装界面选择中文，也没有安装中文字体，安装后第一次重启登录，中文显示是乱码，需要再手工用命令行安装中文字体才行。
* Debian 的在安装过程中的可定制化程度比较高，有较多安装选项在安装过程中需要选择，对用户的技术知识水平也有一定的要求。

### 响当当的铜豌豆 Linux

针对以上的这些问题，铜豌豆 Linux 定制化安装 iso 文件，对安装过程进行了大量优化：

* 采用 preseed 等技术，默认设置安装过程中的很多配置选项，无需用户输入
* 默认使用中文安装界面、中文字符集
* 默认集成常见无线网卡固件，让内核能够直接识别并驱动
* 默认采用 DHCP 方式自动获取网络参数
* 默认使用速度比较快的国内 Debian 官方镜像作为软件源和安全升级源
* 默认安装中文字体、搜狗输入法、WPS 等常用中文应用
* 默认设置 root 账号密码
* 默认设置新用户及密码
* 默认识别多个硬盘的多个操作系统，并自动将 GRUB 安装在 sda 硬盘引导区

在整个安装过程中，以尽量自动化和免交互输入为目标，只需要进行“WiFi 选择”、“WiFi 密码输入”、“硬盘分区”这三个步骤，就可以完成整个操作系统安装。而且这三个步骤，只需要在安装初期前面几分钟的时候需要用户输入。在硬盘分区完成后，后续大部分的安装耗时，都是系统自动完成，不需要人为再干预。安装完成后，会自动重启进入登录界面。

如果是使用的 SSD 硬盘，一般只需要半个小时，可以完成全部安装，而且后续 20 多分钟，是不需要人一直在旁边盯着看的。

### 铜豌豆 Linux 软件收录

除了安装方便之外，铜豌豆 Linux 中都有什么软件呢？

为方便大家安装各类中文软件，铜豌豆 Linux 软件源积极收集各类中文软件。收录的软件包中，既有开源项目软件，也有各类商业软件，丰富 Linux 桌面中文应用。

对收录的 deb 软件包，会用 Debian 官方软件包质量检查工具 lintian 进行质量检查，安装卸载测试等工作。 确保收录的软件包，维持在相当的质量水平。

铜豌豆 Linux 完全尊重软件包知识产权，所收录的软件包至少是可以个人免费使用才行，不收录破解版本。

* 全部软件包列表如下： <https://www.atzlinux.com/allpackages.htm>
* 软件包的收录规则： <https://www.atzlinux.com/allpackages.htm#pkgrules>

铜豌豆软件源同时支持 Debian 系发行版。

#### 收纳开源社区中文软件包

中国象棋、麻将 等中文开源软件，积极收集整理到“铜豌豆”软件源，并进行必要的调整、重新打包，共同打造 Linux 中文桌面生态。 目前[铜豌豆软件源](https://www.atzlinux.com/allpackages.htm)收录的中文应用软件包约 90 个。（不包括 Debian 官方软件包和底层依赖相关软件包）

铜豌豆软件源的软件源，都可以在“铜豌豆应用商店”里面轻松安装。

#### 自制中文字体等软件包

针对目前 Linux 桌面缺少中文字体的窘境， iso 文件默认安装自制字体包，让 WPS 打开不报缺少字体的错误。

“铜豌豆”项目组成员凡客做出了积极的贡献，收集整理了若干开源或者免费商用的中文字体，制作打包。目前已经制作好的字体软件包有：

* 微软 cascadia 英文字体
* 鸿雷板书简体
* 江西拙楷
* 演示春风楷（毛笔楷体）
* 演示秋鸿楷（毛笔楷体）
* 演示夏行楷（毛笔楷体）
* 演示悠然小楷（毛笔楷体）
* 优设标题黑
* 杨任东竹石体
* 小赖手写体
* 一点明体
* 江城斜宋体、江城斜黑体
* 萌神拼音体（自带拼音）
* 黄令东齐伋体、黄令东齐伋复刻体
* 演示佛系体
* 悠哉手写体
* 更纱黑体（自带常规体、斜体）

中文字体软件包还在持续制作增加中。

#### 商业软件互动

对中文商业软件在适配测试过程中发现的问题，也积极和商业公司沟通，进行良性互动。得到了百度网盘、WPS 、永中 office 等公司的反馈。而在向 linuxqq 反馈的意见，也在 linuxqq 新版本中得到了改进。

### 关于铜豌豆

* 官网： <https://www.atzlinux.com/>
* 开源仓库：<https://gitee.com/atzlinux/projects>

#### 历程

铜豌豆最早始于 2019 年 9 月在码云上创建的第一个仓库： <https://gitee.com/atzlinux/debian-cn>

* 前期是用的一键安装脚本的方式，在已经安装好 Debian 操作系统的上一次性安装常用中文应用： <https://www.atzlinux.com/yjaz.htm>
* 后来自己搭建了 apt 软件源，方便软件包下载： <https://www.atzlinux.com/allpackages.htm>
* 第一版定制化的 iso 文件发布于 2019 年 11 月初，目前已经经历了 9 次更新迭代到了 10.5.1 版本。

#### 项目团队成员

项目发布后，先后有多位 Linux 爱好者参与项目，目前总计有 5 位铜豌豆开发者贡献了软件包，项目核心成员约 10 人。

非常欢迎更多的 Linux 爱好者加入，具体请访问： <https://www.atzlinux.com/devel.htm>

### 来一起添砖加瓦吧

与其抱怨中文 Linux 社区匮乏，不如身体力行：

* 目前发现的中文软件，总体很少，大家有发现合适的软件，欢迎提交软件包新增需求： <https://gitee.com/atzlinux/debian-cn/issues/I13NQT>
* 欢迎大家反馈在使用铜豌豆过程中遇到的问题： <https://gitee.com/atzlinux/debian-cn/issues>
* 其它我们做的不够好的地方，比如 UE/UI 方面还不够漂亮，文档还不够完善，大家都可以参与贡献
* 甚至，你还可以捐赠：<https://www.atzlinux.com/juanzeng.htm>

### 结语

那么，你有没有试过铜豌豆呢，你对这个项目感兴趣吗？希望大家来反馈和参与，把这颗铜豌豆打造得圆坨坨、响当当。


Summary: • k3s 进入 CNCF 沙箱，首个进入 CNCF 的 k8s 发行版 • Google Chrome 加入密码泄露检查功能，支持一键跳转修改

# #新闻拍一拍# Manjaro 社区版 PinePhone Linux 智能机即将上市

<img src="content_image/album_202009_01_111845iznnzjnbna104bc8.jpg" alt="" title="">

#### Manjaro 社区版 PinePhone Linux 智能机即将上市

Manjaro 团队表示：“PinePhone 的下一个社区版本（CE）将启用 Manjaro……现已支持几乎所有 Pine64 单板机和相关设备”。可购买预装了 Manjaro Linux 的 PinePhone，并且可从 2GB RAM + 16GB ROM / 3GB RAM + 32GB ROM 这两种存储组合中进行选择。

来源：[cnbeta](https://www.cnbeta.com/articles/tech/1023045.htm "https://www.cnbeta.com/articles/tech/1023045.htm")

>
> 拍一拍：真正的开源爱好者，自然希望他的手机也是真正开源的。
>
>
>

#### k3s 进入 CNCF 沙箱，首个进入 CNCF 的 k8s 发行版

Rancher 发布公告，宣布其开源项目 k3s 已经进入 CNCF 沙箱孵化。k3s 是一个轻量级 Kubernetes，适用于 Edge、IoT、CI 与 ARM 场景。k3s 旨在成为完全兼容的 Kubernetes 发行版。自 2019 年 2 月发布，k3s 的全球下载量超过 100 万次，每周平均被安装超过 2 万次，其中 30% 的下载量来自于中国。

来源：[开源中国](https://www.oschina.net/news/118294/k3s-joins-cncf-sandbox "https://www.oschina.net/news/118294/k3s-joins-cncf-sandbox")

>
> 拍一拍：虽然 k3s 像是一个 k8s 的子项目，但是还是被认为是独立项目进入了孵化。
>
>
>

#### Google Chrome 加入密码泄露检查功能，支持一键跳转修改

这项功能采用了“众所周知（.well-known）”的解决方案，大多数网站都有提供标准的“修改密码”页面。而 Chrome 浏览器做到了更进一步 —— 帮助用户一件跳转！

来源：[cnbeta](https://www.cnbeta.com/articles/tech/1023053.htm "https://www.cnbeta.com/articles/tech/1023053.htm")

>
> 拍一拍：为了你们泄露的密码，浏览器厂商真是操尽了心。
>
>
>