=encoding utf8
=for advent_year 2014
=for advent_title 客户端来源 IP 信息处理
=for advent_author fukai
=head2 前言
我们进行日志处理, 常有的一个需求就是需要日志中来源的 IP 变成指定的信息来进行分析, 也有可能有一种需求, 就是需要给所有用户的请求转换成 "ISP, 省市, 城市", 然后在排序分析用户来源相关的信息, 如省市排名, 运营商排名, 更加复杂的还有可能, 根据这些信息来做基础信息来判断用户的体验, 比如那个地区, 那个 ISP 的用户访问速度最快等等.
另外, 对于象视频, 大文件下载, 这种应用, 目前很多是基于 HTTP 之类的更加高级的调度, 这时我们就需要更加给请求过来的用户 IP , 也转换成相应的地区, 然后查询自己的全网调度系统中, 是否存在相应最优节点.
基于以上二点, 我们需要非常非常快速的 IP 转换成城市信息的模块. 在 08 年的时候, 我就想过各种方式, 使用过 Geo::IP 之类的库, 当年的 QQway.bat 的结构,还有比如给 IP 段折开, 存到数据之类的地方, 然后有了 IP , 根据这个信息来查询段是什么 ISP 和地区, 试过各种方式, 但速度和效率都不太理想.
比如日志 cat 出来后进行二次分析和清洗的时候, 这个查询和转换是最占用时间的, 真到我找到了 Net::IP::Match::Trie 这个模块, 这个速度快到可以不影响你 cat 的速度, 直接线性的处理 IP 到信息的转换.
当年这个模块还是刚出来的时候我关注到的, 非常好用, 非常想推荐给其它人. 但一直没有发布正式版本, 就这样用了几年, 因为不是正式版本, 所以 cpanm 一直找不到这个模块, 要指定 url 才能安装. 直到去年末, 我发了个邮件给作者, 提醒他, 这个模块几年还没 release , 作者接到邮件后立即就更新, 所以现在正式接这个机会推荐给有相应需求的朋友 ( 注: cpan 作者都非常热情, 有问题直接联系作者哦 ). 注: 我自己的调度系统中一直使用这个模块, 很多年了.
=head2 原始 IP 段和地址信息的加入
进行 IP 信息处理, 我们需要先收集 IP 段是哪个运营商. 目前网络上这种数据很多, 可以下载任何一个数据来加入到这个模块当中.
use Net::IP::Match::Trie;
my $matcher = Net::IP::Match::Trie->new;
$matcher->add(CNC-ZJ-ZJ => [qw(66.249.64.0/19 74.125.0.0/16)]);
我是直接给对应的信息写成了一个如下的文件结构, 然后使用上面的方式导入.
上面 add 的 key 就是后面的 CNC,ZJ-ZJ. 然后在加上网段.
=head2 来源 IP 的查询
查询非常简单, 只需要给 IP 放到 match_ip 的方法中就搞定了.
say $matcher->match_ip("66.249.64.1"); # => "CNC-ZJ-ZJ"
=head2 样例
下面是一个简单的管道传送过来的日志进行 IP 地址翻译的小程序.
use strict;
use 5.010;
use Net::IP::Match::Trie;
my $matcher = Net::IP::Match::Trie->new;
open my $fh, "<", 'isp_ip.csv' or die "print $!";
while (<$fh>) {
my ($CIDRS, $isp, $region) = split(/,/, $_);
chomp $region;
my $name = "$isp-$region";
$matcher->add( $name , [$CIDRS] );
}
while(<>){
chomp;
my $ISP = $matcher->match_ip($_);
print "$_, $ISP\n";
}
=head2 使用
象上面, 可以用于日常的日志处理, 让信息读进来一次, 给 IP 以流的方式 cat 进去就好了, 象日志处理什么之类就非常好用了.
# echo 202.106.0.20 |perl check.pl
202.106.0.20, CNC-BJ-BJ
=head2 IP 段的整理
象上面的 IP 段, 因为运营商信息不断的变化, 所以你的 IP 数据库也会跟着不断的变化, 当运营商给你一堆 IP 时, 你对很多重复的段要合并, 有些小的段要折分, 这样手工操作很累, 同样, 也推荐一个模块, 叫 Net::IP::RangeCompare , 小小包装和处理一下, 配合起来使用, 非常合适.
=head2 作者
fukai, L<mail://iakuf@163.com>
=cut
您收到此邮件是因为您订阅了Google网上论坛上的"PerlChina Mongers 讨论组"群组。
要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到perlchina+unsubscribe@googlegroups.com。
要发帖到此群组,请发送电子邮件至perlchina@googlegroups.com。
访问此群组:http://groups.google.com/group/perlchina。
要查看更多选项,请访问https://groups.google.com/d/optout。
没有评论:
发表评论