Golang结合ip2region实现ip归属地查询

 更新时间:2024年03月01日 16:26:56   作者:柯柏技术笔记  
ip2region - 是一个离线IP地址定位库和IP定位数据管理框架,提供了众多主流编程语言的 xdb 数据生成和查询客户端实现,下面我们就来看看Golang如何结合ip2region实现ip归属地查询吧

背景

最近公司做了一些营销活动,投入资金进行了流量推广,pv、UV都做了统计。老板说,我要看下用户的区域分布的数据。

以前的文章我讲过,pv、UV如何统计?我们是基于ip进行统计的。用的ip能获取到,那通过ip查询归属地就ok了。

思维扩展下,ip 查询归属地的的场景还蛮多的,我列举一些:

场景

  • 网络安全调查:当发生网络攻击或恶意行为时,通过查询IP地址的归属地可以帮助调查人员追踪攻击者的位置和身份,进而采取相应的应对措施。
  • 电商网站反欺诈:电商平台可以通过查询IP的归属地来检测是否有异常行为,如异地登录或使用虚假身份信息下单,从而防止欺诈行为发生。
  • 广告定向投放:在在线广告市场中,根据用户所在地区进行IP归属地查询可以帮助广告主精准定位目标受众,提高广告投放效果和ROI。
  • 地理位置服务:地图应用、天气预报和周边生活服务等可以利用IP归属地查询来确定用户的大概地理位置,提供个性化的地理服务和信息。
  • 网站流量分析:网站管理员可以利用IP归属地查询来分析网站访问的地域分布情况,评估市场覆盖范围,制定针对性的营销策略和内容优化计划。

这些具体的使用场景说明了IP归属地查询在网络安全、营销推广、个性化服务等方面的重要作用,能够帮助用户更好地理解用户行为和优化业务流程。

谷歌搜索了下,第三方提供的ip查询归属地服务,挺多的,但是收费、收费、收费!!!免费也有些,但是怕不稳定。

无意间找到了ip2region这个项目,一直持续维护更新,试用后,效果杠杆的。那我们怎么用的,继续往下看

ip2region

Ip2region 是什么

ip2region - 是一个离线IP地址定位库和IP定位数据管理框架,10微秒级别的查询效率,提供了众多主流编程语言的 xdb 数据生成和查询客户端实现。

Ip2region 特性

1、IP 数据管理框架

xdb 支持亿级别的 IP 数据段行数,默认的 region 信息都固定了格式:国家|区域|省份|城市|ISP,缺省的地域信息默认是0。 region 信息支持完全自定义,例如:你可以在 region 中追加特定业务需求的数据,例如:GPS信息/国际统一地域信息编码/邮编等。也就是你完全可以使用 ip2region 来管理你自己的 IP 定位数据。

2、数据去重和压缩

xdb 格式生成程序会自动去重和压缩部分数据,默认的全部 IP 数据,生成的 ip2region.xdb 数据库是 11MiB,随着数据的详细度增加数据库的大小也慢慢增大。

3、极速查询响应

即使是完全基于 xdb 文件的查询,单次查询响应时间在十微秒级别,可通过如下两种方式开启内存加速查询:

  • vIndex 索引缓存 :使用固定的 512KiB 的内存空间缓存 vector index 数据,减少一次 IO 磁盘操作,保持平均查询效率稳定在10-20微秒之间。
  • xdb 整个文件缓存:将整个 xdb 文件全部加载到内存,内存占用等同于 xdb 文件大小,无磁盘 IO 操作,保持微秒级别的查询效率。

Ip2region 支持那些语言

Ip2region大部分主流语言都支持,支持的语言如下:

Ip2region怎么用

在这里,我以golang语言作为演示,其他语言,可以看下官方文档

例子:我需要查询ip为:218.63.140.248 的归属地

下载ip2region.xdb包

访问ip2region 项目,ip的库文件在data目录下,点击下载即可

package 获取

go get github.com/lionsoul2014/ip2region/binding/golang

完全基于文件的查询

package main

import (
	"fmt"
	"github.com/lionsoul2014/ip2region/binding/golang/xdb"
	"time"
)

func main() {
	//dbPath写入你下载的ip2region.xdb文件的路径,我这里放在了当前目录下
	var dbPath = "ip2region.xdb"
	searcher, err := xdb.NewWithFileOnly(dbPath)
	if err != nil {
		fmt.Printf("failed to create searcher: %s\n", err.Error())
		return
	}
	defer searcher.Close()
	// 查询218.63.140.248对应的地址
	var ip = "218.63.140.248"
	var tStart = time.Now()
	region, err := searcher.SearchByStr(ip)
	if err != nil {
		fmt.Printf("failed to SearchIP(%s): %s\n", ip, err)
		return
	}
	fmt.Printf("{region: %s, took: %s}\n", region, time.Since(tStart))
	// 备注:并发使用,每个 goroutine 需要创建一个独立的 searcher 对象。
}

查询结果

此ip的归属地为: 中国云南省昆明市电信

