在运维工作中我们经常需要检测用户访问是否正常,一般来说,直接通过 DNS 客户端获取 A 记录就可以满足需要。不过如果我们可以获得具体连接的 IP 地址,那么就可以缩小问题的判断范围,因为 DNS 的 A 记录通常是有多个的。
AE::HTTP 模块可以返回 sock 给用户进行具体操作,我们可以通过 sock 接口很简单的获得对端的 IP 地址:
package Web::Checker::Util::HTTP; use Moo; use MooX::Types::MooseLike::Base qw/Str Num/; use AnyEvent::HTTP; use AnyEvent::Socket; use AnyEvent; use Time::HiRes qw/time/; has peer => ( is => 'rw', isa => Str ); has reptime => ( is => 'rw', isa => Num ); has clength => ( is => 'rw', isa => Num ); has body => ( is => 'ro', isa => Str ); has proxy => ( is => 'ro', isa => Str, default => sub { undef } ); has cv => ( is => 'ro', default => sub { AnyEvent->condvar } ); sub get { my ( $self, $url ) = @_; $self->cv->begin; my $begin = time; http_get $url, proxy => $self->proxy, # 就是这里发挥了作用,默认应该是直接返回 body 字符串的 want_body_handle => 1, sub { my ( $hdl, $headers ) = @_; my ( $port, $peer ) = AnyEvent::Socket::unpack_sockaddr getpeername $hdl->{fh}; $self->peer( AnyEvent::Socket::format_address $peer ); if ( $headers->{Status} =~ /^2/ ) { my $end = time; $self->reptime( $end - $begin ); $self->clength( $headers->{'content-length'} ); $self->cv->end; } }; $self->cv->recv; } 1;
其实 AE::HTTP 还可以在 tcp_connect 的时候获取 sock,这时候就需要自己用AnyEvent::Handle 写一遍 AnyEvent::HTTP::tcp_connect 已经写过的东西了(当然如果你本来就打算干点别的事情,那就是另外一回事情了)~~
暂无评论
写评论