当前位置:网站首页>IP属地如何高效率识别
IP属地如何高效率识别
2022-08-03 17:01:00 【欧菲斯集团】
概述
IP属地显示各大平台已经有更新,抖音、今日头条、知乎、小红书等,作为一个技术,如果实现获取IP属地呢,正好近期需要做一个IP属地跳转,识别IP的归属地如果单纯的靠调用接口获取属地信息在效率上难以保证,因此给大家分享一个强大的离线IP地址定位库ip2region获取IP归属地。

获取IP属地那么重要的步骤就是获取IP地址,怎么获取ip地址呢?
获取用户ip地址
HttpServletRequest 获取 IP
/**
* 获取ip地址
*/
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.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
// 本机访问
if ("localhost".equalsIgnoreCase(ip) || "127.0.0.1".equalsIgnoreCase(ip) || "0:0:0:0:0:0:0:1".equalsIgnoreCase(ip)){
// 根据网卡取本机配置的IP
InetAddress inet;
try {
inet = InetAddress.getLocalHost();
ip = inet.getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (null != ip && ip.length() > 15) {
if (ip.indexOf(",") > 15) {
ip = ip.substring(0, ip.indexOf(","));
}
}
return ip;
}
通过此方法,从请求 Header 中获取到用户的 IP 地址。
获取IP归属地的方法
1、在线方式
我们可以 通过一些网络接口获取IP的归属地,例如ip.taobao.com淘宝ip地址库来获取,

但是今天我进入淘宝ip地址库看到2022年3月31日起永久关停,如果我们使用在线的ip地址查询接口的时候也是需要防止对方接口停用到带来的损失,因此我们还有其它的方式获取ip地址属地吗?,答案是有的。

2、离线获取IP地址属地库---Ip2region
1、Ip2region 是什么
ip2region v2.0 - 是一个离线IP地址定位库和IP定位数据管理框架,10微秒级别的查询效率,提供了众多主流编程语言的 xdb 数据生成和查询客户端实现。v1.0 旧版本: v1.0版本入口
github 地址:https://github.com/lionsoul2014/ip2region
2、Ip2region 特性
标准化的数据格式、数据去重和压缩、极速查询响应、IP 数据管理框架,使用固定的 512KiB 的内存空间缓存 vector index 数据,减少一次 IO 磁盘操作,保持平均查询效率稳定在10-20微秒之间。并且准确率达到惊人的99.9% 准确率
3、最新版本
目前最新已更新到了 v2.0 版本,ip2region v2.0 是一个离线 IP 地址定位库和 IP 定位数据管理框架,10 微秒级别的查询效率,准提供了众多主流编程语言的 xdb 数据生成和查询客户端实现。
4、多查询客户端的支持

5、ip2region xdb java 查询客户端实现
1)maven 仓库引入
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>2.6.5</version>
</dependency>2)下载离线IP库
3)完全基于文件的查询
import org.lionsoul.ip2region.xdb.Searcher;
import java.io.*;
import java.util.concurrent.TimeUnit;
public class SearcherTest {
public static void main(String[] args) {
// 1、创建 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\n", dbPath, e);
return;
}
String ip = "1.2.3.4";
// 2、查询
try {
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}\n", region, searcher.getIOCount(), cost);
} catch (Exception e) {
System.out.printf("failed to search(%s): %s\n", ip, e);
}
// 3、关闭资源
searcher.close();
// 备注:并发使用,每个线程需要创建一个独立的 searcher 对象单独使用。
}
}
}
4)缓存 VectorIndex 索引
全局缓存,每次创建 Searcher 对象的时候使用全局的 VectorIndex 缓存可以减少一次固定的 IO 操作,从而加速查询,减少 IO 压力。
import org.lionsoul.ip2region.xdb.Searcher;
import java.io.*;
import java.util.concurrent.TimeUnit;
public class SearcherTest {
public static void main(String[] args) {
String dbPath = "ip2region.xdb file path";
// 1、从 dbPath 中预先加载 VectorIndex 缓存,并且把这个得到的数据作为全局变量,后续反复使用。
byte[] vIndex;
try {
vIndex = Searcher.loadVectorIndexFromFile(dbPath);
} catch (Exception e) {
System.out.printf("failed to load vector index from `%s`: %s\n", dbPath, e);
return;
}
// 2、使用全局的 vIndex 创建带 VectorIndex 缓存的查询对象。
Searcher searcher;
try {
searcher = Searcher.newWithVectorIndex(dbPath, vIndex);
} catch (Exception e) {
System.out.printf("failed to create vectorIndex cached searcher with `%s`: %s\n", dbPath, e);
return;
}
String ip = "1.2.3.4";
// 3、查询
try {
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}\n", region, searcher.getIOCount(), cost);
} catch (Exception e) {
System.out.printf("failed to search(%s): %s\n", ip, e);
}
// 4、关闭资源
searcher.close();
// 备注:每个线程需要单独创建一个独立的 Searcher 对象,但是都共享全局的制度 vIndex 缓存。
}
}
5)缓存整个 xdb 数据
预先加载整个 ip2region.xdb 的数据到内存,然后基于这个数据创建查询对象来实现完全基于文件的查询
import org.lionsoul.ip2region.xdb.Searcher;
import java.io.*;
import java.util.concurrent.TimeUnit;
public class SearcherTest {
public static void main(String[] args) {
String dbPath = "C:\\Users\\Mr.Hong\\Desktop\\ip2region\\_doc\\ip2region.xdb";
// 1、从 dbPath 加载整个 xdb 到内存。
byte[] cBuff;
try {
cBuff = Searcher.loadContentFromFile(dbPath);
} catch (Exception e) {
System.out.printf("failed to load content from `%s`: %s\n", dbPath, e);
return;
}
// 2、使用上述的 cBuff 创建一个完全基于内存的查询对象。
Searcher searcher;
try {
searcher = Searcher.newWithBuffer(cBuff);
} catch (Exception e) {
System.out.printf("failed to create content cached searcher: %s\n", e);
return;
}
String ip = "1.2.3.4";
// 3、查询
try {
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}\n", region, searcher.getIOCount(), cost);
} catch (Exception e) {
System.out.printf("failed to search(%s): %s\n", ip, e);
}
// 4、关闭资源 - 该 searcher 对象可以安全用于并发,等整个服务关闭的时候再关闭 searcher
// searcher.close();
// 备注:并发使用,用整个 xdb 数据缓存创建的查询对象可以安全的用于并发,也就是你可以把这个 searcher 对象做成全局对象去跨线程访问。
}
}
结束语
使用ip2region xdb的方式查询ip地址属地效率是非常高的,可以看到我的几种不同测试中,最快的速度达到了惊人的47纳秒,可以说基本上是及时响应。所以有了这么好用的工具,并且准确率达到99%,所以以后使用IP属地查询,如果频率非常高,那么建议使用。
边栏推荐
- 工程仪器设备在线监测管理系统常见问题和注意事项
- 【指针初解】
- uniapp 切换 history 路由模
- SwinIR实战:详细记录SwinIR的训练过程
- 【系统学习编程-编程入门-全民编程 视频教程】
- LeetCode·1163.按字典序排在最后的子串·最小表示法
- 论文解读(JKnet)《Representation Learning on Graphs with Jumping Knowledge Networks》
- 【目标检测】Focal Loss for Dense Object Detection
- 11. Container With Most Water
- ORACLE CLOUD 在国内有数据中心吗?
猜你喜欢

