私は単純な分散プログラムを書いています。buy メソッドは、RMI を使用して同時クライアントにサービスを提供します。10人ごとの顧客に割引を適用したい. 購入リクエストの順序は、タイム スタンプに基づいて 10 番目の顧客を選択します。購入方法を実装する最良の方法は何ですか。
2 に答える
これを行う方法はたくさんあります。タイムスタンプが十分にランダムであれば使用できますが、使用することもできます。
static final AtomicInteger COUNTER = new AtomicInteger();
if (COUNTER.getAndIncrement() % EVERY_NTH_USER == 0) {
// give offer
}
うーん、これは宿題ですか?タイムスタンプの使用を主張して、処理が順不同の場合に間違った顧客に割引を提供しないようにします。しかし、「顧客は 10 人に 1 人」というのは非常に恣意的なルールのように聞こえます。注文が行われたときではなく、注文がサーバーに届いたときに通り過ぎるかどうかは誰が気にしますか?
注文が行われたときに割り当てられたタイムスタンプによって行われなければならないが、割引を決定するサーバーが必ずしも注文を順番に受け取るとは限らないと仮定すると、... 注文前の既知の最大遅延はありますか?サーバーに到達し、割引を適用する前に少なくともそれだけ待つことができますか? そうでない場合、問題は解決できません。サーバーが注文のタイムスタンプを見て、一部の注文が 10 番であると判断した場合、9 番と 10 番の間にタイムスタンプがあり、まだ輸送中で、まだ到着していない別の注文がないことをサーバーはどうやって知るのでしょうか。 ?
「10 番目ごとの注文」を決定するには、定義上、注文をカウントしている中央サーバーが必要であると考えます。そのため、すべての注文はこの単一のサーバーを通過するか、少なくともこの単一のサーバーに「登録」する必要があります。したがって、カウントする論理的な方法は、注文が到着したときにカウントすることです。
最大待ち時間を過ぎて到着した注文を拒否できますか? または、たとえば、90% の確率で注文が 3 秒以内に到着する場合、注文が 3 秒以内に到着しない場合、厳格な 10 分の 1 注文ルールを満たしていない可能性があることを受け入れると言えますか? 答えが「いいえ」の場合、その問題は不可能です。
問題の定義が、独立した並行サーバーによって割り当てられたタイムスタンプに基づいて実行する必要があるというものである場合、それを実行できる唯一の方法は、注文が中央に到達するのにかかる最大時間を知ることですサテライト サーバーからのサーバー。次に、注文をタイムスタンプで並べ替え、最後の割引が付与されてから 10 カウントします。その注文のタイムスタンプが maxium-wait-time 前よりも短い場合、割引を提供できるかどうかを決定する前に待機する必要があります。次に、前に戻ってプロセスをもう一度やり直します。今回は、前回の試行以降に到着した新しい注文をすべて含めます。何かのようなもの:
(pseudo-code)
loop forever
select order_id, timestamp from orders where prcoessed=0 order by timestamp
count to tenth record
if timestamp<now-max_wait then
award discount to number 10
mark numbers 1 to 10 as processed
else
do nothing
endif
endloop
具体的には、タイムスタンプ ルールを考えると、注文を受け取った瞬間に割引を与えることはできません。これは、以前のタイムスタンプを持つ別の注文が進行中ではないことを知る方法がないためです。
最大待ち時間の後に到着した注文をどうするか、注文を拒否するか、到着時に処理を許可するかなどについて、何らかの決定を下す必要があります。
注文時に割引を受けていることを顧客に通知することを期待している場合、あなたが知らないため、それは不可能です。最大待機時間が数秒以下のように十分に短い場合は、その時間が経過するまで顧客への応答を延期できる場合があります。最大待機時間が数分である場合、応答をそれほど長く停止させることはできないと思います. しかし、それは他の要件に依存すると思います。