IP定位库的完美替代品:ip2region,开源、免费!

关注我的公众号:【编程朝花夕拾】,可获取首发内容。

01 引言

ip2region 是一个开源的离线 IP 地址定位库和 IP 数据管理框架,以其高效、精准的特性在互联网行业得到广泛应用。

本文档将详细介绍 ip2region 的核心特性、数据文件获取方式以及 Java 客户端的完整使用教程,帮助开发者在项目中快速集成 IP 定位功能。

02 简介

ip2region 是一个离线 IP 地址定位库,支持 IPv4IPv6 两种协议。该项目具有以下核心特点:

  • 高性能查询:10 微秒级别的查询效率,单机每秒可处理数十万次查询请求
  • 支持海量数据:支持亿级别的 IP 数据段,采用 xdb 格式存储,文件体积约 11MiB
  • 多语言支持:提供主流编程语言的客户端实现,包括 Java、Python、Go、PHP、Node.js、C# 等
  • 离线定位:无需调用第三方在线 API,纯本地化查询,保护数据隐私

ip2region 的数据格式采用标准化的区域信息格式:国家|区域|省份|城市|ISP。对于中国的 IP 数据,绝大部分可以精确到城市级别;海外数据则大多只能精确到国家。

社区地址:ip2region.net/

Gitee地址:gitee.com/lionsoul/ip...

GitHub地址:github.com/lionsoul201...

03 核心特性

3.1 标准化的数据格式

ip2region 对每个 IP 数据段的区域信息采用固定格式定义,便于程序解析和数据管理。标准格式如下:

复制代码
国家|区域|省份|城市|ISP

示例返回值:

复制代码
中国|0|广东省|深圳市|阿里云
美国|0|0|0|0

其中 0 表示该级别信息未知或不可用。这种标准化设计使得开发者可以方便地解析和应用 IP 定位结果。

3.2 数据去重与压缩

xdb 格式的数据生成程序会自动进行数据去重和压缩处理。默认情况下,包含全部 IP 数据的 ip2region.xdb 数据库文件约为 11MiB。随着数据详细程度的增加(如从城市级提升到区县级),数据库文件的体积也会相应增大,但总体仍然保持较小的文件尺寸。

3.3 极速查询响应

即使完全基于 xdb 文件进行查询,单次查询的响应时间也能达到十微秒级别。如果对查询性能有更高要求,ip2region 支持两种内存加速模式:

vIndex 索引缓存模式:使用固定的 512KiB 内存空间缓存 vector index 数据,可以减少一次磁盘 IO 操作,使平均查询效率稳定在 10-20 微秒之间。这是一种性价比极高的性能优化方案。

xdb 全文件缓存模式:将整个 xdb 文件一次性加载到内存中,内存占用等同于 xdb 文件大小。这种模式完全消除了磁盘 IO 操作,能够保持真正的微秒级查询效率。适合对性能要求极高且服务器内存充足的场景。

3.4 IP 数据管理框架

ip2region v2.0 的 xdb 格式支持亿级别的 IP 数据段行数,region 信息字段可以完全自定义。开发者可以在 region 中追加特定业务需求的数据,例如:

  • GPS 坐标信息
  • 国际统一地域信息编码
  • 邮政编码
  • 具体的业务分类标识

这种灵活的数据结构设计使得 ip2region 不仅是一个 IP 查询工具,更是一个完整的 IP 数据管理解决方案。

04 数据文件的获取

4.1 直接从项仓库下载

bash 复制代码
git clone https://github.com/lionsoul2014/ip2region.git

克隆完成后,在项目的 data 目录下可以找到 ip2region.xdb 文件。

4.2 从官网社区下载

访问 ip2region 官方社区(ip2region.net),登录后进入"数据服务"页面,可以下载不同版本的 xdb 文件:

版本类型 字段集合 适用场景
满载版 全部有效字段 通用版本,包含全部字段数据,文件体积最大
标准版 精确到区县的字段 需要精确到区县的定位场景,体积比满载版小数十 MiB
精简版 精确到城市的字段 只需要精确到城市的定位场景,体积最小

05 最佳实践

5.1 配置类

3.2.0 版本开始提供了一个双协议兼容且并发安全的 Ip2Region 查询服务,我们需要创建V4V6的配置。

java 复制代码
@BeforeAll
static void init() throws Exception {
    Config v4Config = Config.custom()
            .setCachePolicy(Config.NoCache)     // 指定缓存策略:  NoCache / VIndexCache / BufferCache
            .setSearchers(15)                       // 设置初始化的查询器数量
            // .setCacheSliceBytes(int)             // 设置缓存的分片字节数,默认为 50MiB
            .setXdbInputStream(Ip2regionTests.class.getResourceAsStream("/ip2region_v4.xdb"))      // 设置 v4 xdb 文件的 inputstream 对象
            // .setXdbFile(File)                    // 设置 v4 xdb File 对象
            // .setFairLock(boolean)                // 设置 ReentrantLock 是否使用公平锁
            // .setXdbPath("path")    // 设置 v4 xdb 文件的路径
            .asV4();

    final Config v6Config = Config.custom()
            .setCachePolicy(Config.NoCache)     // 指定缓存策略: NoCache / VIndexCache / BufferCache
            .setSearchers(15)                       // 设置初始化的查询器数量
            // .setCacheSliceBytes(int)             // 设置缓存的分片字节数,默认为 50MiB
            .setXdbInputStream(Ip2regionTests.class.getResourceAsStream("/ip2region_v6.xdb"))      // 设置 v6 xdb 文件的 inputstream 对象
            // .setXdbFile(File)                    // 设置 v6 xdb File 对象
            // .setFairLock(boolean)                // 设置 ReentrantLock 是否使用公平锁
            //.setXdbPath("path")    // 设置 v6 xdb 文件的路径
            .asV6();

    ip2Region = Ip2Region.create(v4Config, v6Config);// 指定为 v6 配置// 指定为 v4
}

