在做互联网技术开发中经常会需要用到IP地址对应地址位置的功能。
大部分情况会选择使用大厂API实现,大厂API无论在性能,速度上都非常好,但唯一缺点就是调用收费,大厂一般会提供1000次左右免费查询,但后期需要按量收费,一个中度流量应用一年下来费用在千元左右。
几个接口商的API测试,如ATB等,调用速度还是非常稳定,缺点就是在调用量大时费用也随着直线上升。
为了研究技术精神(省钱),所以决定自己开发实现,首先在网上找到全球IP地址数据库,导入MYSQL后大概有70万的数据量,备份文件在文章尾部提供下载。
先贴上在应用中的最终效果图:
实现方法:
根据用户的IP地址显示地理信息。
先建好IP地址库的数据表,表的结构如下:
CREATE TABLE IF NOT EXISTS `ui_ip` ( `id` int(11) NOT NULL, `s_ip` varchar(255) DEFAULT NULL, `e_ip` varchar(255) DEFAULT NULL, `u_s_ip` bigint(11) DEFAULT NULL, `u_e_ip` bigint(11) DEFAULT NULL, `a1` varchar(255) DEFAULT NULL, `a2` varchar(255) DEFAULT NULL, `a3` varchar(255) DEFAULT NULL, `a4` varchar(255) DEFAULT NULL, `a5` varchar(255) DEFAULT NULL, `a6` varchar(255) DEFAULT NULL, `a7` varchar(255) DEFAULT NULL, `a8` varchar(255) DEFAULT NULL, `state` varchar(255) DEFAULT NULL, `lon` decimal(20,6) DEFAULT NULL, `lat` decimal(20,6) DEFAULT NULL, `status` int(1) DEFAULT NULL, `crid` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; -- -- Indexes for table `ui_ip` -- ALTER TABLE `ui_ip` ADD PRIMARY KEY (`id`) USING BTREE, ADD KEY `state` (`state`) USING BTREE, ADD KEY `u_s_ip` (`u_s_ip`), ADD KEY `u_e_ip` (`u_e_ip`); -- -- AUTO_INCREMENT for table `ui_ip` -- ALTER TABLE `ui_ip` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
PHP实现IP地址查询MYSQL对应的地理位置代码:
function wztm_mysql_get($sqlstr) { $rsql = mysql_query($sqlstr); $infolist = array(); $i=0; if($rsql) { while($row = mysql_fetch_assoc($rsql)) { $infolist[$i]=$row; $i++; } } return $infolist; } function ecs_geoip($ip) { $ip_temp=explode(".",$ip); $ip_num=$ip_temp[0]*256*256*256+$ip_temp[1]*256*256+$ip_temp[2]*256+$ip_temp[2]; $get_ip=wztm_mysql_get("select a1,a2,a3,a4,a5,a6 from ui_ip where u_s_ip if(count($get_ip)>0) $addinfo=$get_ip[0]['a1'].$get_ip[0]['a2'].$get_ip[0]['a3'].$get_ip[0]['a4']."(".$get_ip[0]['a6'].")"; else $addinfo="未知"; return $addinfo; } echo ecs_geoip("116.253.0.77");
php接Mysql数据库代码就省略了。
功能写好后,在批量调用时,出现了慢的问题,在百万级数据库查询一条记录4H4G的服务器配置大约0.8秒,但一个页面如果需要列20条记录,这样加载一次页面就需要约15秒左右,这样开发的产品是不能拿出来用的,所以还是得继续优化程序。
解决思路:
一、用户访问时就通过接口把IP地址转换成物理地址
这个方法马上给PASS掉,因为,每个流量访问都得去查询百万级数据库,反而更占硬件资源了。
二、在后台管理人员浏览数据时再进行转换
这个是在第一方法上优化出来的,读取数据时,先比对这个IP是否在流量统计表中已存在,已有就直接拉取流量统计表的数据更新本条内容,否则就去Ip地址库查询数据。
当然第二点也是有缺点,如果没有通过地址转换的记录就无法统计地址位置的信息。
三、通过定时转换功能指令达到转换
开发一个定时器,通过日志分析在基本无用户访问的时候,进行转换。
通过以上三个方法,基本已能实现IP地址转换成地址位置的功能,其中第一点是不推荐的,第二点和第三点可根据实际情况做选择。如果大家有更好开发实现方案,可以在评论区留言。
实现功能后的展示地址:
前端的统计页,添加在开发完成的英文站中 https://cs.wzjm.cn
后端登录网址:https://cs.wzjm.cn/as_admin/logo.php
用户名:tj 密码:123456
以上信息复制在电脑端即可查看
最后,附上IP地址Mysql数据库下载地址,因为有几百M,我就放到自己的百度网盘了,需要的可以关注本公众号后回复 "ip地址"即可获得。