廈門公司網(wǎng)站建設一條龍全包(ip歸屬地api)ip歸屬地本地局域網(wǎng),
細心的朋友們可能已經(jīng)發(fā)現(xiàn)了,先在抖音、知乎、快手、小紅書等這些平臺已經(jīng)上線了“網(wǎng)絡用戶顯示 IP 的功能”,境外用戶顯示的是國家,國內的用戶顯示的省份,而且此項顯示無法關閉,歸屬地強制顯示作為網(wǎng)友,我們可能只是看看戲,但是作為一個努力學習的碼農,我們肯定要來看一下這個功能是怎么實現(xiàn)的,今天這篇文章,就用幾分鐘的時間來講述一下這個功能是怎么實現(xiàn)的。
1獲取用戶 IP 地址HttpServletRequest 獲取 IP首先我們來看一下,在 Java 中,是如何獲取到 IP 屬地的,主要有以下兩步:通過 HttpServletRequest 對象,獲取用戶的 「IP」 地址
通過 IP 地址,獲取對應的省份、城市]首先,我們這里寫一個工具類用于獲取 IP 地址,因為用戶的每次 Request 請求都會攜帶請求的 IP 地址放到請求頭中,所以我們可以通過截取請求中的 IP 來獲取 IP 地址;
/** * 網(wǎng)絡工具類 * * @author 程序員魚皮 * @from 編程導航知識星球 */
publicclassNetUtils{ /** * 獲取客戶端 IP 地址 * * @param request * @return */public
static String getIpAddress(HttpServletRequest request){ String ip = request.getHeader("x-forwarded-for"
); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader(
"Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader(
"WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr();
if (ip.equals("127.0.0.1")) { // 根據(jù)網(wǎng)卡取本機配置的 IP InetAddress inet = null
; try { inet = InetAddress.getLocalHost(); } catch
(Exception e) { e.printStackTrace(); } if (inet !=
null) { ip = inet.getHostAddress(); } } }
// 多個代理的情況,第一個IP為客戶端真實IP,多個IP按照,分割if (ip != null && ip.length() > 15) { if (ip.indexOf(","
) > 0) { ip = ip.substring(0, ip.indexOf(",")); } } // 本機訪問
if ("localhost".equalsIgnoreCase(ip) || "127.0.0.1".equalsIgnoreCase(ip) || "0:0:0:0:0:0:0:1".equalsIgnoreCase(ip)){
// 根據(jù)網(wǎng)卡取本機配置的IP InetAddress inet; try { inet = InetAddress.getLocalHost(); ip = inet.getHostAddress(); }
catch (UnknownHostException e) { e.printStackTrace(); } }
// 如果查找不到 IP,可以返回 127.0.0.1,可以做一定的處理,但是這里不考慮// if (ip == null) {// return "127.0.0.1";// }return ip; }
/** * 獲取mac地址 */publicstatic String getMacAddress()throws Exception { // 取mac地址byte
[] macAddressBytes = NetworkInterface.getByInetAddress(InetAddress.getLocalHost()).getHardwareAddress();
// 下面代碼是把mac地址拼裝成String StringBuilder sb = new StringBuilder(); for (int i = 0; i < macAddressBytes.length; i++) {
if (i != 0) { sb.append("-"); } // mac[i] & 0xFF 是為了把byte轉化為正整數(shù)
String s = Integer.toHexString(macAddressBytes[i] & 0xFF); sb.append(s.length() ==
1 ? 0 + s : s); } return sb.toString().trim().toUpperCase(); } } 2獲取用戶的 IP 地址屬地淘寶庫獲取用戶 IP 地址屬地
通過這個方法,就可以重請求頭中獲取到用戶的 IP 地址了,然后接下來就是 IP 地址歸屬地省份、城市的獲取了,這里可以用很多 IP 地址查詢的庫進行查詢,這里用一個庫來測試一下淘寶 IP 地址庫:ip.taobao.com/。
不過淘寶的 IP 地址查詢庫已經(jīng)在 2022 年 3 月 31 日下線了,這里我們就不能使用它了,只能另辟蹊徑了。
這里我們截取一段之前淘寶貨期 IP 地址的源碼,然后一起來看一下這里可以看到,在日志文件中,出現(xiàn)了大量的 the request over max qps for user 問題雖然這個方法已經(jīng)寄了,但是我們求知的道路可以停嗎?肯定不可以啊,這里我們就來整一個新的獲取 IP 地址屬地的方法,也就是我們今天文章的主角:Ip2region。
Ip2region 介紹這個是在之前的一篇文章看到的,他是一個 Gthub 的開源項目,即 Ip2region 開源項目地址如下:https://github.com/lionsoul2014/ip2region
這個開源庫目前已經(jīng)更新到了 V2 的版本,現(xiàn)在的它是一個強大的離線IP地址定位庫和IP定位數(shù)據(jù)管理框架,其達到了微秒級別的查詢效率,還提供了眾多主流編程語言的 xdb 數(shù)據(jù)生成和查詢客戶端實現(xiàn),可以說是非常得好用,今天這篇文章我們主要針對其 V2 版本進行講解,如果想要查詢 1.0 版本的內容的話,可以去 Github 上面進行查看。
3Ip2region 詳解高達 99.9 % 的查詢準確率數(shù)據(jù)聚合了一些知名 ip 到地名查詢提供商的數(shù)據(jù),這些是他們官方的的準確率,經(jīng)測試著實比經(jīng)典的純真 IP 定位準確一些ip2region 的數(shù)據(jù)聚合自以下服務商的開放 API 或者數(shù)據(jù)(升級程序每秒請求次數(shù) 2 到 4 次),比例如下:。
80%, 淘寶 IP 地址庫, ip.taobao.com/%5C≈10%, GeoIP, geoip.com/%5C≈2%, 純真 IP 庫, www.cz88.net/%5CIp2region V2.0 特性
1、IP 數(shù)據(jù)管理框架xdb 支持億級別的 IP 數(shù)據(jù)段行數(shù),默認的 region 信息都固定了格式:國家|區(qū)域|省份|城市|ISP,缺省的地域信息默認是0region 信息支持完全自定義,例如:你可以在 region 中追加特定業(yè)務需求的數(shù)據(jù),例如:GPS信息/國際統(tǒng)一地域信息編碼/郵編等。
也就是你完全可以使用 ip2region 來管理你自己的 IP 定位數(shù)據(jù)2、數(shù)據(jù)去重和壓縮xdb 格式生成程序會自動去重和壓縮部分數(shù)據(jù),默認的全部 IP 數(shù)據(jù),生成的 ip2region.xdb 數(shù)據(jù)庫是 11MiB,隨著數(shù)據(jù)的詳細度增加數(shù)據(jù)庫的大小也慢慢增大。
3、極速查詢響應即使是完全基于 xdb 文件的查詢,單次查詢響應時間在十微秒級別,可通過如下兩種方式開啟內存加速查詢:vIndex 索引緩存:使用固定的 512KiB 的內存空間緩存 vector index 數(shù)據(jù),減少一次 IO 磁盤操作,保持平均查詢效率穩(wěn)定在10-20微秒之間。
xdb 整個文件緩存:將整個 xdb 文件全部加載到內存,內存占用等同于 xdb 文件大小,無磁盤 IO 操作,保持微秒級別的查詢效率多語言以及查詢客戶端的支持已經(jīng)客戶端有:Java、C#、php、C、Python、Node.js、PHP 拓展(PHP 5 和 PHP 7)等,主要如下:。
Ip2region xdb Java 查詢客戶端實現(xiàn)這里簡單展示一下 Java 的實現(xiàn),這里使用開發(fā)中常用的 Maven 實現(xiàn)的方式:1. 引入 Maven 倉庫由于項目使用Spring 的方式構建,這里可以選擇使用引入 Spring 的 starter 的方式進行
com.github.hiwepyip2region-spring-boot-starter
>2.0.1.RELEASEorg.lionsoul
ip2region2.7.0在引入 Maven 依賴之后,我們這里引入幾種實現(xiàn)的方式:2. 實現(xiàn)方式 1:【基于文件查詢】
import org.lionsoul.ip2region.xdb.Searcher; import java.io.*; import java.util.concurrent.TimeUnit;
publicclassSearcherTest {publicstaticvoidmain(String[] args){ // 1、創(chuàng)建 searcher 對象 String dbPath =
"ip2region.xdb file path"; Searcher searcher = null; try { searcher = Searcher.newWithFileOnly(dbPath); }
catch (IOException e) { System.out.printf("failed to create searcher with `%s`: %s ", dbPath, e);
return; } // 2、查詢try { String ip = "1.2.3.4"; long sTime = System.nanoTime(); String region = searcher.search(ip);
long cost = TimeUnit.NANOSECONDS.toMicros((long) (System.nanoTime() - sTime)); System.out.
printf("{region: %s, ioCount: %d, took: %d μs} ", region, searcher.getIOCount(), cost); } catch
(Exception e) { System.out.printf("failed to search(%s): %s ", ip, e); }
// 3、備注:并發(fā)使用,每個線程需要創(chuàng)建一個獨立的 searcher 對象單獨使用 } } 3. 實現(xiàn)方式 2:【緩存VectorIndex索引】我們可以提前從 xdb 文件中加載出來 VectorIndex 數(shù)據(jù),然后全局緩存,每次創(chuàng)建 Searcher 對象的時候使用全局的 VectorIndex 緩存可以減少一次固定的 IO 操作,從而加速查詢,減少 IO 壓力。
import org.lionsoul.ip2region.xdb.Searcher; import java.io.*; import java.util.concurrent.TimeUnit;
publicclassSearcherTest {publicstaticvoidmain(String[] args){ String dbPath = "ip2region.xdb file path"
; // 1、從 dbPath 中預先加載 VectorIndex 緩存,并且把這個得到的數(shù)據(jù)作為全局變量,后續(xù)反復使用 byte[] vIndex; 。
try { vIndex = Searcher.loadVectorIndexFromFile(dbPath); } catch (Exception e) { System.out.
printf("failed to load vector index from `%s`: %s ", dbPath, e); return; }
// 2、使用全局的 vIndex 創(chuàng)建帶 VectorIndex 緩存的查詢對象 Searcher searcher; try { searcher = Searcher.newWithVectorIndex(dbPath, vIndex); } 。
catch (Exception e) { System.out.printf("failed to create vectorIndex cached searcher with `%s`: %s "
, dbPath, e); return; } // 3、查詢try { String ip = "1.2.3.4";
long sTime = System.nanoTime(); String region = searcher.search(ip); long cost = TimeUnit.NANOSECONDS.toMicros((
long) (System.nanoTime() - sTime)); System.out.printf("{region: %s, ioCount: %d, took: %d μs} "
, region, searcher.getIOCount(), cost); } catch (Exception e) { System.out.printf
("failed to search(%s): %s ", ip, e); } // 備注:每個線程需要單獨創(chuàng)建一個獨立的 Searcher 對象,但是都共享全局的制度 vIndex 緩存。
} } 4. 實現(xiàn)方式 3:「緩存整個 xdb 數(shù)據(jù)」我們也可以預先加載整個 ip2region.xdb 的數(shù)據(jù)到內存,然后基于這個數(shù)據(jù)創(chuàng)建查詢對象來實現(xiàn)完全基于文件的查詢,類似之前的 memory search。
import org.lionsoul.ip2region.xdb.Searcher; import java.io.*; import java.util.concurrent.TimeUnit;
publicclassSearcherTest {publicstaticvoidmain(String[] args){ String dbPath = "ip2region.xdb file path"
; // 1、從 dbPath 加載整個 xdb 到內存 byte[] cBuff; try { cBuff = Searcher.loadContentFromFile(dbPath); } 。
catch (Exception e) { System.out.printf("failed to load content from `%s`: %s ", dbPath, e);
return; } // 2、使用上述的 cBuff 創(chuàng)建一個完全基于內存的查詢對象 Searcher searcher; try { searcher = Searcher.newWithBuffer(cBuff); } 。
catch (Exception e) { System.out.printf("failed to create content cached searcher: %s ", e);
最新文章
- 沈陽企業(yè)網(wǎng)站建設需要多少錢(進行戶外活動怎么說)大自然戶外活動主題,
- 武漢企業(yè)網(wǎng)站建設需要多少錢費用(戶外爬山叫什么)戶外爬山需要注意什么,
- 廣州企業(yè)網(wǎng)站建設全包(興仁市馬馬崖)興仁市馬乃屯,
- 西安企業(yè)網(wǎng)站建設制作公司哪家好(園藝跨專業(yè)考研方向有哪些?)園藝跨專業(yè)考研方向是什么,
- 上海企業(yè)網(wǎng)站建設公司(泳池專用防水材料)泳池做防水用什么材料好,
- 沈陽企業(yè)網(wǎng)站建設需要多少錢(三棵樹涂料排名)三棵樹涂料全球排名,
- 佛山企業(yè)網(wǎng)站建設制作(中國涂料展會2023年時間表)中國涂料展會2023年時間表及地點,
- 濟南做企業(yè)網(wǎng)站建設的公司(塘沽閥門好牌子推薦)天津最放心的塘沽閥門公司電話,
- 沈陽企業(yè)網(wǎng)站建設公司(j61w截止閥型號含義)j61y-p55170v截止閥型號含義,
- 成都做企業(yè)網(wǎng)站建設的公司(施工樓梯防護欄桿廠家排名前十)施工樓梯防護欄桿廠家排名榜,
- 南京企業(yè)網(wǎng)站建設價格(三棵樹涂料生產廠家)三棵樹涂料總公司在什么地方,
- 鄭州企業(yè)網(wǎng)站建設制作(開平水暖品牌有哪些)開平水暖品牌排行榜,
- 上海企業(yè)網(wǎng)站建設公司(胰島素泵的操作)胰島素泵的操作流程表,
- 天津企業(yè)網(wǎng)站建設費用(老電梯安全嗎)老電梯照片,
- 長沙企業(yè)網(wǎng)站建設全包(中國國際涂料展覽會)中國國際涂料展2019,
- 成都企業(yè)網(wǎng)站建設報價(陶瓷餐具和廚具行業(yè)容量及產業(yè)鏈分析)陶瓷餐具和廚具行業(yè)容量及產業(yè)鏈分析圖,
- 沈陽企業(yè)網(wǎng)站建設制作(熱工儀表高級工技能考試題目)供熱行業(yè)考什么證書,
- 鄭州做企業(yè)網(wǎng)站建設的公司(二手儀器交易平臺排名)二手儀器交易平臺排行榜,
- 鄭州企業(yè)網(wǎng)站建設需要多少錢(溧水水泵經(jīng)銷)南京抽水泵租賃,
- 哈爾濱企業(yè)網(wǎng)站建設公司哪家便宜(成都園藝博覽運營發(fā)展有限公司招聘)成都園藝博覽運營發(fā)展有限公司官網(wǎng),
- 沈陽企業(yè)網(wǎng)站建設哪家好(園藝專題)園藝資訊,
- 深圳企業(yè)網(wǎng)站建設制作(窗簾掛不上)想掛窗簾 但是不能打孔怎么辦,
- 南京做企業(yè)網(wǎng)站建設的公司(北新涂料重組進程)北新涂料產能,
- 哈爾濱做企業(yè)網(wǎng)站建設的公司(重慶一人墜樓砸死兩人)重慶最近商場墜樓事件,
- 西安企業(yè)網(wǎng)站建設報價(九牧衛(wèi)浴領軍品牌)九牧專注高端衛(wèi)浴三十年,
- 江蘇公司網(wǎng)站建設一條龍全包(usnews生物學排名)usnews生物科學排名,
- 湖北網(wǎng)站建設多少錢僅需500元(小米14價格多少錢一臺)小米14上市時間及價格,
- 河北網(wǎng)站建設需要多少錢(抖音電商開啟首屆年貨節(jié))抖音年貨節(jié)背景圖,
- 海口網(wǎng)站建設多少錢僅需500元(抖音市場規(guī)模2023)抖音市場規(guī)模分析,
- 青島網(wǎng)站建設多少錢僅需500元(搭建商城平臺)怎么搭建自己的商城,
- 太原網(wǎng)站建設多少錢僅需500元(抖音電商年貨節(jié))抖音新潮好物節(jié),
- 臺州網(wǎng)站建設需要多少錢(蔚萊汽車科技有限公司)蔚萊汽車怎么樣,
- 河南網(wǎng)站建設多少錢僅需500元(平安壹錢包可靠嗎)平安壹錢包正規(guī)嗎,
- 河南公司網(wǎng)站建設一條龍全包(游戲編程之從零開始pdf)從0開始學編程,
- 無錫網(wǎng)站建設多少錢僅需500元(全國大學生程序設計競賽2023年報名時間)全國大學生程序設計競賽含金量高嗎,
- 浙江企業(yè)網(wǎng)站建設500元全包(編程新手教學)初學編程的常見困難,
- 蘇州公司網(wǎng)站建設一條龍全包(noc編程貓創(chuàng)新編程全國決賽)編程貓創(chuàng)新編程是什么,
- 貴陽企業(yè)網(wǎng)站建設500元全包(nas建站違法嗎)nas的搭建,
- 河北公司網(wǎng)站建設一條龍全包(u盤file)u盤傳文件顯示被占用,
- 寧夏網(wǎng)站建設需要多少錢(數(shù)據(jù)傳輸安全解決方案)數(shù)據(jù)傳輸安全包括數(shù)據(jù)加密,