










在做互聯(lián)網(wǎng)技術(shù)開發(fā)中經(jīng)常會需要用到IP地址對應(yīng)地址位置的功能。
大部分情況會選擇使用大廠API實現(xiàn),大廠API無論在性能,速度上都非常好,但唯一缺點就是調(diào)用收費,大廠一般會提供1000次左右免費查詢,但后期需要按量收費,一個中度流量應(yīng)用一年下來費用在千元左右。
幾個接口商的API測試,如ATB等,調(diào)用速度還是非常穩(wěn)定,缺點就是在調(diào)用量大時費用也隨著直線上升。
為了研究技術(shù)精神(省錢),所以決定自己開發(fā)實現(xiàn),首先在網(wǎng)上找到全球IP地址數(shù)據(jù)庫,導(dǎo)入MYSQL后大概有70萬的數(shù)據(jù)量,備份文件在文章尾部提供下載。
先貼上在應(yīng)用中的最終效果圖:
實現(xiàn)方法:
根據(jù)用戶的IP地址顯示地理信息。
先建好IP地址庫的數(shù)據(jù)表,表的結(jié)構(gòu)如下:
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實現(xiàn)IP地址查詢MYSQL對應(yīng)的地理位置代碼:
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數(shù)據(jù)庫代碼就省略了。
功能寫好后,在批量調(diào)用時,出現(xiàn)了慢的問題,在百萬級數(shù)據(jù)庫查詢一條記錄4H4G的服務(wù)器配置大約0.8秒,但一個頁面如果需要列20條記錄,這樣加載一次頁面就需要約15秒左右,這樣開發(fā)的產(chǎn)品是不能拿出來用的,所以還是得繼續(xù)優(yōu)化程序。
解決思路:
一、用戶訪問時就通過接口把IP地址轉(zhuǎn)換成物理地址
這個方法馬上給PASS掉,因為,每個流量訪問都得去查詢百萬級數(shù)據(jù)庫,反而更占硬件資源了。
二、在后臺管理人員瀏覽數(shù)據(jù)時再進(jìn)行轉(zhuǎn)換
這個是在第一方法上優(yōu)化出來的,讀取數(shù)據(jù)時,先比對這個IP是否在流量統(tǒng)計表中已存在,已有就直接拉取流量統(tǒng)計表的數(shù)據(jù)更新本條內(nèi)容,否則就去Ip地址庫查詢數(shù)據(jù)。
當(dāng)然第二點也是有缺點,如果沒有通過地址轉(zhuǎn)換的記錄就無法統(tǒng)計地址位置的信息。
三、通過定時轉(zhuǎn)換功能指令達(dá)到轉(zhuǎn)換
開發(fā)一個定時器,通過日志分析在基本無用戶訪問的時候,進(jìn)行轉(zhuǎn)換。
通過以上三個方法,基本已能實現(xiàn)IP地址轉(zhuǎn)換成地址位置的功能,其中第一點是不推薦的,第二點和第三點可根據(jù)實際情況做選擇。如果大家有更好開發(fā)實現(xiàn)方案,可以在評論區(qū)留言。
實現(xiàn)功能后的展示地址:
前端的統(tǒng)計頁,添加在開發(fā)完成的英文站中 https://cs.wzjm.cn
后端登錄網(wǎng)址:https://cs.wzjm.cn/as_admin/logo.php
用戶名:tj 密碼:123456
以上信息復(fù)制在電腦端即可查看
最后,附上IP地址Mysql數(shù)據(jù)庫下載地址,因為有幾百M,我就放到自己的百度網(wǎng)盤了,需要的可以關(guān)注本公眾號后回復(fù) "ip地址"即可獲得。