2017-04-21 11 views
0

私のサーバーでは、メールを頻繁に送信する必要があります。電子メールは重いです。彼らはそれらに添付ファイルとインラインイメージを持っています。メインコードフローをブロックしてJavaで電子メールを送信する最良の方法は何ですか?

現在のコードは、メールが送信されるまでコードをブロックします。 (電子メールごとに5〜6秒が失われます)

メインコードの流れを阻止して電子メールを処理する最良の方法は何ですか?

スレッドを提案している場合は、スレッドを効率的に処理できるかどうかを教えてください。

+2

効率的にはどういう意味ですか?シングルスレッドのみで処理できます。メールのための余分なスレッドを追加するそれはそれです。これは誰もが従う一般的なアプローチです。 –

+0

スレッドは、常にメインスレッドをブロックせずに重いプロセスを実行するソリューションです。これはあなたのコードと同じくらい効率的です...一度に複数のメールを送信する場合は、複数のスレッドを使用します(ドン無制限の金額を使用する)。しかし、それ以上の完全な答えはありません。必要に応じてスレッドに関するガイドをお読みください – AxelH

+0

さらに詳しい情報を入力してください。 Spring、Java EE、または別のフレームワークを使用していますか? Java Mail APIやその他のライブラリを使用していますか? – ipper

答えて

1

この機能を実現するには複数の方法があります。

同期呼び出し

これは、あなたが既に使用しているものです。コードは(同期的に)Java Mail APIを呼び出し、APIが実行を完了するのを待ちます。プロセス等、電子メール・メッセージ(データベースからレコードをフェッチし、画像/文書(添付ファイル)を読み込むの構築の複雑さに応じてのために

トレードオフ

  1. をメールサーバとの通信を、時間がかかる場合があります
  2. メールを送信する際の例外として、処理全体のやり直しが必要になる場合があります(再試行の場合)
  3. トランザクションデータ(Web /デスクトップ)、応答待ち時間は、例えばDB)は、e電子メールを送信している間。これは望ましい動作ではないかもしれません。
  4. 同様の機能が複数のユーザーによって同時に呼び出された場合は、全体的なアプリケーションの待ち時間が長くなります。
  5. 電子メールの送信コードが他の機能コードと緊密に結合されていると、電子メールの再試行機能が使用できない場合があります。

マルチスレッドアプローチ

非同期的に電子メールを送信するために別のスレッドを作成します。呼び出しコードは、コードの残りの部分を完了して実行する電子メール送信機能を待つ必要はありません。理想的には、新しいスレッドを穏やかに作成するのではなく、ThreadPoolを使用する必要があります。

トレードオフ

  1. ものの、待ち時間が下がるだろう要求し、それはまだ信頼できるものではありません。電子メールの作成/送信中に例外が発生した場合、電子メールはユーザーに送信されません。

  2. メール送信機能を複数のマシンに分散することはできません。

  3. 電子メールコードが別のクラスに分かれているので、再試行機能が可能です。このクラスは、他のものをやり直す必要なく、独立して呼び出すことができます。

非同期処理

メール要求とデータベースまたはメッセージングインフラストラクチャのどちらかに格納する(例えば、JMS)を受け付けるクラスを作成します。メッセージリスナーは、到着時にタスクを処理し、各タスクに対してステータスを更新します。

トレードオフ

  1. メール要求が分散モードで処理することができます。
  2. 副作用を起こすことなく、電子メールを再試行できます。
  3. 複数のコンポーネントとしての複雑な実装は、電子メール要求を永続化して処理することに関係しています。
+0

だから私は最高のアプローチは、マルチスレッドのアプローチと一緒に非同期処理を組み合わせることだと思う。送信する必要があるすべての電子メールをデータベースのテーブル1にプッシュする必要があります。電子メールが正常に送信されると、そのレコードは別のテーブル、たとえばtable2にプッシュされます。これらはすべて個別にスレッドで実行される可能性があります。 –

+0

テーブルを別に管理する必要はありません。 PENDING、FAILED、SENTなどの可能な値を持つ同じテーブル内のステータスフィールドを持つだけです – CuriousMind

0

送信する必要があるメールごとにスレッドを生成すると、これを効率的に行うことができます。


あなたはThreadのちょうど純粋な拡張であるクラス必要があります:

public class MailSenderThread extends Thread {   
    @Override 
    public void run() { 
     try { 
      // Code to send email 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     }  
    }  
} 

そして、あなたは電子メールを送信したい、あなたは次のようにそれを行うには

一つの方法ですすることができます:

new MailSenderThread().start(); 

これは私が考えることができる最短/最も簡単な方法です。


an example in my public repositoryも参照してください。それはオフトピックですが、それは概念を取得します。

関連する問題