
我們有一個 XYZ 批次流程,每天凌晨 2:00 啟動。此 XYZ 配置為在連接埠 59070 上啟動。但最近我們遇到了一個問題,另一個進程正在使用 59070,當這個 XYZ 進程啟動時,它無法運作。
作為解決方法,我們已將配置更新到不同的連接埠 59071 並正常運行該過程。我的疑問是,我們是否可以阻止此連接埠 59070 並確保沒有其他進程使用它?我們正在使用 Solaris 10。
答案1
埠 59070 是臨時連接埠- 一個可以用於出境任何進程的 TCP 連線。 (連接埠 59071 也是如此,所以這並不是一個很好的解決方法...)
在 Solaris 上,臨時連接埠範圍由以下方式設置的tcp_smallest_anon_port
和tcp_largest_anon_port
可調參數。預設範圍是 32,768 到 65,535。該範圍內的任何連接埠都可能正在使用中隨時透過傳出 TCP 連線。
正如 @Jeff Schaller 的回答所述,連接埠是按照先到先得的原則使用的,因此「保留」連接埠的唯一方法是始終將某些東西綁定到它。請注意,在該答案中,另一個進程可能會在殺死「連接埠保護程式」腳本和實際使用該連接埠的「正常」進程之間的時間內取得有問題的連接埠bind()
。它不是可能,誠然,但這可能會發生。如果您的處理至關重要,我認為您需要擔心這一點。
我建議不要使用臨時連接埠和/或將進程配置為始終運行,或者用於inetadm
配置自動運行您的進程的服務。這將導致inetd
進程始終綁定到“您的”端口,從而有效地保留它供您使用。
答案2
除了自己主動使用連接埠之外,我不知道有什麼方法可以阻止連接埠的使用。我提出的總體想法是將批次更改為:
殺死“連接埠保護程式”腳本
運作正常的批次
啟動一個新的「連接埠保護程式」腳本
此解決方法將幫助防止惡意進程綁定到您想要的連接埠(進程可能會在步驟 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 或找到並終止它,因為它在保持給定連接埠開啟的同時運行無限循環。