在网关的应用中,有时会有限制服务在指定的国家和城市进行开放,目前主流的方案有使用付费的在线API和使用离线的IP数据库。接下来将介绍这两种方案的实际应用。
腾讯云上的千帆云市场就有大量的第三方企业提供的付费API服务,比如:https://market.cloud.tencent.com/products/30498,这种方式的API通常是按次数计费,35元就能调用一百万次。
商品详情页面也提供了API接口的不同语言的调用示例,其中在头部信息中的secretId和secretKey需要购买服务后从腾讯云平台中获取。
接口返回的数据示例如下,更多接口信息请参考详情页面。
{
"code": 200, // 详见code返回码说明
"msg": "成功", // code对应的描述
"charge": true,
"taskNo": "69564903663951243279", // 本次唯一请求号
"data": {
"country": "中国", // 国家
"country_id": "CN", // 国家编号
"area": "华东", //地域
"region": "浙江", //省份
"region_id": "330000", //省份编号
"city": "杭州", //城市
"city_id": "330100", //城市编号
"ip": "120.26.64.20",
"long_ip": "2014986260",
"isp": "移动" // 运营商
}
}
需要注意的是,这种调用API的方式会收到第三方服务的性能限制,咨询过商家,建议QPS在100左右,超过之后可能会报错,因为服务是所有用户共用。
本地解析的前提是要获取IP相关的数据库,目前比较主流的是maxmind的IP库,也有其它的IP解析服务商如ipinfo。
Maxmind是IP数据领域中的专业级公司,在注册平台之后,免费用户可以获取lite版本的数据库,该数据库每周更新一次,如果需要更精确的调用需求,则可以考虑升级付费用户,数据库更精确,且每天更新一次。
下载链接如下,在链接中更新个人的license_key信息,也可以在页面中自行选择需要下载的内容。
https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=xxxx&suffix=tar.gz
使用示例如下,使用的SDK是geoip2,在Maxmind开源的SDK maxminddb基础上再封装了一层。
import (
"encoding/json"
"fmt"
"log"
"net"
"github.com/oschwald/geoip2-golang"
)
const ipCityDataPath = "../data/GeoLite2-City.mmdb"
func main() {
// 要查询的IP地址
ip := "x.x.x.x"
// 本地maxmind数据库调用
geoip2DB, err := geoip2.Open(ipCityDataPath)
if err != nil {
log.Printf("country: %v", err.Error())
println(err)
return
}
parseIP := net.ParseIP(ip)
country, err := geoip2DB.Country(parseIP)
if err != nil {
println(err)
return
}
city, err := geoip2DB.City(parseIP)
if err != nil {
println(err)
return
}
val, _ := json.Marshal(city)
log.Printf("local db resp country: %s, city: %v", country.Country.IsoCode, city.City.Names)
log.Printf("local db resp: %v", string(val))
}
返回的示例如下,注意,有可能获取不到City的相关信息,Names可能为null,但是还是可以获取到Location中的经纬度,根据经纬度也能获取到城市信息。
{
"City": {
"Names": {
"de": "Bangkok",
"en": "Bangkok",
"es": "Bangkok",
"fr": "Bangkok",
"ja": "バンコク",
"pt-BR": "Banguecoque",
"ru": "Бангкок",
"zh-CN": "曼谷"
},
"GeoNameID": 1609350
},
"Postal": {
"Code": "10200"
},
"Continent": {
"Names": {
"de": "Asien",
"en": "Asia",
"es": "Asia",
"fr": "Asie",
"ja": "アジア",
"pt-BR": "Ásia",
"ru": "Азия",
"zh-CN": "亚洲"
},
"Code": "AS",
"GeoNameID": 6255147
},
"Subdivisions": [
{
"Names": {
"en": "Bangkok",
"ja": "バンコク",
"zh-CN": "曼谷"
},
"IsoCode": "10",
"GeoNameID": 1609348
}
],
"RepresentedCountry": {
"Names": null,
"IsoCode": "",
"Type": "",
"GeoNameID": 0,
"IsInEuropeanUnion": false
},
"Country": {
"Names": {
"de": "Thailand",
"en": "Thailand",
"es": "Tailandia",
"fr": "Thaïlande",
"ja": "タイ王国",
"pt-BR": "Tailândia",
"ru": "Таиланд",
"zh-CN": "泰国"
},
"IsoCode": "TH",
"GeoNameID": 1605651,
"IsInEuropeanUnion": false
},
"RegisteredCountry": {
"Names": {
"de": "Deutschland",
"en": "Germany",
"es": "Alemania",
"fr": "Allemagne",
"ja": "ドイツ連邦共和国",
"pt-BR": "Alemanha",
"ru": "ФРГ",
"zh-CN": "德国"
},
"IsoCode": "DE",
"GeoNameID": 2921044,
"IsInEuropeanUnion": true
},
"Location": {
"TimeZone": "Asia/Bangkok",
"Latitude": 13.7512,
"Longitude": 100.5172,
"MetroCode": 0,
"AccuracyRadius": 20
},
"Traits": {
"IsAnonymousProxy": false,
"IsSatelliteProvider": false
}
}
IpInfo在注册之后,也能获取每月50k的免费调用次数,可以获取到城市信息,如果需要更多调用需求,则可以考虑升级付费用户。
当然也可以在页面https://ipinfo.io/account/data-downloads中下载所需要的离线IP数据库,支持IPv4和IPv6,不过只能精确到国家。一般下载选择mmdb数据格式,后续可以用现有SDK快速解析,离线的数据库每天更新一次,后续可以通过脚本每日从下载链接中更新数据库。
使用示例如下,使用的SDK就是Maxmind开源的maxminddb。
import (
"encoding/json"
"fmt"
"log"
"net"
"github.com/oschwald/maxminddb-golang"
)
const ipCityDataPath = "../data/Country.mmdb"
func main() {
// 要查询的IP地址
ip := "x.x.x.x"
// 本地infoip数据库调用
db, err := maxminddb.Open(ipCityDataPath)
if err != nil {
log.Fatal(err)
}
defer db.Close()
ipNet := net.ParseIP(ip)
var record any
err = db.Lookup(ipNet, &record)
if err != nil {
log.Fatal(err)
}
result := record.(map[string]interface{})
fmt.Printf("local db resp Country: %s\n", result["country"])
log.Printf("local db resp: %v", result)
}
返回的示例如下:
{
"ip": "1.194.x.x",
"hostname": "194.1.broad.ha.dynamic.163data.com.cn",
"region": "Henan",
"country": "CN",
"loc": "34.7578,113.6486",
"org": "AS4134 CHINANET-BACKBONE",
"postal": "450000",
"timezone": "Asia/Shanghai"
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。