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.IDobj.candidateリモートString投票メソッドのパラメーターです。NoSuchMethodException が発生します。

ここに私のログと例外があります:

1644 DEBUG [メイン] 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 DEBUG [メイン] org.jgroups.protocols.pbcast.STABLE - [エルゴノミクス] 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 のディスパッチャーで失敗しました。

投票方法は次のとおりです。

public class EvoterServer extends ReceiverAdapter implement Runnable{
    private static final String serverProperties = null; // デフォルトのプロパティ
    プライベート静的ロガー logger = Logger.getLogger(EVoterServer.class);
    プライベート JChannel チャネル = null;
    プライベート文字列 stateName = null;    
    private static final String serverProperties = null; // デフォルトのプロパティ
    private static final String channelName = "StateServerGroup";
    プライベートブール isRunning = true;

    @オーバーライド
    public void run() {
        試す {
               channel = new JChannel(serverProperties);
            channel.setName(stateName);
            @SuppressWarnings("未使用")
            RpcDispatcher ディスパッチャ = 新しい RpcDispatcher(チャネル、これ、これ、これ);
            channel.connect(チャンネル名);
            channel.getState(null, 0);

            logger.info(stateName + " server started at " + new Date() + ".");
            logger.info(stateName + " 参加したチャンネル '" + channelName + "' (" + channel.getView().size() + " members).");
            logger.info(stateName + "サーバーはリクエストを処理する準備ができています。");
            logger.info(stateName + " サーバーのチャンネルアドレスは " + channel.getAddress() + ".");

            isRunning = true;

            while(実行中) {
                Util.sleep(10000);
            }
        }
        キャッチ(例外e){
            logger.error("EVoterServer.run(); 状態: " + stateName + "; " + e.getMessage(), e);
        }
        最後に
        {
            Util.close(チャンネル);
        }
    }

    public boolean vote(文字列voterId、文字列候補名)
    {
         System.out.println("" + 候補名 + " に " + 投票者 ID + " で投票");
         true を返します。
    }
}

これがドライバークラスです(メインメソッドのスニペット)。各状態のサーバーを初期化する方法。

String [] 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 DEBUG [メイン] org.jgroups.protocols.pbcast.GMS - 選挙結果: {アメリカ領サモア=2}
1411 DEBUG [main] org.jgroups.protocols.pbcast.GMS - JOIN(VoterClient) をアメリカ領サモアに送信
1523 DEBUG [メイン] org.jgroups.protocols.pbcast.NAKACK -
[セットダイジェスト()]
4

2 に答える 2

1

java.lang.NoSuchMethodException:投票

JgroupsはMethodCall.invoke()、問題のメソッドが見つからなかった場合からその例外をスローします。これが発生する可能性がある理由はいくつかあります。

  • あなたはこれがあなたの他のサーバーで働いていると言いました。古いバージョンのソフトウェアを実行している可能性がありますか?たぶん、vote()メソッドは最近更新されましたか?
  • EVoterServerハンドラオブジェクトが適切に登録されていない可能性はありますか?
  • エラーメッセージが気になりますfailed on dispatcher for VoteAction。何VoteActionですか?代わりに登録された可能性はありEVoterServerますか?たぶん、それは間違ったグループに接続されている偶然の別のチャネルですか?

ここで何かが役立つことを願っています。

于 2012-06-05T22:38:30.190 に答える
0

デフォルト設定を使用しているため、IP マルチキャストに依存していることになります。OS とスイッチによっては、自分自身へのマルチキャストが無効になったり、奇妙な動作をすることがあります。

マルチキャストなしで TCP スタックを使用して JChannel をインスタンス化してみてください (理論をテストするためだけに - TCP はほぼ確実です)。機能する場合は、UDP に戻ります (最初はマルチキャストを使用せず、次に使用します)。アドレスに応じて、リモート呼び出しを行う必要があるかどうかを理解する必要があるかもしれません (アドレス == ローカルの場合、リモートではなく、通常どおりメソッドを呼び出すだけです)。

于 2012-06-14T12:44:46.183 に答える