一、实现方式
社区的“数据服务”会提供一个版本信息API用于查询最新数据版本的信息,一旦发现有新版本即可调用”外用下载API“去下载最新版本的xdb数据,核心步骤如下:
1. 调用“版本信息API”查询最新数据的版本信息。
2. 对比最新版本和本地版本的信息,判断数据是否有更新。
3. 如果有更新则调用“外用下载API”去下载最新版本的xdb数据覆盖本地数据完成更新,如果没有更新则继续等待至少10分钟继续上述2个步骤。
二、版本检测
登录社区后,点击数据服务中的自动更新找到您的专属”版本信息 API“,API 格式类似如下:
// 该 API 地址不可用,仅作演示使用
https://ip2region.net/api/public/data/offline/ver_latest?t=cb0ecb9356.1.6844f7e6.OF001@JCB
备注:请至少间隔10分钟请求一次该API,请求过于频繁 token 参数会被系统屏蔽。
调用该API将返回您的数据服务的最新的版本信息(JSON格式),数据和注解如下:
{"errno"
:0
,// 错误代码,0 表示成功,非 0 则表示失败
"errstr"
:"OK"
,// 错误描述,errno 为 0 时为 OK,否则为具体的错误描述
"data"
: {"_source"
:"vinfo"
,"srv_id"
:"OF001@JCB"
,// 当前数据服务的 id
"model"
:"v4_monthly"
,// 当前数据服务的型号,v4_monthly 表示月更
"released_at"
:1754110800
,// 最新数据的发布时间戳
"released_dt"
:"2025-08-02 13:00:00"
,// 最新数据的发布日期时间
"expired_at"
:1875586300
,// 当前数据更新服务的过期时间戳
"expired_dt"
:"2029-06-08 12:11:40"
// 当前数据更新服务的过期日期时间
} }
上述返回参数中的data.released_at即为最新xdb数据的发布时间,要确定本地xdb数据是否有更新,我们还需要知道本地使用的xdb文件的发布时间。
C/PHP/Golang/Java等这些查询客户端提供了本地API用于获取指定xdb文件的生成时间戳,例如:
// C
xdb_header_t
*header =xdb_load_header
(handler); header->created_at;// xdb 文件的生成时间戳
// PHP
$header = XdbSearcher::loadHeaderFromFile
($xdbFile); $header['createdAt
'];// xdb 文件的生成时间戳
// Golang
header := xdb.LoadHeaderFromFile
(xdbFile); header.CreatedAt// xdb 文件的生成时间戳
// 其他语言可以查看对应的 Github / Gitee 对应的 binding 的源码
也有部分查询客户端没有提供这个API,查阅一下XDB-V4数据结构可以知道xdb的header段存储了文件生成的时间戳,通过一些简单的文件操作可以得到这个数据,具体代码逻辑如下:
// 以只读的方式打开对应的 xdb 文件
var
handle =fopen
("本地xdb文件的路径"
,"r"
);// 文件指针移动到 4
fseek
(handle,4
);// 从当前位置读取 4 个字节
var
b4 =fread
(handle, 4);// 按照小端字节序解码得到一个无符号整数即为 xdb 文件的生成时间
var
createdAt = b4[0
] | (b4[1
] <<8
) | (b4[2
] <<16
) | (b4[3
] <<24
);
本地xdb文件的createdAt如果比版本信息 API返回的data.released_at要小即本地的 xdb 文件需要更新。
三、数据下载
登录社区后,点击数据服务中的自动更新找到您的专属”外用下载 API“,例如,V4-基础版的满载版XDB的API如下类似如下:
该 API 地址不可用,仅作演示使用
https://ip2region.net/api/public/data/offline/get_file?t=6e94fe429a.1.6842bce6.OF001@JCB&v=v001@full
备注:该链接每天限制最多 12 次访问。
直接使用下载工具或者浏览器访问该地址即可直接下载满载版XDB文件,例如:
// 使用 wget 下载最新版本的 xdb 文件并且存储到本地的 base_full.xdb 文件中
wget https://ip2region.net/api/public/data/offline/get_file?t=6e94fe429a.1.6842bce6.OF001@JCB&v=v001@full -O base_full.xdb
如果是在代码中使用http客户端去下载这个数据,一定要注意开启http重定向追踪,因为该 API 最终会重定向到一个阿里云的 oss 地址。例如,使用curl客户端的一些核心设置和描述如下:
var
oss_url ="外用下载API地址"
;var
ch =curl_init
();curl_setopt
(ch,CURLOPT_URL
, oss_url);curl_setopt
(ch,CURLOPT_RETURNTRANSFER
,1
);// 返回 API 返回的数据, 不直接打印出来
curl_setopt
(ch,CURLOPT_TIMEOUT
,1800
);// 设置超时时间,xdb 文件很大,下载过程可能比较长
curl_setopt
(ch,CURLOPT_FOLLOWLOCATION
,true
);// 跟踪 HTTP 的重定向,直接访问最终的 oss 地址
// 过滤掉 https 的一些验证
if
(substr
(oss_url, 0, 6) =="https:"
) {curl_setopt
(ch,CURLOPT_SSL_VERIFYPEER
,false
);curl_setopt
(ch,CURLOPT_SSL_VERIFYHOST
,false
); }
使用中,无论您是直接将整个xdb文件缓存到内存中,还是直接基于文件去查询,xdb文件的下载过程建议按照如下方式来进行:
// 1,调用 “外用下载API” 将最新的 xdb 文件下载到一个临时文件,此处以 wget 作为演示。
wget https://ip2region.net/api/public/data/offline/get_file?t=6e94fe429a.1.6842bce6.OF001@JCB&v=v001@full -O base_full.tmp.xdb// 2,将临时 xdb 文件 move 到正式线上文件,完成升级覆盖。
// move 这个操作不影响基于文件的查询使用。
// 如果您线上是使用的将整个 xdb 内存缓存的方式,需要重新载入新文件替换线上使用的 xdb 实例/引用。
move base_full.tmp.xdb base_full.xdb
四、升级脚本
依据上述描述的升级过程,您可以自己编写一个 bash 脚本使用 linux crontab 这样的定时任务来执行,也可以是一个升级程序,程序中定期休眠去检测,大致逻辑如下:
var
ver_api_url = "";// 版本信息 API 地址
var
_dl_api_url = "";// 外用下载 API 地址
var
_created_at =get_local_xdb_created_at
();// 本地 xdb 文件的生成时间
for
( ; ; ) {// 1, 调用 “版本信息 API ” 获取最新数据的版本信息
var
latest =get_latest_release_info
(ver_api_url);if
(latest.data.released_at <= _created_at) {// 最新发布时间 <= 本地生成时间,不需要更新,继续等待下一次检测
goto
wait; }// 2, 调用 “外用下载 API ” 下载最新的 xdb 文件到一个临时文件
var
err =download_xdb_to_file
(_dl_api_url, "base_full.tmp.xdb");if
(err != null) {// 处理错误
goto
wait; }// 3, move 临时 xdb 文件到正式的 xdb 文件
err =move
("base_full.tmp.xdb", "base_full.xdb");if
(err != null) {// 处理错误
goto
wait; }// 休眠等待 10 分钟
wait: sleep(600); }
社区将后续会提供一个自动升级程序的实现,并且开源到Ip2Region的代码仓库中,请关注社区的后续通知。