JGroups RPC:NoSuchMethodException

时间:2012-06-05 20:57:27

标签: multithreading client rpc jgroups

包含3个服务器节点(美属萨摩亚,阿拉斯加,阿拉巴马州)和1个客户端节点(VoterClient)。每当我尝试在视图中的第一个服务器中调用vote方法时,在下面的例子中是美属萨摩亚,我得到一个NoSuchMethodException。以下是视图中的节点列表,如下所示:(ping_dest是American Samoa,pingable_mbrs = [American Samoa,Alaska,Alabama,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.IDobj.candidate是远程投票方法的String参数,我得到NoSuchMethodException。< / p>

这是我的日志和例外:

1644 DEBUG [main]         org.jgroups.protocols.FD_SOCK     - VIEW_CHANGE received: [American Samoa, Alaska, Alabama, VoterClient, VoterClient]
1664 DEBUG [FD_SOCK pinger,StateServerGroup,VoterClient]         org.jgroups.protocols.FD_SOCK     - ping_dest is American Samoa, pingable_mbrs=[American Samoa, Alaska, Alabama, VoterClient, VoterClient]
1664 DEBUG [main]   org.jgroups.protocols.pbcast.STABLE     - [ergonomics] setting max_bytes to 20MB (5 members)
This should be occuring right?????
State server address: American Samoa.
java.lang.NoSuchMethodException: vote
    at org.jgroups.blocks.MethodCall.invoke(MethodCall.java:312)
    at org.jgroups.blocks.RpcDispatcher.handle(RpcDispatcher.java:326)
    at org.jgroups.blocks.RequestCorrelator.handleRequest(RequestCorrelator.java:456)
    at org.jgroups.blocks.RequestCorrelator.receiveMessage(RequestCorrelator.java:363)
    at org.jgroups.blocks.RequestCorrelator.receive(RequestCorrelator.java:238)
    at org.jgroups.blocks.MessageDispatcher$ProtocolAdapter.up(MessageDispatcher.java:543)
    at org.jgroups.JChannel.up(JChannel.java:716)
    at org.jgroups.stack.ProtocolStack.up(ProtocolStack.java:1026)
    at org.jgroups.protocols.pbcast.STATE_TRANSFER.up(STATE_TRANSFER.java:178)
    at org.jgroups.protocols.FRAG2.up(FRAG2.java:181)
    at org.jgroups.protocols.FlowControl.up(FlowControl.java:418)
    at org.jgroups.protocols.FlowControl.up(FlowControl.java:400)
    at org.jgroups.protocols.pbcast.GMS.up(GMS.java:889)
...
    at org.jgroups.protocols.TP$IncomingPacket.handleMyMessage(TP.java:1728)
    at org.jgroups.protocols.TP$IncomingPacket.run(TP.java:1710)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
failed on dispatcher for VoteAction.

这是投票方法:

public class EVoterServer extends ReceiverAdapter implements Runnable{
    private static final String serverProperties = null; // default properties
    private static Logger logger = Logger.getLogger(EVoterServer.class);
    private JChannel channel = null;
    private String stateName = null;    
    private static final String serverProperties = null; // default properties
    private static final String channelName = "StateServerGroup";
    private boolean isRunning = true;

    @Override
    public void run() {
        try {
               channel = new JChannel(serverProperties);
            channel.setName(stateName);
            @SuppressWarnings("unused")
            RpcDispatcher dispatcher = new RpcDispatcher(channel, this, this, this);
            channel.connect(channelName);
            channel.getState(null, 0);

            logger.info(stateName + " server started at " + new Date() + ".");
            logger.info(stateName + " joined channel '" + channelName + "' (" + channel.getView().size() + " members).");
            logger.info(stateName + " server ready to serve requests.");
            logger.info(stateName + " server's channel address is " + channel.getAddress() + ".");

            isRunning = true;

            while(isRunning) {
                Util.sleep(10000);
            }
        }
        catch(Exception e) {
            logger.error("EVoterServer.run(); State: " + stateName + "; " + e.getMessage(), e);
        }
        finally
        {
            Util.close(channel);
        }
    }

    public boolean vote(String voterId, String candidateName)
    {
         System.out.println("Vote for " + candidateName + " by " + voterId + ".");
         return true;
    }
}

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

String [] STATE_NAMES = {"Alabama", "Alaska", "American Samoa"};
       for (int i = 0; i < 3; i++) {
           try {
              EVoterServer server = new EVoterServer(STATE_NAMES[i]);
              new Thread(server).start();
            } catch (Throwable t) {
               logger.error(t.getMessage(), t);
            }
       }

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

1401 DEBUG [main]             org.jgroups.protocols.UDP     - created unicast receiver thread 
1401 DEBUG [main]             org.jgroups.protocols.UDP     - created multicast receiver thread 
1411 DEBUG [main]      org.jgroups.protocols.pbcast.GMS     - election results: {American Samoa=2}
1411 DEBUG [main]      org.jgroups.protocols.pbcast.GMS     - sending JOIN(VoterClient) to American Samoa
1523 DEBUG [main]   org.jgroups.protocols.pbcast.NAKACK     - 
[setDigest()]

2 个答案:

答案 0 :(得分:1)

  

java.lang.NoSuchMethodException:vote

如果Jgroups无法找到相关方法,则会从MethodCall.invoke()中抛出该异常。我看到为什么会发生这种情况的原因有很多:

  • 您提到这适用于您的其他服务器。可能是那个正在运行该软件的旧版本?也许最近更新了vote()方法?
  • EVoterServer处理程序对象是否有可能未正确注册?
  • 我对错误消息failed on dispatcher for VoteAction感到好奇。什么是VoteAction?是否有机会注册而不是EVoterServer?也许这是一个意外的不同渠道,附在错误的群体上?

希望这里有所帮助。

答案 1 :(得分:0)

由于您使用的是默认配置,因此表示您依赖IP多播。多播到自身有时会被禁用,有时会出现奇怪的行为 - 取决于操作系统和交换机。

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