用例- Astrid: Netflix的人工来源依赖洞察

文摘:

Jon Schneider和Nadav Cohen / NETFLIX, 2016年5月:凭借完全基于二进制集成的依赖管理策略,NETFLIX每天只需数十名运营工程师,无需NOC即可成功执行数千次生产更改。这种成功在很大程度上要归功于开发的工具和技术,这些工具和技术允许产品工程团队在尽可能多的环境中快速移动。
Astrid将从Java方法调用到AWS中数千多个实例自动伸缩组的低级别信息拼接在一起,为工程师提供了一段代码对Netflix生态系统影响的多维视图。我们将提供Astrid的现场演示,Netflix计划在2016年将其开源。

讨论转录:

[约翰]好的。我叫约翰·施耐德。

[纳达夫]我是纳达夫·科恩。

[约翰]我们来自

(Nadav)开发人员

(约翰)生产力

[Nadav]团队

(约翰)在

(Nadav)净

(约翰)毛皮。

[Nadav]酷。

[约翰]你不知道我们练习了多少次。这就像我们在Netflix上的一天一样有条理。这一切都是因为Netflix是一种自由和责任的文化。那是什么意思,纳达夫?

[Nadav]嗯,在我们的环境中,自由和责任意味着每个团队都可以选择自己的工具、自己的语言和自己的发布周期。

[John]虽然每个团队都可以做自己的事情,但在这里,我们作为一个核心开发人员生产力团队,试图为Netflix的每个团队提供良好的信息和见解。帮助他们确保,你知道,最大限度地提高生产效率,减少交货时间。

[John]所以,在我们看来,有两种方法可以真正整合你的代码库。您可以进行源级集成。源级集成有时称为从头构建或单仓库。在这方面有一些非常成功的组织。你知道,谷歌,脸书和推特都在某种程度上从头脑中构建。但他们是在大型工程组织中这样做的,而且通常是巨大的工程努力。

[John]我认为谷歌入侵了文件系统,使他们的构建系统运行良好,Facebook入侵了Git本身,使他们的构建系统运行良好。

[John]另一种选择是二进制集成,每个团队都将二进制文件发布到一个中央工件存储库中,我们以这种方式进行集成。Netflix做二进制积分。所以我们是一个相对较大的组织,但我们只有少数开发人员的生产力,所以我们选择了二进制集成。

[John]我们今天要告诉你的是,我们是如何处理这些二进制依赖问题的。这是我们看到的最常见的。我们会给出一些解决方法。合理的警告。这是一个基于JVM的演讲,所以我们会给出解决方案。我们将在Gradle中提供解决方案,因为Gradle是我们选择的构建框架。但是,您知道,如果您选择这样做,可以在其他工具堆栈中编写类似的解决方案。我们从第一个问题开始。Nadav。

[纳达夫]好吧。在约翰说的基础上再补充一点,这张幻灯片中唯一相关的信息是我们在GitHub上有所有将要演示的代码。所以如果你想的话,你可以访问它并跟随它。

[纳达夫]好吧。有了这些,我们来看第一个例子。我们将演示在Java中把重复的类放在相同的类路径中会发生什么。在这个例子中,我将构建一个命令行应用程序来打印给定集合的幂集。好,首先我要做的是添加一些库。我不想重新发明轮子,对吧,而且我也有点懒。我要添加Guava这是一个Google库。我还会添加Google collection。

[纳达夫]好吧。现在我已经有了我的依赖项,我可以实际编写输出功率集的代码了。我就这么做。

[纳达夫]好吧。假设我没有错,这个应该在Gradle中构建。好吧。我还可以检查依赖项。我发现我同时收藏了Guava和Google。然后我也可以运行它。如果我运行它,你可以看到我成功地得到了集合的幂集。