缓存策略

  • NoCache:没有缓存,直接从文件中获取
  • VIndexCache:缓存 VectorIndex 索引
  • BufferCache:基于内存缓冲区

如果使用setXdbInputStream方式,只能使用BufferCache策略。还可以通过setFairLock(boolean)设置锁。

我们以BufferCache为例。

3.2 测试

v4IP说明:

  • 1.1.1.1:Cloudflare DNS
  • 114.114.114.114:国内 DNS
  • 127.0.0.1:本地回环

v6IP说明:

  • 2001:4860:4860::8888:Google DNS IPv6
  • 2606:4700:4700::1111:Cloudflare DNS IPv6
java 复制代码
@Test
void test01() throws Exception {
    String[] ips = {"1.1.1.1", "114.114.114.114", "127.0.0.1", "2001:4860:4860::8888", "2606:4700:4700::1111"};
    for (String ip : ips) {
        String search = ip2Region.search(ip);
        IpInfo ipInfo = Ip2RegionUtil.parse(ip, search);
        System.out.println(ipInfo);
        System.out.println("---------------------------------");
    }
}

执行结果

06 使用场景

6.1 CDN 加速节点选择

根据用户 IP 地址选择最近的 CDN 节点,提升资源访问速度。

java 复制代码
public String getCdnNode(String userIp) {
    IpQueryService.IpInfo info = ipQueryService.analyze(userIp);
    String province = info.getProvince();

    // 根据省份选择对应的 CDN 节点
    if ("广东省".equals(province)) {
        return "cdn-guangzhou.example.com";
    } else if ("浙江省".equals(province) || "江苏省".equals(province)) {
        return "cdn-shanghai.example.com";
    } else if ("北京市".equals(province)) {
        return "cdn-beijing.example.com";
    } else {
        return "cdn-default.example.com";
    }
}

6.2 地区访问控制

根据用户地区实施访问控制策略。

java 复制代码
public boolean isAccessAllowed(String userIp, String[] allowedRegions) {
    IpQueryService.IpInfo info = ipQueryService.analyze(userIp);
    String country = info.getCountry();

    // 检查是否在允许的地区列表中
    for (String region : allowedRegions) {
        if (country.contains(region) || info.getProvince().contains(region)) {
            return true;
        }
    }
    return false;
}

6.3 用户地区统计

分析用户地域分布,优化业务决策。

java 复制代码
public Map<String, Integer> getUserRegionStats(List<String> ipList) {
    Map<String, Integer> stats = new HashMap<>();

    for (String ip : ipList) {
        IpQueryService.IpInfo info = ipQueryService.analyze(ip);
        String province = info.getProvince();
        if (!"0".equals(province) && !province.isEmpty()) {
            stats.put(province, stats.getOrDefault(province, 0) + 1);
        }
    }

    return stats;
}

07 小结

ip2region 是一个高效、可靠、免费的离线 IP 地址定位解决方案。开发者可以在项目中快速集成 ip2region,实现高效、稳定 IP 定位功能。建议在生产环境中采用索引缓存模式,在性能和内存占用之间取得最佳平衡。

相关推荐
小明同学011 小时前
C++后端项目:统一大模型接入 SDK(五)
服务器·c++·后端·计算机网络·语言模型
XiYang-DING1 小时前
【Spring】Lombok
java·后端·spring
凤山老林1 小时前
AI辅助编程:Copilot在Java开发中的最佳实践
java·人工智能·copilot
ew452181 小时前
【Java】Apache POI 终极封装:支持多表格循环、图片插入、日期格式化的Word导出工具类(兼容POI3.17+)
java·word·apache
铁打的阿秀1 小时前
IDEA启动项目报错: 加载主类 com.seeburger.webedi.system.SystemApplication 时出现 LinkageError
java·ide·intellij-idea
ZC跨境爬虫1 小时前
模块化烹饪小程序开发日记 Day5:(后端Flask接口开发与AI智能解析菜谱的实现)
前端·人工智能·后端·python·ui·flask
Yeats_Liao1 小时前
物联网接入层技术剖析(一):从select到epoll
java·linux·后端·物联网·struts
上弦月-编程1 小时前
Java类与对象:编程核心解密
java·开发语言·jvm
小钻风33661 小时前
Spring Boot WebSocket 两种集成方式深度解析
spring boot·后端·websocket