問題の説明
メールを送信するために SMTP サーバーに接続すると、「SMTP ホストに接続できませんでした」のようなエラーメッセージが表示されます。
原因
このエラーは、プログラムがメール送信の初期段階でメールサーバーに接続する際に問題が発生したために発生します。このとき、メールサーバーには受信レコードと関連する送信ログがありません。一般的に、SMTP 送信コードが配置されているクライアントからトラブルシューティングを開始する必要があります。
解決策
段階的な調査と分析を行い、具体的な状況に応じて対応策を講じます。
1. イベント分析
最初に判断するのは良いでしょうか?すべての呼び出しでエラーが報告されますか(エラーは散発的ですか、それとも必須ですか)?
以前は正常だった場合、問題が発生する前にコードの変更、コンポーネントのスペックアップ、その他の操作が行われたかどうかを確認し、ロールバックと復元を試みます。
エラーを再現できれば、後続のトラブルシューティングが容易になります。
2. 接続分析
465 ポートを例に、次のコマンドを実行してスクリーンショットを撮ります。
コマンド 1:割り当てられたサーバーの IP アドレスを表示します。 IP アドレスはリージョンによって異なります。
ping smtp.sg.aliyun.comping コマンドが失敗した場合、または待機時間が長い場合は、ローカルで ping が禁止されているか、ネットワーク接続の問題である可能性があります。
成功結果:

コマンド 2 (指定されたポートを使用して SMTP サーバーに接続し、ポートとネットワーク接続を確認します):
telnet smtp.sg.aliyun.com 465成功結果:
![]()
または

コマンド 3 (ルーティングパスを確認):
# Linux または Mac コマンド:
mtr -n -i 1 -c 100 smtp.sg.aliyun.com
traceroute smtp.sg.aliyun.com
# Windows コマンド:
tracert smtp.sg.aliyun.com
pathping smtp.sg.aliyun.comSMTP サーバーへのルーティングパスを確認し、どのホップで問題が発生し始めているかを特定します。
デフォルトでは、tracert は最大 30 ホップを表示し、最後の IP はメールボックスサーバーの IP です。
pathping の実行は遅く、統計の生成に数分かかります。
WinMTR などのビジュアルオープンソースツールも使用できます。
成功結果:
コマンド 4 (465 ポートのみ):
# TLS バージョンは指定されていません。
openssl s_client -connect smtp.sg.aliyun.com:465
# TLS バージョンを指定します。
openssl s_client -connect smtp.sg.aliyun.com:465 -tls1_2暗号化方式を使用して接続テストを実行し、ハンドシェイクの例外が TLS バージョンによって引き起こされているかどうかを判断します。
成功結果:
CONNECTED

3. 除外分析
ポート 25 やポート 80 など、他のポートでメッセージを正常に送信できるかどうかを確認します(ECS はデフォルトでポート 25 を禁止していることに注意してください)。ポート 80 が成功するかどうかを試すことができます。これらの 2 つのポートは SSL 関連のコードを使用しません。関連するコードをコメントアウトしてください。
他のポートは正常だが、465 は機能しない場合:465 ポートで SSL を強制的に有効にします
final Properties props = new Properties(); props.setProperty("mail.smtp.ssl.enable", "true");
他のスクリプトから個別に送信するか、サンプルコードを使用して送信してみてください(他のビジネスロジックからのコードの干渉を除外するため)。
Direct Mail プロダクトの例(参考まで):
他のサーバーアドレスを使用し、ポート 465 を使用してテストメールを送信します。たとえば、qq メールボックス smtp.qq.com、Netease メールボックス smtp.163.com、Alibaba Cloud Direct Mail smtpdm.aliyun.com などです。
4. パケットキャプチャ分析
ポート 25 または 80 が無効になっていない場合(465 ポートの暗号化では詳細は表示されません)、ポート 25 または 80 でパケットをキャプチャして分析できます。
パケットキャプチャプロセスとコマンドリファレンス:
送信者がパケットキャプチャを開始します(メールボックスの IP アドレスとポートを指定します)
linux コマンドリファレンス:デフォルトの保存ルートディレクトリ。コマンドを変更して保存ディレクトリを指定することもできます(例:/tmp/capture.pcap)。
sudo tcpdump -i eth0 host xx.xx.xx.xx and port 80 -w capture.pcapwindows:wireshark を使用します。
メールをテストし、問題を再現します。
パケットキャプチャを停止します
linux:コマンド実行インターフェイスで ctrl + c を押してパケットキャプチャを停止します。
windows:ソフトウェアの操作停止ボタン。
wireshark で分析を開きます。
その他の考えられるオプション
ハンドシェイクフェーズでの暗号化アルゴリズムの不一致
Java 環境を例に挙げます。JRE の高バージョンでは、暗号化アルゴリズム SSLv3、TLSv1、TLSv1.1 などが禁止されています。バージョンを指定するか、関連する無効な項目を削除してみてください。
final Properties props = new Properties(); props.put("mail.smtp.ssl.protocols", "TLSv1.2");SSL で接続を確立し、失敗した場合は互換性を維持するためにフォールバックします。
何らかの理由で SSL を使用して接続を確立できない場合(たとえば、サーバーが SSL をサポートしていない場合)、暗号化されていない接続方法にフォールバックするのではなく、接続試行を失敗させます。
final Properties props = new Properties(); prop.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); prop.put("mail.smtp.socketFactory.fallback", "false");
その他の分析方法
デバッグモードを有効にすると、サーバーとの対話プロセスが出力され、他のフェーズでのエラー分析に使用できますが、現在のシナリオには適用できない場合があります。
Java の例:
// デバッグモードを有効にします:
Session mailSession = Session.getInstance(props, authenticator);
mailSession.setDebug(true);