ip2region 实战指南:10 微秒级离线 IP 定位,城市级 IP 归属地查询与 xdb 数据自管

ip2region 实战指南:10 微秒级离线 IP 定位,城市级 IP 归属地查询与 xdb 数据自管

【免费下载链接】ip2region Ip2region is an offline IP-to-Region localization library and IP data management framework with both IPv4 and IPv6 supports, 10-microsecond level query efficiency, xdb search client for many programming languages 【免费下载链接】ip2region 项目地址: https://gitcode.com/GitHub_Trending/ip/ip2region

ip2region 是一个离线 IP 定位库与 IP 数据管理框架,同时支持 IPv4/IPv6 双栈。单次 xdb 查询处于 10 微秒级别:既能回答"某 IP 属于哪",也能管理你自有的上亿段 IP 数据。

从第一个查询跑通:xdb 文件到城市级 IP 归属地结果

先认识 data/ 目录的四份文件:ipv4_source.txt、ipv6_source.txt 是覆盖全部 IPv4/IPv6 地址段的原始源数据;ip2region_v4.xdb、ip2region_v6.xdb 是由源数据生成的二进制文件,可直接被各语言客户端加载查询。内置数据的区域信息固定为五段格式:

国家|省份|城市|运营商|ISO 3166-1 两位国家代码

例如 1.2.3.4 返回 Australia|Queensland|Brisbane|0|AU,240e:3b7:... 返回 中国|广东省|深圳市|电信|CN。两条约定:中国区域全部用中文,非中国区域全部用英文;五段字段不固定——生成时可用 --field-list 按字段索引重组,把 GPS 坐标、邮编等业务字段挂进去,从而用 ip2region 管理自有 IP 定位数据。

查询路径很短:读文件头确认版本,经向量索引定位段索引块,再读出区域字符串。binding/golang/ 的交互式查询程序每次查询都会打印 iocount 字段,它来自 searcher 内部 ioCount 的累计——这是观察磁盘 IO 次数、对比不同缓存策略最直接的出口。

选对缓存策略:最省内存 / 默认推荐 / 极致性能

各语言客户端的三种模式设计一致。以 Go 实现为例,Searcher 结构体同时持有 vectorIndex 与 contentBuff 两块缓冲,read() 优先从 contentBuff 拷贝,落空才走 Seek + Read:

档位构造方式内存延迟适用场景
最省内存:纯文件NewWithFileOnly无常驻内存每次查询有磁盘 IO低 QPS、内存紧张的工具服务
默认推荐:VectorIndexNewWithVectorIndex固定 512KiB平均 100 微秒以内大多数线上查询服务
极致性能:整文件NewWithBuffer等于 xdb 文件大小10 微秒级、零 IO高并发网关、极致延迟场景

512KiB 索引缓存为什么够用

512KiB 不是拍出来的,是常量相乘:binding/golang/xdb/header.go 中 VectorIndexRows = 256、VectorIndexCols = 256、VectorIndexSize = 8 字节,256×256×8 = 524288 字节。把这块区域理解成大图书馆的"楼层导览牌":段索引区被切成 256×256 个分组,每个 8 字节的 super block 只记该组的"首个索引块指针 + 末个索引块指针",查询先查导览牌缩小范围,再在块内二分,省掉了寻找起点的磁盘 IO。vIndex 是只读数据,可在进程启动时 LoadVectorIndexFromFile 一次,全局共享,每个 goroutine 各自创建 searcher,减少固定 IO 与系统压力。

要零 IO 就上 NewWithBuffer:整文件入内存后创建的 searcher 天然并发安全、可直接共享,延迟钉在 10 微秒级;验证方式是跑 bench,输出的 Cost 字段即单次查询平均耗时(ns)。

多语言生产环境:并发安全查询与 xdb 文件校验

查询客户端覆盖主流语言,全部同时支持 IPv4 与 IPv6:

语言目录语言目录
Golangbinding/golang/C(std=c99)binding/c/
Javabinding/java/Rustbinding/rust/
PHPbinding/php/Pythonbinding/python/
JavaScriptbinding/javascript/C#binding/csharp/
Lua / Lua_Cbinding/lua/、binding/lua_c/Erlangbinding/erlang/
Nginx 扩展binding/nginx/C++binding/cpp/
Cangjie(仓颉)binding/cangjie/

