用perl给nginx写个IP地址查找模块
2010-12-26
perl怎么给nginx写模块,其实并不难。网上 search 一下很多 如何安装和配置,参考官方文档: http://wiki.nginx.org/EmbeddedPerlModule
nginx配置:
worker_processes 1;
error_log logs/error.log info;
events {
worker_connections 1024;
}
http {
perl_modules /opt/perl/lib/;
perl_require IPaddr.pm;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
perl IPaddr::handler;
}
}
}
模块主要功能:
request 提交一个 IP 地址 www.nginx.com/?8.8.8.8 返回用户这个IP 地区
性能:
不搭载nginx 跑了下 查找一个IP 消耗 20ms 速度并不快(不统计预编译时间)。 搭载nginx 测试了下
time curl http://192.168.1.103/?211.151.63.100
北京市
real 0m0.135s
user 0m0.004s
sys 0m0.008s
优化计划:
精简IP 地址库标 算法优化 性能提升10倍以上
源代码如下:
package IPaddr;
BEGIN {
open my $fh, "<./ip.list" or die "$!\n";
our %ip;
our @nums;
while(<$fh>)
{
my ($a,$b) = split /\s+/;
push @nums, $a;
$ip{$a} = $b;
}
close $fh;
@nums = sort {$b <=> $a} @nums;
}
use nginx;
use Socket;
sub handler {
$r = shift;
$r->send_http_header('Content-Type', 'text/html; charset=utf-8');
return OK if $r->header_only;
my $city;
my $num = unpack "N4", inet_aton($r->args);
my $index = $#num / 2;
if ( $num <= $nums[$index])
{
for (@nums[$index..$#nums])
{
$city = $ip{$_} and last if $num >= $_;
}
}
else
{
for (@nums[0..$index])
{
$city = $ip{$_} and last if $num >= $_;
}
}
$r->print("$city");
$r->rflush();
}
1;