0

AnyEvent::DNS一部の DNS サーバーで自分のドメインを解決するために使用したいと考えています。サーバーリストは、それぞれ約 60 以上のサーバーの 2 つの場所から取得されます。1 つのサーバー リストに対してのみ解決を実行すると、問題はありません。しかし、すべてのリストに対して解決を実行すると、エラーが発生しました: "unable to create either an IPv4 or an IPv6 socket".

私のスクリプトは次のとおりです。

#!/usr/bin/perl
use Modern::Perl;
use AnyEvent::DNS;
use AnyEvent::Socket;
use AnyEvent;
use Module::Runtime qw/require_module/;
use lib './lib';

my $domain = $ARGV[0] // 'fmn.xnimg.cn';
my $cv = AnyEvent->condvar;

for my $mod ( ( 'DNS::xixik', 'DNS::yqie' ) ) {  # error
#for my $mod ( ( 'DNS::xixik' ) ) {  # ok
    require_module($mod);
    my $dnslist = $mod->new->get_dnslist;
    for my $isp ( keys %$dnslist ) {
        while ( my ( $addr, $dns ) = each %{ $dnslist->{$isp} } ) {
            resolv( $isp . $addr, $_, $domain ) for @{$dns};
        }
    }
}
$cv->recv;

sub resolv {
    my ( $addr, $dns, $domain ) = @_;
    my $resolver = AnyEvent::DNS->new(
        server => [ AnyEvent::Socket::parse_address $dns ],
    );
    $cv->begin;
    $resolver->resolve(
        "$domain" => 'a',
        sub {
            my @ips = map { $_->[-1] } @_;
            printf "%s (%s) => %s\n", $dns, $addr, join( ", ", @ips ) if @ips;
            $cv->end;
        }
    );
}
4

1 に答える 1

1

AnyEvent::DNS には人為的な制限はありませんが、未処理の並列クエリの数は max_outstanding 構成値に制限されています (この制限を超えても、単にリクエストが遅延するだけで、エラーは発生しません)。ただし、すべてのリクエストに対してリゾルバーを作成します。各リゾルバーには 1 つ以上のソケットが必要であり、これが問題になる可能性があります (通常、プログラム内の他のコードも多くのソケットを作成しない限り、500 以上のリゾルバーを作成できるはずです)。ハンドル、または Windows を使用している)。

非常に多くのリゾルバーが本当に必要な場合は、ファイル記述子の制限を増やす必要があります。UNIX では、スクリプトを開始する前に ulimit -n を使用してこれを行うことができます。

于 2013-12-29T00:16:17.910 に答える