另有社区开发者通过第三方仓库贡献了 php composer 客户端、node.js addon、ruby 查询实现与数据转换工具。

Go 并发查询:searcher 池怎么配

自 3.11.0 起,官方建议直接用 binding/golang/service/ip2region.go 的 Ip2Region 统一服务接入,分四步:

  1. v4、v6 配置分开创建(NewV4Config/NewV6Config),参数依次为缓存策略(NoCache/VIndexCache/BufferCache)、xdb 路径、searcher 数量;某参数传 nil 即禁用该版本查询,对应查询返回 "";
  2. 用 service.NewIp2Region(v4Cfg, v6Cfg) 创建服务,API 并发安全,内部按 IP 字节长度(4 或 16)自动识别版本;
  3. searcher 数量按你的服务并发量设置,运行期固定——每次查询从池中借出一个 searcher、用完归还,池空时借出操作会阻塞等待可用实例;
  4. 缓存策略为 BufferCache 时数量参数被忽略,内部使用单实例内存 searcher;关闭时调用 Close(),默认最多等 10 秒让 searcher 归还,可用 CloseTimeout 自定义。

基础 API 为 Search(string | []byte) (string, error):失败时 error 携带具体原因,IP 未命中返回空串。

import "github.com/lionsoul2014/ip2region/binding/golang/service"

// v4/v6 配置分开创建,参数传 nil 表示禁用该版本查询
v4Cfg, _ := service.NewV4Config(service.VIndexCache, "data/ip2region_v4.xdb", 20)
v6Cfg, _ := service.NewV6Config(service.VIndexCache, "data/ip2region_v6.xdb", 20)
ip2, _ := service.NewIp2Region(v4Cfg, v6Cfg)
defer ip2.Close() // 默认等待 10 秒让 searcher 归还

region, err := ip2.Search("1.2.3.4") // 自动识别 v4/v6,未命中返回 ""

VerifyFromFile:为什么只在启动时校验一次

// 服务启动时执行一次;严禁在每次创建 Searcher 时校验
err := xdb.VerifyFromFile(dbPath)

校验逻辑见 binding/golang/xdb/util.go 的 Verify:读取 256 字节文件头,按结构版本(Structure20/Structure30)推导运行时指针字节数,并确认 xdb 文件大小不超过指针可表达的最大值,防止文件指针溢出。后续版本的新特性可能让旧 searcher 与新文件不兼容,不做校验会在运行期出意外错误;但校验本身要读盘,放进高并发查询路径会拖慢响应,所以只在启动时(或命令行手工)做一次。

自己造 xdb:从文本源文件生成的完整命令

xdb 文件四段结构与字节级细节

生成程序位于 maker/,语言覆盖:Golang、Java、Rust、C++ 均支持 IPv4 与 IPv6,Python、C# 仅支持 IPv4。maker/golang/xdb/maker.go 头注释给出的文件布局如下:

+----------------+-------------------+---------------+--------------+
| header space   | speed up index    |  data payload | block index  |
+----------------+-------------------+---------------+--------------+
| 256 bytes      | 512 KiB (fixed)   | dynamic size  | dynamic size |
+----------------+-------------------+---------------+--------------+
  • 头部区 256 字节:2 字节版本号(IPv6 支持前固定为 2,其后更新为 3)、2 字节索引算法编码、4 字节生成时间戳、4 字节索引块起始/结束指针、2 字节 IP 版本(4/6)、2 字节运行时指针字节数;
  • 数据负载区:每条区域信息为 2 字节长度 + 动态长度内容;
  • 段索引区:每条索引项 = 起始 IP + 结束 IP + 2 字节数据长度 + 4 字节数据指针,IPv4 每项 14 字节、IPv6 每项 38 字节(见 binding/golang/xdb/version.go 的 SegmentIndexSize 常量);
  • 向量索引区:256×256 个 super block、每个 8 字节,即前文的"楼层导览牌"。