缓存整个 xdb 数据

可以预先加载整个 ip2region.xdb 到内存,完全基于内存查询,类似于之前的 memory search 查询。

package main

import (
	"fmt"
	"github.com/lionsoul2014/ip2region/binding/golang/xdb"
	"time"
)

func main() {
	//dbPath写入你下载的ip2region.xdb文件的路径,我这里放在了当前目录下
	var dbPath = "ip2region.xdb"
	// 1、从 dbPath 加载整个 xdb 到内存
	cBuff, err := xdb.LoadContentFromFile(dbPath)
	if err != nil {
		fmt.Printf("failed to load content from `%s`: %s\n", dbPath, err)
		return
	}

	// 2、用全局的 cBuff 创建完全基于内存的查询对象。
	searcher, err := xdb.NewWithBuffer(cBuff)
	if err != nil {
		fmt.Printf("failed to create searcher with vector index: %s\n", err)
		return
	}
	defer searcher.Close()
	// 查询218.63.140.248对应的地址
	var ip = "218.63.140.248"
	var tStart = time.Now()
	region, err := searcher.SearchByStr(ip)
	if err != nil {
		fmt.Printf("failed to SearchIP(%s): %s\n", ip, err)
		return
	}
	fmt.Printf("{region: %s, took: %s}\n", region, time.Since(tStart))
	// 备注:并发使用,每个 goroutine 需要创建一个独立的 searcher 对象。
}

查询结果:

方案比对

  • 基于文件的查询,响应时间:38us
  • 基于缓存的查询,响应时间:10.29µs

生成环境使用建议使用方式为:基于缓存的查询

生产如何使用

以上的演示,只是个demo,如果要放在线上如何使用呢?

  • 以sdk的形式嵌入到项目,使用基于缓存的查询方式。
  • ip查询的场景很多,可以单独构建一个ip查询的公共服务,提高给各个业务线使用

sdk接入的方式,用到的业务线都需要对接一次,ip2region.xdb如果有更新,所有用到的项目都要自己去更新升级db文件,维护成本太高。如果你的项目比较单一,sdk接入也是不错的

我们的方案:因为我业务线相对太多,如果各个业务线自己接,维护的成本太高。我们决定构建IP查询归属地公共服务,往外提供查询的能力。后续服务的升级、维护等,统一在公共服务里面来做。

以上就是Golang结合ip2region实现ip归属地查询的详细内容,更多关于Go ip2region查询ip归属地的资料请关注脚本之家其它相关文章!

相关文章

  • golang基础之Gocurrency并发

    golang基础之Gocurrency并发

    这篇文章主要介绍了golang基础之Gocurrency并发,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • golang如何自定义json序列化应用详解

    golang如何自定义json序列化应用详解

    son格式可以算我们日常最常用的序列化格式之一了,下面这篇文章主要给大家介绍了关于golang如何自定义json序列化应用的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧
    2018-08-08
  • Go语言如何实现TCP通信详解

    Go语言如何实现TCP通信详解

    go里面实现tcp没有像之前写的C++那些那么麻烦,在C++里面要先创建套接字,然后绑定ip地址,go里面直接就一个函数建立套接字,然后在进行通信就可以了,下面这篇文章主要给大家介绍了关于Go语言如何实现TCP通信的相关资料,需要的朋友可以参考下
    2023-01-01
  • go设置多个GOPATH的方式

    go设置多个GOPATH的方式

    这篇文章主要介绍了go设置多个GOPATH的方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • Golang switch语句的具体使用

    Golang switch语句的具体使用

    switch 语句提供了一种简洁的方式来执行多路分支选择,本文主要介绍了Golang switch语句的具体使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-08-08
  • Go语言的反射机制详解

    Go语言的反射机制详解

    本文详细讲解了Go语言的反射机制,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • Golang语言如何避免空指针引发的panic详解

    Golang语言如何避免空指针引发的panic详解

    简单地说go语言的指针类型和C/C++的指针类型用法是一样的,除了出去安全性的考虑,go语言增加了一些限制,这篇文章主要给大家介绍了关于Golang语言如何避免空指针引发panic的相关资料,需要的朋友可以参考下
    2022-01-01
  • windows下使用vscode搭建golang环境并调试的过程

    windows下使用vscode搭建golang环境并调试的过程

    这篇文章主要介绍了在windows下使用vscode搭建golang环境并进行调试,主要包括安装方法及环境变量配置技巧,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • k8s容器互联-flannel host-gw原理篇

    k8s容器互联-flannel host-gw原理篇

    这篇文章主要为大家介绍了k8s容器互联-flannel host-gw原理篇,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • 一文带你探索Golang计时器的奥秘

    一文带你探索Golang计时器的奥秘

    在 Golang 中,计时器(timer)是一种常见的工具,用于定期执行某个任务或者在指定时间后触发某个事件。本文将深入探讨 Golang 计时器的实现原理和使用方法,帮助大家更好地理解和应用计时器
    2023-05-05

最新评论