くそったれの物語

この記事は、Jet Infosystems Applied Financial Systems Departmentのアーキテクト、Dmitry Ovcharenkoによって作成されました。



統一があるかもしれません! この決定は、Oracle Service Busのバスを介してCRMを他の外部システムと接続する統合アーキテクチャを設計するときに行われました。 Webサービスに基づくオンライン統合に加えて、システムに着信するファイルを受け入れ、CRM側でWebサービスを呼び出します。これは、着信データのタイプごとに特別に設計されています。



ファイルには多くのレコードが含まれており、各レコードにはCRM側で個別のサービスコールが必要です。 ファイル処理は、レコードごとにループで実行されます。 サービスコールごとに5秒かかります-これはかなりの量ですが、設定された要件を満たすには十分でした。 CRMでWebサービスコールを処理するプロセスは、最初にレコードのテイクをチェックしてから、必要なビジネスロジックを実行し、データベースにレコードを作成します。



しかし、「驚き」は、「タイヤフィッティング」の予期せぬ瞬間に発生する可能性があります。 CRMデータベース内の大量のデータに重複が現れ始めました。 何らかの理由で、ソースが大きなファイルを再度送信できることがわかりました(ファイルプロキシサービスによってピックアップされ、Stageフォルダーに配置された直後)。 さらに、複製を作成するWebサービスへの呼び出し間の遅延は非常に小さいため、2番目の呼び出しの時点では、最初の呼び出しのデータはまだ通信されておらず、CRM側のチェックには時間がありません。





統一で地獄に! 現在、処理中のファイルの名前をメモリに保存する別のStatefullサービスをJavaで実装することにしました。 ファイルを受信すると、OSB上のプロキシサービスはJavaサービスを呼び出し、ファイル名をファイルに渡し、現在処理されているかどうかを確認します。 ファイル処理の最後(または例外の場合)に、プロキシサービスは指定された名前のファイルの処理が終了したことをJavaサービスに通知します。 したがって、この名前は現在のリストから削除する必要があります。 同じ名前の2つのファイルを処理することは、ビジネス要件に従って許可されていません。 Javaプロセスだけでなく、再起動中にファイルが存在する場合は処理されたファイルもリセットされるため、サーバーの再起動も怖くありません。



一般に、Oracle SOA Suite Service Bus 11gでは、任意の識別子による同期を使用してプロセスにロックを設定する方法はありません。ファイルの取得時の起動を制限するだけでなく、原則としてStatefullサービスに渡すために同様のアプローチを使用することをお勧めします必要な識別子。



例外が発生した場合でも、リストから処理中のファイルの名前を削除するために、OSBファイルハンドラーに最上位のCatchブロックがあることが重要です。



サービスコード:



@WebService(serviceName = "TaskManager") public class TaskManager { private static HashMap<String,String> map; public TaskManager() { super(); map = new HashMap<String,String>(); } @WebMethod @WebResult(name = "Result") public String addTask(@WebParam(name = "ProcessName") String name){ String result; try{ result = map.get(name); // Try to get name from map }catch (Exception e){ // if there is no such name result = null; // we receive exception } if (result == null){ // if there is no such name map.put(name, "Is running"); // we add name result = "Task added"; } else{ result = "Task is running"; // else - inform caller } return result; } @WebMethod @WebResult(name = "Result") public String removeTask(@WebParam(name = "ProcessName") String name){ String result; try{ result = map.get(name); }catch (Exception e){ result = null; } if (result == null){ result = "There is no task"; } else{ map.remove(name); result = "Task removed"; } return result; } }
      
      







この方法は非常に簡単ですが、残念ながら、クラスター展開オプションでは機能しません。 また、OSB処理と現在のプロセスのリストの両方が再起動時にリセットされるように、WebLogic OSB管理対象サーバーにデプロイすることが望ましいです。 OSBサーバーがクラスター内にある場合、サービスは別の管理対象サーバーにデプロイする必要があり、再起動するときにこの事実を覚えておく必要があります。



結論として。 このような繰り返し処理に対する保護により、ソリューションは1年以上機能しましたが、新しいローディングメカニズムに置き換えられました。 Oracle SOA Suiteに実装され、そのレコードの処理は並行して実行されます。 しかし、別のトピックがこのトピックを開きます。



建設的なコメントを歓迎します。



All Articles