经常刷短视频或逛社区的朋友,可能已经注意到一个现象:很多平台会在作者和评论区用户旁边显示 IP 归属地。这个功能到底是怎么实现的?其实背后依赖的就是 IP 归属地定位服务。


收费平台的 API
我们可以调用一些付费平台的 API 来实现,比如主流地图服务的开放接口。但这些服务通常是收费的,免费额度也比较有限,测试还可以,真正上线之后配额往往不够用。

离线库推荐
既然付费 API 有配额限制,那有没有免费又靠谱的离线方案?这里推荐一个准确率高达 99.9% 的离线 IP 地址定位库 ip2region,查询速度在 0.0x 毫秒级别,数据库体积只有 10 MB 左右。
开源地址:https://github.com/lionsoul2014/ip2region
这个项目提供了 Java、PHP、C、Python、Node.js、Golang、C# 等多种语言的查询绑定,同时支持 Binary、B 树和内存三种查询算法。

在 GitHub 上直接搜索 ip2region,也可以找到这个开源库。
使用方法
下面用 Java 代码演示一下如何接入这个 IP 库,该库目前支持多种主流语言。
1. 引入依赖
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>3.3.7</version>
</dependency>
从 3.2.0 版本开始,项目提供了一个双协议兼容且并发安全的 Ip2Region 查询服务,建议优先使用这种方式进行查询调用。
详细的 Java 使用教程可以参考:https://github.com/lionsoul2014/ip2region/blob/master/binding/java/README_zh.md
2. 下载离线库文件 ip2region.xdb

3. 简单使用代码
下面用 Java 代码挑选某个国内的 IP 进行查询,看看会输出什么样的结果。
public class IpTest {
public static void main(String[] args) throws Exception {
// 1、创建 searcher 对象 (修改为离线库路径)
String dbPath = "C:\\Users\\Administrator\\Desktop\\ip2region.xdb";
Searcher searcher = null;
try {
searcher = Searcher.newWithFileOnly(dbPath);
} catch (Exception e) {
System.out.printf("failed to create searcher with %s: %s\n", dbPath, e);
return;
}
// 2、查询
String ip = "110.242.68.66";
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 对象单独使用。
}
}
输出结果为:
{region: 中国|0|河北省|保定市|联通, ioCount: 3, took: 1192 μs}
其中 region 的格式为 国家|区域|省份|城市|ISP,缺省的地域信息默认显示为 0。
这个库不仅支持国内 IP,对国外 IP 同样可以查询。

国外 IP 查询结果。
其他语言的接入方式可以参考该开源库的说明文档。
总结
如果项目中有 IP 定位需求,这个离线库的准确率和性能都相当不错,值得一试。
开源地址:https://github.com/lionsoul2014/ip2region
如果你对这类开源工具感兴趣,也可以在云栈社区和更多开发者交流实践经验。