[纳达夫]现在问题来了。Java类加载的特殊之处在于不能保证顺序。换句话说,如果在类路径中有两个类,例如,Tomcat可能会选择加载A,然后加载B,而Jetty可能会选择加载B,然后加载A。当您有重复的类,或者在类路径上有同一个类的多个定义时,这就成了一个问题。最终,Java会任意地选择一个,然后把其余的都扔掉。最终,你知道,你不知道在运行时你会得到什么。这当然是个问题。对吧?一切都通过了编译,这很好,我们把它发布到部署,然后一切,当然,都中断了。

[Nadav]所以这不是Gradle特有的问题,但基本上我要用Gradle向你展示一个非常简单的顺序改变是如何导致这个问题的。对吧?

[Nadav]所以我要去Gradle文件。我要改变秩序,然后再试着重建。正如您所期望的那样,构建是成功的。然后我要检查依赖性。哦。同样的依赖关系。Gradle实际上并没有重新编译,因为据Gradle所知,这是完全相同的代码,它实际上是相同的依赖,所以一切都保持不变。但当我继续运行时,我们会得到一个运行时异常。正确的。我们会得到no such method错误。 So what actually happened here was that our code dependent on a very specific method on the set’s class. Right? From Guava. But because we used Google collections first in Gradle, that one was loaded first and because this one has the same set class with different functionality but the same set class. It basically masked away the class we wanted to use and cause this runtime exception. Right. Which is, of course, a problem.

[Nadav]因此,我们在Netflix内部解决这类问题的方法基本上是看看这些重复类问题可能发生在哪里。在这种情况下,它的发生是因为Google在Guava中的集合,我相信你们中的一些人已经知道,实际上是同一个库。对吧?这就是为什么它们共享相同的代码。不幸的是,Gradle并不知道这一点,因为不同的命名、不同的依赖意味着它们可以愉快地生活在一起。因此,我们在Netflix内部构建了一个插件,名为Resolution Rules,它可以帮助Gradle了解依赖项实际上是相同的,然后可以相应地解决冲突。

[Nadav]。让我继续添加插件,只是为了向您展示它有多简单。

Nadav星云。然后再加上规则本身。在这里,我对插件说,每次你看到谷歌收藏,我希望你用Guava代替它。因为它已经改名为Guava,而且还记录了谁制定的规则和哪一天,以防我忘记。我们知道这是可能发生的。正确的。回到构建,我只想包含那个规则。希望一切都正确。这将构建并运行。好的,构建成功通过。 I run dependencies. And now you’ll see something has changed. Now instead of having Google collections and Guava, I basically set up Gradle manage Google collections to Guava. And once it saw that it’s actually the same library it conflict resolved it to the latest 19 which is exactly what I wanted in this case. All right. And when I run the same program, you see that the power set works as expected despite the fact that I have multiple declarations of conflicting libraries. All right.

[约翰]所以这是一个有点做作的例子。我们引入了两个一阶依赖关系这两个一阶依赖关系是已知相同的。但实际上,这在过去的一年里确实伤害了我们。这类问题,重复类的问题。特别是当我们作为一个组织从Java 7迁移到Java 8时,ASM是造成最痛苦的库之一。ASM的版本,通过代码支持Java 7的ASM的最后一个版本有一个名为ASM的组,一个名为ASM的工件。第一个通过代码支持Java 8的组织有一个名为org . OW2 . ASM的组,然后是一个名为ASM的工件。因此,当我们尝试从7到8的转换时,我们不得不尝试推出旧的ASM, ASM版本,我们不能依靠我们的构建工具冲突解决机制来为我们做这件事。所以这些事情在实践中真的很痛苦,但这是有帮助的。因此,这是一个有用的规则。 On to the next one?

[Nadav]。有人有问题吗?特别是现在,在我们继续之前?

[约翰]对这个问题有什么问题吗?

[纳达夫]我想那里有人。

(约翰)。是吗?

[纳达夫]我不确定。

