2

拥有一个由 3 个服务器节点(美属萨摩亚、阿拉斯加、阿拉巴马)和 1 个客户端节点(VoterClient)组成的视图。每当我尝试在以下情况下是美属萨摩亚的视图中调用第一台服务器中的投票方法时,我都会收到 NoSuchMethodException。这是视图中的节点列表,如下图所示:(ping_dest 是美属萨摩亚,pingable_mbrs=[美属萨摩亚,阿拉斯加,阿拉巴马,VoterClient])。所以当我打电话时

// Call the vote method on the state.
voteResult = dispatcher.callRemoteMethod(address1, "vote",
    new Object[] { obj.ID, obj.candidate },
    new Class[] { String.class, String.class },
    new RequestOptions(ResponseMode.GET_ALL,    50000));

address1的地址在哪里"American Samoa"obj.ID并且obj.candidateString远程投票方法的参数,我得到 NoSuchMethodException。

这是我的日志和例外:

1644 调试 [main] org.jgroups.protocols.FD_SOCK - VIEW_CHANGE 收到:[美属萨摩亚、阿拉斯加、阿拉巴马、VoterClient、VoterClient]
1664 DEBUG [FD_SOCK pinger,StateServerGroup,VoterClient] org.jgroups.protocols.FD_SOCK - ping_dest 是美属萨摩亚,pingable_mbrs=[美属萨摩亚、阿拉斯加、阿拉巴马州、VoterClient、VoterClient]
1664 调试 [main] org.jgroups.protocols.pbcast.STABLE - [ergonomics] 将 max_bytes 设置为 20MB(5 个成员)
这应该发生吧????
国家服务器地址:美属萨摩亚。
java.lang.NoSuchMethodException:投票
    在 org.jgroups.blocks.MethodCall.invoke(MethodCall.java:312)
    在 org.jgroups.blocks.RpcDispatcher.handle(RpcDispatcher.java:326)
    在 org.jgroups.blocks.RequestCorrelator.handleRequest(RequestCorrelator.java:456)
    在 org.jgroups.blocks.RequestCorrelator.receiveMessage(RequestCorrelator.java:363)
    在 org.jgroups.blocks.RequestCorrelator.receive(RequestCorrelator.java:238)
    在 org.jgroups.blocks.MessageDispatcher$ProtocolAdapter.up(MessageDispatcher.java:543)
    在 org.jgroups.JChannel.up(JChannel.java:716)
    在 org.jgroups.stack.ProtocolStack.up(ProtocolStack.java:1026)
    在 org.jgroups.protocols.pbcast.STATE_TRANSFER.up(STATE_TRANSFER.java:178)
    在 org.jgroups.protocols.FRAG2.up(FRAG2.java:181)
    在 org.jgroups.protocols.FlowControl.up(FlowControl.java:418)
    在 org.jgroups.protocols.FlowControl.up(FlowControl.java:400)
    在 org.jgroups.protocols.pbcast.GMS.up(GMS.java:889)
...
    在 org.jgroups.protocols.TP$IncomingPacket.handleMyMessage(TP.java:1728)
    在 org.jgroups.protocols.TP$IncomingPacket.run(TP.java:1710)
    在 java.util.concurrent.ThreadPoolExecutor.runWorker(未知来源)
    在 java.util.concurrent.ThreadPoolExecutor$Worker.run(未知来源)
    在 java.lang.Thread.run(未知来源)
VoteAction 的调度程序失败。

投票方式如下:

公共类 EvoterServer 扩展 ReceiverAdapter 实现 Runnable{
    私有静态最终字符串 serverProperties = null; // 默认属性
    私有静态 Logger logger = Logger.getLogger(EVoterServer.class);
    私人 JChannel 频道 = null;
    私有字符串 stateName = null;    
    私有静态最终字符串 serverProperties = null; // 默认属性
    private static final String channelName = "StateServerGroup";
    私有布尔 isRunning = true;

    @覆盖
    公共无效运行(){
        尝试 {
               频道 = 新的 JChannel(服务器属性);
            通道.setName(stateName);
            @SuppressWarnings("未使用")
            RpcDispatcher dispatcher = new RpcDispatcher(channel, this, this, this);
            通道.连接(通道名称);
            通道.getState(null, 0);

            logger.info(stateName + " 服务器开始于 " + new Date() + ".");
            logger.info(stateName + " 加入频道 '" + channelName + "' (" + channel.getView().size() + " members).");
            logger.info(stateName + "服务器准备好服务请求。");
            logger.info(stateName + " 服务器的频道地址是 " + channel.getAddress() + ".");

            isRunning = true;

            而(正在运行){
                实用程序.sleep(10000);
            }
        }
        捕获(异常 e){
            logger.error("EVoterServer.run(); 状态:" + stateName + "; " + e.getMessage(), e);
        }
        最后
        {
            实用程序关闭(通道);
        }
    }

    公共布尔投票(字符串 voterId,字符串候选人名称)
    {
         System.out.println("投票给" + CandidateName + " by " + voterId + ".");
         返回真;
    }
}

这是驱动程序类'(主要方法片段);我如何为每个州初始化服务器。

字符串 [] STATE_NAMES = {“阿拉巴马”、“阿拉斯加”、“美属萨摩亚”};
       for (int i = 0; i < 3; i++) {
           尝试 {
              EvoterServer 服务器 = 新的 EvoterServer(STATE_NAMES[i]);
              新线程(服务器).start();
            } 捕捉(可投掷的 t){
               logger.error(t.getMessage(), t);
            }
       }

我认为这与 GMS 选出的协调员有关。当协调者与投票服务器状态相同时,客户端无法投票。下面显示了如何选举美国萨摩亚协调员:

1401 DEBUG [main] org.jgroups.protocols.UDP - 创建单播接收线程
1401 DEBUG [main] org.jgroups.protocols.UDP - 创建多播接收线程
1411 调试 [main] org.jgroups.protocols.pbcast.GMS - 选举结果:{美属萨摩亚=2}
1411 调试 [main] org.jgroups.protocols.pbcast.GMS - 向美属萨摩亚发送 JOIN(VoterClient)
第1523章
[setDigest()]
4

2 回答 2

1

java.lang.NoSuchMethodException:投票

如果JgroupsMethodCall.invoke()无法找到相关方法,则会引发该异常。我看到了可能发生这种情况的多种原因:

  • 您提到这适用于您的其他服务器。会不会是这个软件运行的是旧版本的软件?也许该vote()方法最近更新了?
  • 处理程序对象是否有可能EVoterServer没有正确注册?
  • 我很好奇错误信息failed on dispatcher for VoteAction。是什么VoteAction?它有可能被注册而不是EVoterServer?也许这是一个不同的频道偶然连接到错误的组?

希望这里有帮助。

于 2012-06-05T22:38:30.190 回答
0

由于您使用的是默认配置,这意味着您依赖于 IP 多播。Multicast to self 有时会被禁用,有时会出现奇怪的行为 - 取决于操作系统和交换机。

尝试使用没有多播的 TCP 堆栈实例化 JChannel(只是为了测试理论 - TCP 几乎是肯定的)。如果可行,请继续返回 UDP(首先不使用多播,然后使用)。您可能需要了解是否需要进行远程调用,具体取决于地址(如果 address == local 只是正常调用该方法,而不是远程调用)。

于 2012-06-14T12:44:46.183 回答