news 2026/9/8 23:50:01

ip2region 完整指南:3 步搞定离线 IP 定位到城市级

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ip2region 完整指南:3 步搞定离线 IP 定位到城市级

ip2region 完整指南:3 步搞定离线 IP 定位到城市级

【免费下载链接】ip2regionIp2region 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项目地址: https://gitcode.com/GitHub_Trending/ip/ip2region

你有没有过这种经历:系统里存了一堆用户 IP,想看看他们来自哪里,结果每次都要调第三方在线接口——网络一抖就超时,调用量一大还要计费,更麻烦的是服务一停,日志里的位置信息就再也没法补查。ip2region 是一款免费的离线 IP 定位库,把全国乃至全球的城市级 IP 数据压缩进一个本地文件,查询不需要联网,单次响应在微秒级。这篇文章带你从零走到落地。

它到底是什么

把 ip2region 理解成一本"随身携带的电话簿":在线查询服务像是打电话给 114 查号,每次都要等对方接;而 ip2region 是把整本电话簿复印在你桌上,翻到哪页自己查,不用问任何人。

它干两件事:一是提供ip2region_v4.xdbip2region_v6.xdb两个数据文件,直接查 IP 归属的"国家|省份|城市|运营商";二是提供一整套数据管理工具,让你能改数据、重新打包,把 GPS 坐标、邮编这类自定义字段塞进查询结果里。查询客户端覆盖了 Golang、Java、Python、C、PHP、Rust、C#、Lua、Erlang、Nginx 扩展等十几种语言,在 binding/ 目录下各有一版实现和文档。

第一次查询:3 步手动跑通

先亲手查一个 IP,感受一下它快不快。

第一步,拿到代码和数据:

git clone https://gitcode.com/GitHub_Trending/ip/ip2region

第二步,用仓库里现成的 Python 查询测试程序启动交互查询(Python 版在 binding/python/):

cd ip2region/binding/python python search_test.py --db ../../data/ip2region_v4.xdb

第三步,在提示符后面输入一个 IP,比如113.92.157.29,回车。你会看到类似这样的输出:

{region: 中国|广东省|深圳市|中国联通, ioCount: 3, took: 87 μs}

took这一列就是单次查询耗时,这里的单位是微秒。输入quit退出。如果你更常用 Golang,binding/golang/main.go 是一个功能一样的交互程序,go run main.go search即可启动,输入框同时支持 IPv4 和 IPv6。

数据文件放在 data/ 目录:v4 文件约 11MB,v6 约 37MB,源数据ipv4_source.txt里有 51 万多个 IP 段,ipv6_source.txt约 67 万个。

它凭什么这么快

你可能会问:五百万多条 IP 段,就算全装进内存,线性扫一遍也不止微秒级。答案在它的查询结构里。

xdb 文件的设计可以类比你查字典:你不可能从第一页翻起找"省"这个字,你会先翻到目录,按首字母定位到大概页码,再在几页里找到它。xdb 内部同样存了一张"目录"——向量索引,它按 IP 数值切分成定长块,查询时先用这个索引算出目标 IP 落在哪个块,再在那个块内做一次二分定位,所以典型查询只需要两三次随机读。

正因为有这层索引,ip2region 给了你三档缓存策略,你可以按需选择:

  • file:完全不缓存,每次查询都读文件,仍然在百微秒级,适合内存紧张或查询量小的场景;
  • vectorIndex:只把那张"目录"(512KiB 内存)装进内存,省掉一次磁盘定位,平均查询压到 100 微秒内,是默认推荐档;
  • content:把整个 xdb 文件读进内存,查询稳定在 10 微秒级,代价是内存占用等于文件大小(v4 约 11MB,很划算)。

切换策略只是一个参数的事,比如 Python 测试程序的--cache-policy就接受这三个值,Golang 里对应service.NoCache/service.VIndexCache/service.BufferCache

一个端到端案例:给访问日志补上城市信息

假设你的 Nginx 访问日志长这样:

2026-09-07 10:15:32 218.17.37.165 GET /index.html 200

你想在日志报表里看到每个访客来自哪个城市。链路其实很短:

  1. 日志进来后提取出点分十进制的 IP 字段;
  2. 把它交给查询服务;Golang 的并发安全查询服务几行就能建起来(摘自 binding/golang/ 文档):