[约翰]如果有的话就大声说出来。或以其他方式。我们继续。好吧。继续。

[Nadav]好了,我们要展示的下一个问题与捆绑依赖关系有关。基本上,我要做的是构建另一个命令行实用程序,但这次我将使用slf4j将内容记录到控制台。好吧。

[纳达夫]好吧。首先,我要添加slf4j的依赖项。准备好就行。让我们来看看这到底带来了什么。这样我就可以运行Gradle dependencies了。我看到这基本上带来了三个依赖关系。第一个,如您所料,日志记录实现。第二个是slf4j的API。然后是两者之间的桥梁。好吧。

[Nadav]所以我现在要开始写代码了。所以。

[Nadav]当然,每个人每天都要这样做。好吧。好吧。如果一切顺利,这应该运行。完美的。所以我们确实从记录器获得消息。现在我想让它更有趣一点。我想使用我自己的库,这个库是我在过去几周建立起来的,它基本上会给你一个Netflix原创的随机引用。我不知道这对其他人有多有用但它在这个例子中非常有用。所以我还是要用它。

[Nadav]首先我想添加依赖性。好吧。好吧。并检查作为结果的依赖项,我们看到我们获得了报价服务。太好了。现在可以继续使用该服务了。好吧。然后运行它,看看会发生什么。

[纳达夫]好吧。我又得到了一个运行时异常,因为依赖关系这次,我希望大家能清楚地看到,它抱怨类路径中有两个冲突的jar。其中一个我知道是因为我想使用日志记录,而另一个,我不知道它是从哪里来的。但它阻止我运行应用,因为这是Gradle,我知道我可以排除依赖我可以移除所有可传递的东西。我将继续尝试去做。好吧。然后我运行,得到完全相同的异常。什么都没有改变,即使如果我看一下依赖项,我看到它仍然是一样的。让我试着去掉所有的传递物。看看会发生什么。 Same thing. So what actually happened here and again maybe some of you have noticed this, this is what we call a bundle dependency.

bundle依赖基本上是jar的一种简化的交付机制。本质上,库生成器只是将所有依赖项嵌入到同一个jar中,使其非常容易实际生成和使用,对吧?你只有一个罐子。但是你也失去了所有关于依赖的信息。正确的。所以在我们的例子中,因为我们实际上想要删除一些传递依赖,但我们不能,因为这些信息丢失了。

[Nadav]所以现在我们知道问题是什么了,下一步就是确保这些捆绑的依赖不会出现在我们的构建中。同样,我们可以使用分辨率规则插件来做到这一点。如果那个特定的包出现在类路径中,构建就会失败。好吧。我还是要添加插件。好吧。顺便说一下,你会注意到我在dependencies块中添加了Resolution Rule。这让我们在Netflix内部做了一件非常有趣的事情,那就是将规则外部化,适用于其他所有人。任何觉得这条规则对他们有用的人都可以在他们的构建中使用这个依赖关系,并从我们对所有可能发生的依赖问题的集体知识和集体经验中受益。

[约翰]除此之外,我们在Netflix大约有5000个构建,所以我们大约有四个人在工作,负责应对与之相关的问题。所以你几乎可以保证我们已经看到了一个普遍存在的依赖问题。因此,这个解决规则的集合将使许多组织受益。

[纳达夫]好吧。谢谢你!在这个例子中,我们使用了拒绝规则。基本上说每次你看到quote服务包,直接让构建失败说这是一个坏的包,我们知道它包装了你不想用的坏库。然后我们也可以给他们指出一个维基条目来进一步解释为什么这是一个问题。正确的。我们一次又一次地看到这种情况。正如John提到的,我们支持每个人的构建环境,这是一个反复出现的问题。所以从自助服务的角度来看,这是非常有用的。

