Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ApacheStorm:发送到不同螺栓的可变对象_Java_Apache Storm_Mutable - Fatal编程技术网

Java ApacheStorm:发送到不同螺栓的可变对象

Java ApacheStorm:发送到不同螺栓的可变对象,java,apache-storm,mutable,Java,Apache Storm,Mutable,几个星期以来,我们在项目中使用了Storm。今天,我们发现了一个非常奇怪的行为。 假设我们有以下拓扑结构: 因此,我们有一个喷口,它向两个不同的螺栓发出一个自定义Java对象(我们称之为消息)。博尔特B和博尔特C。基本上,我们进行拆分 直到今天,我们一直假设,如果SpoutA发出消息对象,它将在SpoutA上序列化,并在BoltB和BoltC上反序列化。然而,这一假设似乎是错误的。今天,我们发现BoltB中的反序列化对象与BoltC中的对象相同(相同的System.IdentityFyHas

几个星期以来,我们在项目中使用了Storm。今天,我们发现了一个非常奇怪的行为。 假设我们有以下拓扑结构:



因此,我们有一个喷口,它向两个不同的螺栓发出一个自定义Java对象(我们称之为消息)。博尔特B和博尔特C。基本上,我们进行拆分

直到今天,我们一直假设,如果SpoutA发出消息对象,它将在SpoutA上序列化,并在BoltB和BoltC上反序列化。然而,这一假设似乎是错误的。今天,我们发现BoltB中的反序列化对象与BoltC中的对象相同(相同的System.IdentityFyHashCode)。换句话说,如果我在BoltB中操纵对象,我也在BoltC中操纵对象,导致许多不可预见的副作用

此外,这种行为对我来说似乎很奇怪,因为它只适用于喷嘴和相应的螺栓B和C在同一个工作台上运行的情况。如果我显式地强制使用三个works,那么对象(正如预期的那样)对于BoltB和BoltC是不同的对象,因为它在不同的JVM中使用。因此,如果我们假设有一个更大的拓扑(50个不同的螺栓)运行在三个工作线程上,那么我们永远无法确定对象当前是否在螺栓之间共享

所以基本上,我们真的不希望螺栓之间共享对象。我们通常期望在反序列化过程中,为每个螺栓创建新的不同对象

所以我的问题是: 我们的主要缺陷是什么?我们的主要缺陷是发射“可变”对象吗?我们使用序列化/反序列化错误吗?或者它甚至可能是暴风雪的一个设计缺陷

显然,我们可以通过发送字节数组来强制创建新对象,但在我看来,这与Storm是矛盾的

致以最良好的祝愿,
André

为什么您希望哈希代码会有所不同?正如没有要求每个新对象实例(具有相同的字段和字段值!)的用户提供的hashcode值应该不同一样,也没有要求本机hashcode实现在创建同一对象两次时返回不同的值

那么回答你的问题:我们的主要缺陷是什么

主要的缺陷是您对hashcode工作原理的理解。正如Mahesh Madushanka在评论中指出的,您可以绕过此功能


此外,当序列化对象时,它会序列化所有内容,包括私有字段。许多Java对象将其哈希值缓存在私有字段中。例如,字符串。因此,它们的哈希代码将返回相同的值是完全正常的(我知道您使用System.IdentityFyHashCode,String将返回一个覆盖的值,但记住这一点很重要)。

Storm在将元组从一个组件移动到另一个组件时使用两种不同的排队方法,一个是两个组件在同一个JVM中,另一个是元组必须跨JVM移动。我认为您正陷入同一个JVM案例中,元组中的对象实际上并没有序列化,因为序列化只在跨JVM队列中需要


我总是对tuple和javabean之间的数据进行marshall和demarshall处理,以便在每个插销中为我的业务逻辑提供一个强类型接口。这样做,我想我无意中避免了您遇到的问题。这可能是解决问题的一种方法。

目前,我们正在生产中运行40螺栓风暴过程,最初我们遇到了更为棘手的问题,因此,当我们从一个螺栓到另一个螺栓解析对象时,我们使用xml序列化,它将作为xml字符串传递。它解决了我们的问题是的,我们还考虑实现我们自己的序列化/反序列化(但是在字节级别)。另一种解决方案是根据约定将传输的对象明确定义为不可变的。但是,我希望可能有更好的解决方案(例如,只需设置强制storm分别反序列化对象…)是的,您可以使用这些选项,这与哈希代码无关。我真的不在乎哈希代码。我关心的是,由两个不同的螺栓反序列化的对象仍然是相同的(不仅仅是哈希代码)。如果我在BoltB中修改对象,它在BoltC中也会更改。这会导致无法定义的行为,因为无法确定螺栓是在同一个VM中执行还是在不同的VM中执行。因此,我们无法确定是否有两个完全相同或完全相等的不同对象。因此,在我看来,这不是ApacheStorm的一个特性,而是ApacheStorm的一个Bug。@Vion所以我不明白,您假设hashcode是相同的,因为对象是相同的。但这一假设是不正确的。那么,您是如何检查这些对象是否相同的呢?您是否对他们的参考进行了“==”比较?因为这就是使两个对象相同的原因。我们通过操纵BoltB中接收的对象的属性(例如计数器)并读取BoltC中的属性(计数器),来检查对象是否相同。我们在BoltB中更改属性的值在BoltC=>中可用,BoltB接收的对象与BoltC接收的对象完全相同。。。我在BoltB中对对象进行的每一次修改也适用于BoltC。。。(就像在一个简单的线程场景中…)好的。很高兴知道。很高兴你发现了。是的,谢谢你的详细解释。半小时前,我还在下面的演示文稿()中读到了一些关于这方面的内容。然而,我不明白为什么Storm网站上没有记录这一点。编组和解编组确实解决了问题,但也可能降低性能。
SpoutA ---> BoltB
       ---> BoltC