PHP 跟据用户IP获取所在国家高效解决方案(GEOIP)

最近项目中有一个需求统计访客数据,为了保证效率。前端尽量轻量化,仅将访客原始请求信息不作任何处理直接写入消息队列。后端计划任务服务器监听消息队列,解析 user agent, ip 地址,处理结果写入 ES  供报表使用,其中 IP地址处理需要跟据 IP地址获取国家,本文主要研究解决PHP语言跟据IP获取国家的单一需求。

首先解决数据源

1 纯真IP库

缺点:主要为国内IP库,如果仅需要国家信息,则冗余信息多,解析效率低

2 高用第三方接口(如:ip138)解析。

缺点:延时高,稳定性差

排除以上数据源方案。

当前比较可靠的数据源:GEOIP 库,商业化运作,更新频率很高,有提供免费的IP库供下载

官网:

https://geoip.com/

https://www.maxmind.com/

这两个网站是同一家公司。

PHP官方 支持 geoip 扩展,相关方法见官方文档:

https://www.php.net/manual/zh/book.geoip.php

更多的时候,项目不方便安装扩展,可以使用纯 php 的 composer 安装包

官方开发的 PHP composer 安装包:

在 composer 包管理网站 packagist.org 搜 geoip

排名靠前的. geoip2/geoip2,maxmind-db/reader, geoip/geoip 是官方提供的安装包,其中 "geoip/geoip". Abandoned,转到了 geo2/geoip2,


下载库文件:

composer requre geoip2/geoip2

编写代码前,首先需要下载最新版的 IP数据库, 官网下载地址:

https://www.maxmind.com/en/geoip2-country-database

默认是商业版,下载需要一定的费用。支持一次性/按月/按年三种付费方式


同时,官方提供了免费版本,首先在官网注册一个账号,成功后使用账号登录,在用户中心 点 "download files" 下载相关文件


程序示例:

<?php
// 指定 IP数据库,在调用代码中引用该文件:
$reader = new \GeoIp2\Database\Reader('/path/tp/your/GeoLite2-Country.mmdb');
$record = $reader->country('128.101.101.101');
print($record->country->isoCode . "\n"); // 'US'
print($record->country->name . "\n"); // 'United States'
print($record->country->names['zh-CN'] . "\n"); // '美国'
?>

简单测试下效率:

<?php
$reader = new \GeoIp2\Database\Reader( '/path/tp/your/GeoLite2-Country.mmdb');
$success = 0;
$t0 = microtime(1);
for ($i = 0; $i<2000; $i++) {
    try {
        $ip = rand(1,255) . '.' . rand(1,255) . '.' .rand(1,255) . '.' . rand(1,255);
        $record = $reader->country($ip);
        // echo $ip . ':' .  $record->country->isoCode . "<br>\r\n";
        $success++;
    } catch (\Throwable $t) {
    }
}

$t1 = microtime(1);
echo '用时:' . number_format($t1 - $t0, 3, '.', '') . '秒 <br/>';
echo '有效IP: ' . $success . ' 个';
?>

18款MAC笔记本电脑(4核16G 固态硬盘) docker 环境运行结果:

用时:0.834秒

有效IP: 1723 个

随机生成的IP有一部分无效,相当于1秒执行了 2000+ 随机IP查询,已经相当高了,这种高IO 的查询操作固态硬盘是主要因素

如果有更高的效率需求,可以将 IP数据库转入 REDIS

跟据CSV版本的IP数据,当前版本的 IPv4(IPv6 应该需求不多) 数据库仅有 37万多条记录(3711110),

GeoLite2-Country-Blocks-IPv4.csv 内容示例:

network,geoname_id,registered_country_geoname_id,represented_country_geoname_id,is_anonymous_proxy,is_satellite_provider

1.0.0.0/24,2077456,2077456,,0,0

1.0.1.0/24,1814991,1814991,,0,0

1.0.2.0/23,1814991,1814991,,0,0

1.0.4.0/22,2077456,2077456,,0,0

1.0.8.0/21,1814991,1814991,,0,0

...

223.255.244.0/22,1269750,1269750,,0,0

223.255.248.0/22,1819730,1819730,,0,0

223.255.252.0/23,1814991,1814991,,0,0

223.255.254.0/24,1880251,1880251,,0,0

223.255.255.0/24,2077456,2077456,,0,0

其中第一列 network 为网段/子网掩码,geoname_id 等列关联了另一个 csv 中的国家信息元数据。

可以以网段为键名(可IP2Long 转INT),子网掩码+对应的国家二字码为键值 存入 redis, 以内存换取更快的IO操作,相信查询效率会有更大提升。

国为当前项目是在计划任务中执行,有消息队列缓冲,可多台计划任务服务器并行处理。官方 composer 库效率也足够高,暂时不折腾了,以后有机会了再尝试 REDIS 方案

本文原始网址:https://www.liu12.com/article/ip2country,转载请保留出处

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容