[Nadav]我们又有了作者和日期。只是为了记录是谁建立了这个规则,为什么,什么时候。然后我们试着运行它。好了,现在我们得到一个异常但现在它是一个非常显式的异常。正确的。构建失败是因为我们有一个错误的,我们有一个非常糟糕的bundle,我们只想摆脱它。既然我们知道问题出在哪里,我们就能解决它。把这个去掉。使用非捆绑版本。好吧。 And now we can check the dependencies. Now that we’re no longer using the bundle package and the dependency information is actually there, we can see what’s actually been brought in. Right. And this is the problematic package that we’ve saw before.

[Nadav]但现在我们有了这些信息,我们也可以说及物等于假,然后把它们都去掉。正确的。现在我们只得到我们需要的服务。一旦我们准备好了,我们就可以运行Gradle来获取报价了。我想这是杰西卡·琼斯写的。好吧。就是这样。

(约翰)太好了。这是我们今天想做的两个决议规则的演示。我们还有更多要跟进。在我们进入下一个话题之前,关于决议规则还有什么问题吗?它可能对你有什么帮助?是的。

[观众]那么,有人能把所有的决议规则整合到他们的项目中,并保留他们使用的NLP库吗?因为您一开始就知道哪个包可以与项目中的其他包一起使用。所以。

(约翰)是的。

[观众]在你有了[…]规则之后,[…]可以把它们组合在一起作为所有规则的超级集合吗?

[约翰]我们稍后会给你看一些东西。我们有一个Gradle Lint演示,我们将向你展示我们如何收集可能存在的潜在问题包的信息,然后我们如何构建相应的规则。

[John]但是我确实想给你一个bundle依赖问题的具体例子。我们最常遇到的是Jersey bundle。它实际上演示了我们到目前为止讨论过的两个问题:重复类和bundle依赖。Jersey bundle只是把所有可用的Jersey库打包成一个,如果有人想依赖特定的Jersey核心特定的版本,但也有Jersey bundle。这将导致两个包之间的版本不匹配。根据它们在类路径中加载的顺序,它们可能会以意想不到的方式爆炸。这是最有害的一种。稍后我们将向您展示这对Netflix的影响范围。但是。

(Nadav)确定。我认为问题的另一部分可能是我们是否真的有,你知道的,那些其他人都可以使用的规则,对吧。是的,开源版本的决议规则实际上有相当多的规则,我们认为对其他人普遍有用。我的意思是,如果你有,如果你想,请随时查看GitHub项目。你会看到所有的规则。

(约翰)是的。太好了。关于决议规则还有什么问题吗?是的。后面有一个。

(观众)

[John]现在,这是一个——这是一个只有Gradle的解决方案,因为它使用了Gradle的解析策略等等,但是我再次认为,如果有帮助的话,我们这里的解决方案可以在其他构建工具中重新实现。

(观众)

[John]我们有自由和责任的文化,所以任何团队当然可以选择不同的构建框架,如果他们愿意的话。Maven或其他地方也有一些。SVT吗?

[Nadav]有些人使用Node。

(约翰)是的。但是我们试图提供一条平坦的道路,你知道,如果你接受这条平坦的道路,你将以最简单的方式得到最多的支持。所以目前绝大多数都是Gradle版本。

[Nadav]只是因为使用预先准备好的东西要容易得多,而且在Netflix环境下运行得很好。

(约翰)是的。

[Nadav]现在,如果你正在使用Maven,还有一件事要补充,有一个强制执行插件,它的工作原理与Resolution Rules插件非常相似,所以你可以尝试使用它。如果您正在使用Ant,那么祝您好运。

(约翰)。

[纳达夫]好吧。

(约翰)。下一个我们要给你们看的是-

[Nadav][…]

[约翰]-是的,我想你可以直接打开浏览器。太好了。这是一个例子。我们有一个叫做Astrid的工具,这是Netflix的一个内部依赖关系分析工具。

