实现一个简单的java版本高性能获取ip地址所属国家工具
TL;DR 用 Java 实现高性能 IP 地址归属国家查询工具,基于 IP2Location 数据源,将 IP 段排序后通过二分查找定位,单次查询延迟微秒级。
一个高性能的 Java IP 地址归属国家查询工具,核心思路是用二分查找在预加载的 IP 段数组中定位,单次查询延迟在微秒级。
设计思路
IP 地址本质上是一个 32 位整数。所谓”IP 段”就是一段连续的整数范围。给定一个 IP,我们要找到它落在哪个 IP 段中——这是一个典型的区间查找问题。
最直接的做法是遍历所有 IP 段,O(n) 复杂度。但全球 IP 段有几十万个,遍历太慢。更好的做法是把 IP 段的起始地址排序后放入数组,用二分查找定位,O(log n) 复杂度,几十万个段只需要约 19 次比较。
数据源
IP 地址库数据可以从 IP2Location Lite 免费获取。数据格式示例:
1 | 16781312,JP |
每行包含两个字段:IP 段的起始地址(转换后的整数)和国家代号。
原始数据其实还包含 IP 段的结束地址,但 IP2Location 的数据段是连续无间隙的——一个段的结束地址恰好是下一个段的起始地址减一。因此我们可以只存储起始地址,结束地址自然而然地由下一个段的起始地址确定。这个优化节省了一半的内存。
数据结构
1 | public class IpCountryLookup { |
两个并行数组:startIps[i] 和 countryCodes[i] 一一对应。二分查找在 startIps 上进行,找到后从 countryCodes 中取结果。
核心实现:二分查找
1 | public String lookup(String ip) { |
性能数据
- 内存占用:约 30 万条 IP 段,两个数组各 ~30 万元素,总计约 4 MB
- 查询延迟:单次查询 < 10 微秒(二分查找约 19 次比较)
- QPS:单机轻松支撑百万级
- 数据更新:IP 库约每月更新一次,定时任务自动拉取并重载
其他数据源对比
| 数据源 | 精度 | 免费版 | 特点 |
|---|---|---|---|
| IP2Location Lite | 国家 | ✓ | 数据干净,格式统一 |
| GeoIP2(MaxMind) | 城市 | ✓(有限) | 社区认可度高,Java API 完善 |
| 纯真 IP 库 | 运营商 | ✓ | 国内精度最高 |
| ipip.net | 城市/运营商 | ✗ | 国内最准确,但收费 |
如果只需要国家粒度,IP2Location Lite 足够。需要城市精度则推荐 MaxMind GeoLite2。
部署
项目基于 Spring Boot,支持两种运行方式:
1 | # 直接运行 |
在线体验:http://ip-country.lichuanyang.top/
项目源码:https://github.com/lcy362/ip-country
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Mobility!
评论