生成过程自动完成去重与压缩:相邻、重叠的 IP 段会被检查并合并补全;Maker 内部用 regionPool map[string]uint32 充当"中心仓库"——首个出现的区域字符串分配一个数据指针,后续相同区域只存指针引用,同一份内容在文件里只落盘一次。

# 在 maker/golang 目录 make 编译后执行
./xdb_maker gen --src=../../data/ipv4_source.txt --dst=./ip2region_v4.xdb --version=ipv4
# --field-list 可按索引重组字段,如 0,1,2,3-6,7;--log-level: debug/info/warn/error
./xdb_maker bench --db=./ip2region_v4.xdb --src=../../data/ipv4_source.txt --version=ipv4

生成验证:bench 怎么用

自行生成的 xdb 必须跑 bench:它逐行读取源文件,从每个 IP 段中取起始与结束 IP 做查询,与原始区域逐一比对,不一致即打印错误并终止,看到 Bench finished 即代表通过。两个硬约束:--src 必须与生成该 xdb 时使用的源文件一致;默认出错立即终止,加 --ignore-error=true 可跳过继续、最后查看失败统计。maker/golang/ 还附带 Dockerfile,可在隔离环境里构建镜像完成生成、查询与验证。

xdb 数据更新:手工编辑与检测式自动更新

仓库自带的离线 IP 定位源数据只是不定期更新。对数据准确性、更新频率要求高的场景,官方建议购买 Ip2Region 社区或第三方厂商的商业离线数据;要自行维护则走两条路。

用 edit 子命令手工编辑

editor>> put 36.132.128.0|36.132.147.255|中国|黑龙江省|哈尔滨市|移动|CN
Put(...): Ok, with 1 deletes and 2 additions
editor>> put_file ../../data/sample/ip.test.txt
editor>> save

在 maker/golang 目录 make 后执行 ./xdb_maker edit --src=../../data/ipv4_source.txt --version=ipv4 进入交互编辑器,命令分步如下:

  • put [segment]:段格式为 起始IP|结束IP|国家|省份|城市|运营商|国家代码;输出的 1 deletes and 2 additions 表示编辑器已自动完成对原有段的拆分与替换;
  • put_file [file]:批量加载,文件中的 IP 段不必严格连续、允许重叠,编辑器自动分析处理,仓库自带示例 data/sample/ip.test.txt;
  • list [offset] [size]:分页列出数据段用于核对;save:写回源文件,随后用 gen 重新生成 xdb;quit:退出。

maker/cpp/ 同样提供 C++ 数据编辑器,支持 IPv4/IPv6。

检测式自动更新

如果你有海量真实访问来源、能持续采集归属反馈,可参考官方 "Detection Algorithm"(检测算法)编写自己的更新程序:以现有数据为基准,与真实反馈比对,识别漂移段并增量修正。官方社区提供 Data Update 两期实现视频讲解该流程。

⚠️ 上线检查清单

  • xdb 已通过 VerifyFromFile 校验(启动时一次,不做进每次创建 Searcher 的路径);
  • 缓存策略已按三档选定:最省内存 / 默认推荐(512KiB VectorIndex)/ 极致性能(整文件),并用 iocount 与 bench 的 Cost 复核过;
  • searcher 池数量与你的服务并发量匹配,且明白运行期数量固定;
  • 每次数据更新后重跑 bench,--src 与生成时的源文件严格一致;
  • IPv4/IPv6 各自的 xdb 用对应 --version 参数生成与校验;
  • 区域字段(含 --field-list 扩展字段)与业务侧解析逻辑的字段数一致。

想再深入,可前往 ip2region.net 官方社区(2025-06-12 正式上线),那里提供商业离线数据服务、查询测试与数据纠错,以及覆盖 xdb 数据结构、查询过程、生成过程、文件生成教程、并发安全查询、数据更新共 6 篇系列技术文档——建议从"数据结构描述"读起,再对照本清单落地;作者的技术分享公众号为 lionsoul-org。

【免费下载链接】ip2region Ip2region is an offline IP-to-Region localization library and IP data management framework with both IPv4 and IPv6 supports, 10-microsecond level query efficiency, xdb search client for many programming languages 【免费下载链接】ip2region 项目地址: https://gitcode.com/GitHub_Trending/ip/ip2region

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值