[John]我想你已经在主题演讲中听到了JFrog的演示,一个与此非常相似的工具。阿斯特丽德的主要职能之一是,如果我是图书馆制作人,我想知道对组织的影响范围是什么。也就是谁直接和间接依赖于我?我可以利用阿斯特丽德了解这一点。

[John]所以我们特别提到了泽西捆绑是个大问题。我们知道这件事有段时间了。我们最近引入了决议规则,但是尽管我们-,你已经在这个想法周围购物,你不想使用Jersey bundle,它会影响到你下游的人等等。今天,如果你看看Jersey bundle在我们组织中的影响范围,我们在这里搜索Jersey bundle的任何使用,你会发现它存在于,你知道,超过25万个库版本中,你知道,在内部部署,这正在影响- Jersey bundle存在于接近700个亚马逊服务器组中,实际部署在EC2中。这只是其中一个例子,如果Jersey bundle是在相对较低的水平上引入的,它会渗透到整个图表中影响到很多人。我们预计,随着“决议规则”等措施的出台,这一数字将在短期内大幅下降。

[约翰]阿斯特丽德有能力做的其他事情。它是一种,你知道,有很多不同特征的杂七杂七的组合。我们用它来从Artifactory抓取元数据,提交哈希和类似的东西,并为特定模块生成GitHub风格的发布说明页面。所以,如果platform-ipc的生产者,也就是我们的内部jar之一,没有勤奋地向它的消费者提供变更日志,人们可以来这里看看在最近的版本中有什么变化。具体来说,如果他们有问题,他们会先看这里。

[John]这就是Astrid,我们正在或即将使用Astrid做的其他事情,我们发现Artifactory清理的故事对Netflix来说尤其困难。如果我们试图创建一个规则,比如,让我们删除超过90天的快照,这对我们来说真的很难,因为所有的团队都处于不同的发布周期。如果我们删除了90天前的快照,它可能会被包含在30天前的候选快照中,而不是本周发布的版本。所以我们不想删除实际在生产中的东西。使用Astrid,因为我们把所有的信息拼凑在一起,从二进制工件到包括asg它们实际上部署在AC2中。我们确切地知道在任何给定的时间使用了什么,然后我们可以清除旧的东西。这是一个很好的用法。真的很想看看JFrog想出了什么。我认为非常相似。

[约翰]关于阿斯特丽德有什么问题吗?你的用例可能是什么,因为我们正在考虑开源这个,所以这是一种有趣的——我们发现自己处于一个有趣的位置。没有?

[观众]一个问题。

(约翰)是的。

(观众)

[纳达夫]这是个好问题。

(约翰)是的。问题是如何确定哪些项目依赖于某个特定的依赖项。Astrid所做的实际上是摄取依赖描述符,比如ID文件或Pom。所以我们在内存中有大量关于一阶依赖关系的数据然后我们可以沿着另一个方向,在这个过程中模拟最新版本的冲突解决方法。我们打开Debian文件,就像我听说JFrog做的那样。看看里面有哪些依赖项。然后一直走到那个方向。所以,是的。

[约翰]还有关于阿斯特丽德的问题吗?是的,先生。

(观众)

(约翰)是的。问题是这是只与Java相关还是与NPM相关。现在只支持Java。历史上,Netflix的许多服务都是用基于JVM的语言编写的。尽管最近情况发生了变化。我想我们大概有60%是Java, 30%左右是NPM,然后是一些其他的东西。所以,是的,我们确实有一个相对短期的特性,它正在为Node追求同样的洞察力,因为它在内部变得越来越重要。所以。

[约翰]好的。好。我们要展示的下一个主要特性是Gradle Lint和分辨率策略。我们已经展示过的解决策略对我们来说可能有点困难,因为作为一个中心建设团队,我们对我们所有的团队都施加了意见,但我们有自由和责任的文化,所以它并不总是感觉完全正确。感觉好一点的是,如果我们写一个规则,我们看你的构建文件,我们写一个规则,我们发现一个违规说,嘿,这可能是一个问题,然后我们为你提供某种自动修复规则,如果你运行一个特定的命令来修复你的代码,你可以看到它,然后你可以选择是否接受这个违规。这就是我们最近用Gradle Limp插件所做的。我们将展示它的一些功能。它没开?

