特定のスケジュールされたプロセス専用のポートを作成するにはどうすればよいですか?

特定のスケジュールされたプロセス専用のポートを作成するにはどうすればよいですか?

毎日午前 2 時に開始される XYZ バッチ プロセスがあります。この XYZ はポート 59070 で開始するように構成されています。終了すると、このポートはオープン ポートになります。しかし最近、別のプロセスが 59070 を使用していて、この XYZ プロセスが開始されたときに実行に失敗するという問題が発生しました。

回避策として、構成を別のポート 59071 に更新し、プロセスを正常に実行しました。質問ですが、このポート 59070 をブロックして、他のプロセスが使用しないようにする方法はありますか? Solaris 10 を使用しています。

答え1

ポート59070は一時ポート- 使用できるものアウトバウンド任意のプロセスによる TCP 接続。(ポート 59071 も同様なので、これはあまり良い回避策ではありません...)

Solarisでは、一時ポート範囲は次のように設定されます。tcp_smallest_anon_porttcp_largest_anon_port調整可能なパラメータ。デフォルトの範囲は32,768~65,535です。この範囲内のポートは使用中である可能性があります。いつでも送信 TCP 接続によって。

@Jeff Schaller の回答で述べられているように、ポートは先着順で使用されます。したがって、ポートを「予約」する唯一の方法は、常にそのポートにバインドされている何かを用意しておくことです。その回答では、「ポートセーバー」スクリプトを終了してから、そのポートを使用する「通常の」プロセスが実際にbind()そのポートにアクセスするまでの間に、別のプロセスが問題のポートを取得する可能性があることに注意してください。おそらく確かに、それは起こり得ますが、起こり得ます。そして、処理が重要である場合は、そのことを心配する必要があると思います。

一時的なポートを使用しないこと、および/またはプロセスを常に実行するように構成することを推奨します。inetadmプロセスを自動的に実行するサービスを構成するために使用しますこれにより、inetdプロセスは常に「あなたの」ポートにバインドされ、事実上、そのポートがあなたの使用のために予約されます。

答え2

自分で積極的に使用する以外に、ポートの使用をブロックする方法は知りません。私が提案する一般的なアイデアは、バッチ処理を次のように変更することです。

  1. 「ポートセーバー」スクリプトを削除する

  2. 通常のバッチ処理を実行する

  3. 新しい「ポートセーバー」スクリプトを起動する

この回避策はヘルプ不正なプロセスが目的のポートにバインドするのを防ぎます(プロセスはステップ1と2の間、またはステップ2と3の間でポートを取得する可能性があります)。ただし、ないバッチ プロセスが終了したように見えてもポートを解放しない (すべてのプロセスを終了することによって) というバッチ プロセスの事故を防止します。

Perl の「ポート セーバー」スクリプトのサンプルは次のとおりです。

#!/usr/bin/env perl
# listens on the given port
use strict;
use IO::Socket;

my $port = shift or die "Usage: $0 <port>";

my $socket = new IO::Socket::INET(
        LocalHost => '0.0.0.0',
        LocalPort => $port,
        Proto => 'tcp',
        Listen => 1,
        Reuse => 1,
        )
  or die "Cannot create socket: $!\n";

while (1) {
  my $c = $socket->accept();
  shutdown($c, 2);
}

指定されたポートを開いたまま無限ループを実行するため、スクリプトの PID を保存するか、スクリプトを見つけて強制終了する必要があります。

関連情報