C专家编程 第1章 C:穿越时空的迷雾 1.9 阅读ANSI C标准,寻找乐趣和裨益

B站回应HR称核心用户是Loser;微博回应宕机原因;Go 1.19 正式发布|极客头条

使用Stream多年,collect还有这些“骚操作”?

面试不再被吊打!这才是Redis分布式锁的七种方案的正确打开方式
![[Unity Starter Plan] Making RubyAdventure01 - Player Creation & Movement](/img/e9/9bba4f7ecee81ae7ce7e492b54ee11.png)
[Unity Starter Plan] Making RubyAdventure01 - Player Creation & Movement
![[Unity Getting Started Plan] Basic Concepts (7) - Input Manager & Input Class](/img/a7/950ddc6c9eeaa56fe0c3165d22a7d2.png)
[Unity Getting Started Plan] Basic Concepts (7) - Input Manager & Input Class

论文解读(JKnet)《Representation Learning on Graphs with Jumping Knowledge Networks》

Description of the functional scenario of "collective storage and general governance" in the data center

TiKV & TiFlash 加速复杂业务查询丨TiFlash 应用实践

#夏日挑战赛#【FFH】OpenHarmony设备开发基础(四)启动流程
随机推荐
error:Illegal instruction (core dumped),离线下载安装这个other版本numpy
Description of the functional scenario of "collective storage and general governance" in the data center
九种方法!教你如何读取resources目录下的文件路径
一个域名对应多个IP地址
vant自动上传图片/文件
How ArkUI adapter somehow the screen
数据万象内容审核 — 共建安全互联网,专项开展“清朗”直播整治行动
EMQX Newsletter 2022-07|EMQX 5.0 正式发布、EMQX Cloud 新增 2 个数据库集成
Web3 安全风险令人生畏?应该如何应对?
国内首发可视化智能调优平台,小龙带你玩转KeenTune UI
“LaMDA 存在种族歧视,谷歌的 AI 伦理不过是‘遮羞布’!”
C语言04、操作符
fastposter v2.9.0 程序员必备海报生成器
【AppCube】零代码小课堂开课啦
并发高的情况下,试试用ThreadLocalRandom来生成随机数
工程仪器设备在线监测管理系统常见问题和注意事项
EasyExcel实现动态列解析和存表
yolov5s用自己的数据集进行训练模型
出海,是泡泡玛特的“解药”吗?
兄弟组件通信context