Nadav哦。就是这个。

(约翰)。你只要站上去就行了。好了。哦,我的。[…]做演示。

Nadav重置。

(约翰)是的。

[Nadav][…]

[约翰]那是什么?我们在哪里?好吧。

[John]所以我们将从一个非常简单的应用程序开始。这也是一个有点做作的例子。我们将从一个非常简单的应用开始,它只包含一些依赖引用。这里的main方法指的是Amazon S3 Client。它指的是另一种类型默认的awscreential提供者。这里有一个很好用的函数叫做Jackson它从来没有被引用过它引用了Jackson对象映射器。这是我们的一个类。另一个是测试,我们做TDD,对吧。这个测试绝对是指junit。在构建端,我们只有三个依赖项。我们有AWS Java SDK、Jackson数据绑定核心和junit本身。

[约翰]所以。您会注意到一些潜在的错误。第一,我在编译作用域中引用junit,而实际上我应该在测试编译作用域中引用它。现在的情况是,如果我是一个库生产者,我把它作为二进制依赖项推出来,我的下游的每个人都会在他们的类路径中得到junit,而他们可能不想要它。这是我们发现发生在一个不幸的不规则程度的事情。我也在使用这个AWS Java SDK,这是一个家庭jar。它实际上是一个零字节的罐子。里面什么也没有。它有一个Pom文件,其中包含AWS Java SDK的所有其他组件,其中许多组件我没有使用。所以这是一种方便的依赖,我添加了它,但它带来的很多东西我没有使用。 And then finally I’m referring to Jackson databind here, version two-five-five. But I’m actually, because of latest version conflict resolution, I’m actually getting two-six or above. So we’re going to see how Lint will help us surface these issues and fix them for us. So that we know exactly what’s going on.

[John]首先我们要应用插件。和Resolution Rules插件类似,基本上是一种将规则打包到jar中的方式,包括那些jar,那些未使用的依赖规则,当它在Gradle Lint中可用时。您可以直接在构建脚本中或在某个组织范围内的脚本中声明您想使用的脚本。这里我们说我们将使用未使用的依赖规则。当我们运行Lint时,我们会看到Lint报告了一些违规行为。首先,它说,嘿,你正在使用junit,但你实际上并没有在主源代码中使用junit。你只会在考试中用到它。因此,我们应该把这个放到测试编译配置中,这样就不会影响下游用户。其次,它说AWS Java SDK实际上只是一个空罐子。它不包含任何东西,所以我们可以去掉它,因为否则你就会引入你并不需要的依赖项。 And then, you know, another thing it’s doing is it’s saying, hey I see you have a first order dependency on the S3 SDK specifically so we want to add that. We want to be declarative about the fact that we require that, and add that to our build script. Similarly the AWS Java SDK core is required directly so we want to add that as well.

[John]这些规则很棒,但更棒的是,我们现在可以,因为每条规则都有一个自动修复规则,我们可以运行fix Gradle Lint,我们会看到它实际上转换了我们的构建脚本本身,添加了它发现的我们实际上需要从Amazon Java SDK中获得的两个依赖项。它将junit依赖重新定位到适当的配置中,这样我们就不会影响下游的人。现在我们的依赖项更清晰了。我们已经从可能,你知道,30或40或50个依赖关系减少到现在的一个更小的集合。