v4Config, _ := service.NewV4Config(service.VIndexCache, "ip2region_v4.xdb", 20) v6Config, _ := service.NewV6Config(service.VIndexCache, "ip2region_v6.xdb", 20) ip2region, _ := service.NewIp2Region(v4Config, v6Config) region, err := ip2region.Search("218.17.37.165")
  1. Search返回中国|北京市|北京市|中国移动这样的字符串,你的代码按|切分,把省份和城市拼回日志行即可。

这个案例里有几个细节值得注意。返回值是"国家|省份|城市|运营商|ISO 国家码"的固定格式,国内数据用中文、国外数据用英文,解析时按位置取而不是按内容匹配会更稳。Search对 IPv4 和 IPv6 都能处理,服务内部自动识别版本,你不需要写两遍逻辑。查不到该 IP 时返回空字符串,记得在报表里留个"未知"分支。

常见坑与性能取舍

并发问题。单个基于文件的查询对象不是并发安全的,多线程共用一个会出脏数据。两种正规解法:用前面那种带查询池的Ip2Region查询服务,按你的并发数设置池大小(比如 20);或者用content策略的内存查询器,它本身就并发安全。别图省事自己加锁包一个,池化方案吞吐更高。

别在热路径上验文件。各语言 API 都提供Verify校验 xdb 文件完整性,但它有开销,官方注释明确建议只在部署时校验一次,不要每次查询前都调。

缓存策略别一步到位。内存有限就先跑vectorIndex,512KiB 的代价换来比纯文件查询更稳定的延迟;等 QPS 真的高到磁盘 IO 成为瓶颈,再升content。升级路径是平滑的,只改一个参数。

数据会过期。仓库里的源数据不定期更新,对准确性要求高的业务建议接入 data/README_zh.md 里说明的更新渠道,或者用 maker/ 下的生成工具自己维护数据:源数据是纯文本(起始IP|结束IP|国家|省份|城市|ISP|国家码),改完重新打包成 xdb 即可,Golang、Java、Python、C#、Rust 都有打包器,它还会自动合并相邻的相同 IP 段、去重压缩,所以你的自定义数据不用手动整理格式。

下一步去哪

  • 想看懂 xdb 文件长什么样:查一下 v4 文件头,或直接读各语言查询客户端的源码,结构都在 binding/ 里;
  • 想生成或修改数据:看 maker/golang/ 的 README,里面有编辑器和打包流程的完整说明;
  • 想给 Nginx 直接加geo指令级的定位能力:binding/nginx/ 提供了模块实现和测试;
  • 想给自己的项目挑客户端:翻 binding/ 下对应语言的 README,每份都带完整 API 说明和测试程序,照着抄就行。

装好数据、选对缓存策略,你的项目就获得了一个不依赖网络、微秒级响应的定位能力。剩下的只是把日志、风控、报表这些入口接上去的事。

【免费下载链接】ip2regionIp2region 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项目地址: https://gitcode.com/GitHub_Trending/ip/ip2region

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 23:49:53

扩散模型在MIMO检测中的MATLAB实现:从代码到调参全解析

简介:面向MATLAB与无线通信学习者的多天线仿真代码包,聚焦“基于扩散”的码分机制,完整覆盖单入单出、单入多出、多入单出及多入多出空间调制等典型链路,用于演示多天线技术如何提升信道容量与抗衰落能力。压缩包共4个m文件&#…

作者头像 李华
网站建设 2026/9/8 23:48:26

90度FOV多区TOF传感器技术解析与落地实践

1. 这颗TOF芯片到底解决了什么真问题?“意法半导体全新多区测距TOF传感器:高达90度视场角堪比相机水准”——这标题里藏着三个被行业憋了很久的痛点,不是噱头,是实打实的工程突破。我做嵌入式视觉方案落地快十年了,从早…

作者头像 李华
网站建设 2026/9/8 23:48:16

C语言图书管理系统课程设计实战:结构体、链表与文件持久化解析

简介:面向计算机专业学生及C语言初学者的图书管理系统课程设计资源,以经典应用场景帮助读者把语言基础转化为实践项目。系统覆盖图书信息展示、入库登记、销售处理、条件查询、排序和修改等完整业务模块,实现过程中重点展示了结构体封装图书信…

作者头像 李华
网站建设 2026/9/8 23:46:40

Linux DRM子系统实战解析:从KMS到Atomic Commit

1. 项目概述:这不是一篇“历史课”,而是一份内核驱动工程师的实战备忘录 如果你在Linux图形栈里摸爬滚打过,大概率被drm_ioctl()返回的-EINVAL卡住过半天;如果你调试过一块RK3588板子上的HDMI输出,一定反复翻过drm_mod…

作者头像 李华