最近在做一个 p2p 应用,有一个需求是想根据 peer 的物理距离选择最佳路由,貌似 ip 和距离没什么太直接的关系,搜索了一圈提供这种服务的大多是在线的 rpc ,又慢又有次数和频率限制,更过分的是还有收费的,哎!
苦恼了一下午终于发现了救星 《geoip2-golang》 ,他们维护了一套ip地址库并且提供了模糊的坐标信息,经过一番简单的封装,可以在 golang 程序中非常容易的使用这些信息,我已经在生产环境中使用了这个库,迫不及待分享给有需要的伙伴们。
go-geoip2-db
安装
go get https://github.com/cc14514/go-geoip2-db
使用
package geoip2db
import (
"encoding/json"
"fmt"
"net"
"testing"
)
func TestNewGeoipDbByStatik(t *testing.T) {
db, _ := NewGeoipDbByStatik()
defer db.Close()
record, _ := db.City(net.ParseIP("115.35.95.90"))
fmt.Printf("Portuguese (BR) city name: %v\n", record.City.Names["pt-BR"])
fmt.Printf("English subdivision name: %v\n", record.Subdivisions[0].Names["en"])
fmt.Printf("Russian country name: %v\n", record.Country.Names["ru"])
fmt.Printf("ISO country code: %v\n", record.Country.IsoCode)
fmt.Printf("Time zone: %v\n", record.Location.TimeZone)
fmt.Printf("Coordinates: %v, %v\n", record.Location.Latitude, record.Location.Longitude)
}
上面单元测试中得到的 record
结构如下,包含了你想要的全部信息
{
"City": {
"GeoNameID": 0,
"Names": null
},
"Continent": {
"Code": "AS",
"GeoNameID": 6255147,
"Names": {
"de": "Asien",
"en": "Asia",
"es": "Asia",
"fr": "Asie",
"ja": "アジア",
"pt-BR": "Ásia",
"ru": "Азия",
"zh-CN": "亚洲"
}
},
"Country": {
"GeoNameID": 1814991,
"IsInEuropeanUnion": false,
"IsoCode": "CN",
"Names": {
"de": "China",
"en": "China",
"es": "China",
"fr": "Chine",
"ja": "中国",
"pt-BR": "China",
"ru": "Китай",
"zh-CN": "中国"
}
},
"Location": {
"AccuracyRadius": 50,
"Latitude": 39.9289,
"Longitude": 116.3883,
"MetroCode": 0,
"TimeZone": "Asia/Shanghai"
},
"Postal": {
"Code": ""
},
"RegisteredCountry": {
"GeoNameID": 1814991,
"IsInEuropeanUnion": false,
"IsoCode": "CN",
"Names": {
"de": "China",
"en": "China",
"es": "China",
"fr": "Chine",
"ja": "中国",
"pt-BR": "China",
"ru": "Китай",
"zh-CN": "中国"
}
},
"RepresentedCountry": {
"GeoNameID": 0,
"IsInEuropeanUnion": false,
"IsoCode": "",
"Names": null,
"Type": ""
},
"Subdivisions": [
{
"GeoNameID": 2038349,
"IsoCode": "BJ",
"Names": {
"en": "Beijing",
"fr": "Municipalité de Pékin",
"zh-CN": "北京市"
}
}
],
"Traits": {
"IsAnonymousProxy": false,
"IsSatelliteProvider": false
}
}