[John]所以我们将添加另一个规则,就一个。我们将添加覆盖的依赖版本。这就是我在这里引用的Jackson版本在这里我们有一个关于2-5-5的声明但实际上Amazon Java SDK也在使用Jackson它使用的是更高的版本。我们从开发者那里听到了很多抱怨。他们会在构建文件中放入一个特定的版本,然后他们会想为什么他们没有得到它。他们没有得到它,因为冲突因为某种原因被解决了。我们也想让它浮出水面。如果我们运行fix Gradle Lint,你会看到它会说,好吧,你实际上使用的是2-6-6,我们不妨在你的构建中显示出来,这样你就不会对运行时得到的是哪个版本感到困惑了。到目前为止,关于Gradle Lint插件有什么问题吗?好吧。

[约翰]所以,这个——这个Lint的能力对我们来说真的是一种紧急的能力。我们认为这最终会导致一个统一的单回购和二元积分。我们的意思是,你知道,像这样的事情,二进制依赖管理是困难的。我们并不总是指定正确的版本。我们希望确保人们使用尽可能少的依赖项,但明确说明他们使用的依赖项,他们有正确的版本。但是我们想象Lint也会被用来操作源代码。

[John]这是一个很好的例子,在我们内部有一个——在slf4j出现之前,我们走在了前面,我们编写了一个叫做[…]的库。它做了和slf4j一样的事情。这是一个无处不在的答案,然而,直到今天,你知道,我们有成千上万的参考[…]漂浮在周围。你知道,这是相对容易的,当我们看到这段代码时,我们可以用另一段代码替换它。然而,你知道,这真的不是一个负责任的利用我们的时间去寻找每一个参考资料。

[John]所以我们允许的是,我们很快就会允许我们的库生产者将规则打包到他们自己的jar中,这些jar可以操纵源代码,改变API调用,诸如此类。它会在构建过程中一次又一次地出现,每当开发人员运行修复Gradle Lint时,他们就会接受这个更改,并且它会在代码中工作。所以这就像是mono repo的替代品,你知道,当你——如果我们决定从[…]转向slf4j,我们会在整个组织内进行重构操作。在这里,我们可以提供一个规则,然后当人们运行fix Gradle Lint时,它就会有机地工作。

[约翰]好的。我想现在大家可以提问了。Netflix开发人员生产力团队的任何内容,或者到目前为止您看到的任何内容?

[观众]那么这些是任何人都可以使用的吗?

(约翰)是的。这些都在GitHub上。我们今天展示的插件,Gradle Lint插件,Resolution Rules插件,都已经有了。

(Nadav)是的。阿斯特丽德是唯一还在内部的人。

(约翰)是的。

[Nadav]但我们实际上是在寻求反馈。如果这是其他人可能感兴趣的东西,我们不妨将其开源。

[约翰]是的。是的。我们想知道你的用例是什么。所以。

[观众]那么这对项目有什么影响呢[…]当你制定规则,决议规则[…]。这是否反映了依赖项报告的任何输出?

问题是:Resolution Rules插件是否反映在依赖报告的输出中?这是一个很有见地的问题因为有两种可能,要么影响了一阶依赖要么影响了传递依赖。在影响一阶依赖的情况下,假设由于某种原因,您的AWS版本不匹配。这最终将在Pom或IBXM中表示。

[John]在影响及物版本的情况下,它不会。这对我们来说是一个粘滞问题因为,你知道,潜在地如果你应用解析规则并且它修复了一个传递,你的代码可以编译和测试并且一切看起来都很好,你发布它,如果你的下游消费者不也应用解析规则,它可能看起来你的项目是不正常的。

[约翰]所以现在我们只是说,嗯,你知道,每个人都在应用它,所以我应该没事。最终,它会影响到较短的版本,所以它应该渗透到整个版本。但是无论我们在哪里制定了决议规则,我们可能也会制定相关的Lint规则。这样我们就能找到问题的根源一阶依赖在哪里,然后解决它。这最终是更正确的解决方案。

[Nadav]除了他刚才说的,我们还集成了我们的指标插件,这一点我们根本没有提到。基本上,Lint插件可以与另一个我们称为info-broker的插件通信,该插件与度量插件通信,最终将度量发送给弹性搜索实例。

[约翰]是的。

[Nadav]然后我们可以做各种有趣的聚合,看看你知道,我们在整个组织中有多少违规行为。是否有一个特定的团队在背后,我们需要与之交谈,我们的计划是对决议规则也做同样的事情。因此,我们实际上会有一个集中的地方,收集有关组织的所有汇总信息,并根据这些信息采取相应的行动。正确的。也许会制定更多的规则,也许会和球队谈谈,这真的取决于我们的发现。

[约翰]有一个很好的例子,就是公制对我们的帮助。我们之前解决的适配问题,Guava Google集合问题。哦,这是闲置的,我需要。开枪。我把未使用的去掉,因为这对我来说太聪明了。这是我们的一个规则它只是一个重复依赖类规则,它会检查你的依赖项,然后说,嘿,你实际上有两个包含相同类的东西,或者在这种情况下,这两个库之间有超过298个重叠的类。不幸的是,我们没有这个的自动修复规则,因为我不知道你真正想要的是哪个,但它还是会出现,这样开发人员就不会对运行时顺序等问题感到惊讶。而且由于我们将所有这些违规行为运送到我们的度量收集器,我们知道作为一个团队,我们在这里看到,好吧,这是一个例子,在这两个库之间有一个重复的依赖类,我们要为它添加一个解决规则,我们要为它添加另一个Lint规则来处理这个问题。是的,先生。

(观众)

[约翰]问题是:规则只由我们团队管理吗?

(Nadav)是的。所以答案是我们有一些中心化的规则,每个人都可以使用。但是,如果他们觉得可以对构建的方式更严格的话,所有东西都可以自由地添加自己的规则。正确的。所以你只需要用你自己的规则添加另一个依赖项,你自己的内部规则,然后你就可以应用那些了。

(观众)

[Nadav]。它们根本不是硬编码的。您只需用自己的解析规则添加依赖项,就可以了。

(约翰)是的。这是正确的。

所以你在Java方面有这个,你在NPM方面也会走同样的路线吗?非常像狂野的西部

[John]我认为我们已经注意到的问题是:我们是否在重蹈NPM的覆辙?顺便说一下,里面有一点关于NPM也是狂野西部的内容所以你也想说你的名字,先生,开玩笑的。

(观众)

(约翰)。好了。到目前为止,我们的理解是,由于NPM有那个分层打包机制它在那里并不像Java中那么丑陋在Java中我们有平坦的类路径,一个类会胜出等等。我们对Jigsaw项目有很大的希望——允许我们分层,基本上,你知道,在Java中分层依赖关系。虽然他们为此提供了一些编译时间[…],但不幸的是,在运行时,该层的构造-该层机制留给了运行时。所以Java 9并没有解决这个问题。而且,你知道,这将继续是我们的一个痛点,所以我们必须立即采取行动。是的,先生。

(观众)所以你现在谈到了Java和NPM,是否有一个指标数据库或者。这将是一种技术,还是一种Java特有的技术?

[纳达夫]这是个有趣的问题。所以问题是:如果我们的弹性搜索数据库是语言不可知论的,对吧,一旦我们转向不同的技术。我不认为-我不认为-我们内部已经讨论过这个问题了但我相信答案是肯定的。

[观众][…]开源它。不管怎么说,我都得顺其自然。

[John]问题是:我们会把它开源吗?最终如果它是多平台的。现在,度量收集器实际上是Java端——JVM端——的开源。这是Gradle metrics插件。这些都是相关的。是的。我们为NPM做的任何事情都是像这样的通用解决方案,我不认为我们有任何理由不把它开源。而我们正被它弄得晕头转向。所以。

(约翰)[…]。我听说……蛮野的家伙。还有问题吗?[…]。好吧。非常感谢你的到来,我们会一直在你身边。谢谢你!

要么释放,要么死亡