当前位置:网站首页>Geoip2 - golang golang source code analysis
Geoip2 - golang golang source code analysis
2022-08-02 23:03:00 【User 9710217】
https://github.com/oschwald/geoip2-golang用来解析
[GeoLite2](http://dev.maxmind.com/geoip/geoip2/geolite2/)
and [GeoIP2](http://www.maxmind.com/en/geolocation_landing)Database a kit.类似于nginx的https://github.com/leev/ngx_http_geoip2_module
GeoIP2What's the use of the database?我们可以根据ip来获取ipResponse of regional location and do relevant business:
1,简单的cdn,根据ipGeographic information is redirected to the appropriatecdn服务器
2,Do business fixed area block,比如:Don't give the Japanese customers
3,做国际化,According to the different places for different language services.
For example, we commonly used online toolshttps://github.com/zu1k/nali 其实就用到了geoip2-golang这个包来解析GeoIP2数据.下面,We see this package should be how to use:
package main
import (
"fmt"
"log"
"net"
"github.com/oschwald/geoip2-golang"
)
func main() {
db, err := geoip2.Open("./GeoLite2-City.mmdb")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// If you are using strings that may be invalid, check that ip is not nil
ip := net.ParseIP("180.101.49.12") //120.24.37.249
record, err := db.City(ip)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Portuguese (BR) city name: %v\n", record.City.Names["zh-CN"])
fmt.Printf("English subdivision name: %v\n", record.Subdivisions[0].Names["en"])
fmt.Printf("Russian country name: %v\n", record.Country.Names["en"])
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)
// Output:
// Portuguese (BR) city name: Londres
// English subdivision name: England
// Russian country name: Великобритания
// ISO country code: GB
// Time zone: Europe/London
// Coordinates: 51.5142, -0.0931
}
非常简单,加载GeoLite2-City.mmdb数据库,解析ip地址,通过ipAddress loading city information.
接着,我们详细分析下geoip2-golang这个包的源码.Its source code is very simple only a file:
reader.go
调用了maxminddbData analysis packagegithub.com/oschwald/maxminddb-golang来做 数据的解析,Just do a layer on the interface encapsulation,And the corresponding geographic data format(企业、城市、国家、AnonymousIP、Domain、ISP)的定义.
比如城市信息:
// The City struct corresponds to the data in the GeoIP2/GeoLite2 City
// databases.
type City struct {
City struct {
GeoNameID uint `maxminddb:"geoname_id"`
Names map[string]string `maxminddb:"names"`
} `maxminddb:"city"`
Continent struct {
Code string `maxminddb:"code"`
GeoNameID uint `maxminddb:"geoname_id"`
Names map[string]string `maxminddb:"names"`
} `maxminddb:"continent"`
Country struct {
GeoNameID uint `maxminddb:"geoname_id"`
IsInEuropeanUnion bool `maxminddb:"is_in_european_union"`
IsoCode string `maxminddb:"iso_code"`
Names map[string]string `maxminddb:"names"`
} `maxminddb:"country"`
Location struct {
AccuracyRadius uint16 `maxminddb:"accuracy_radius"`
Latitude float64 `maxminddb:"latitude"`
Longitude float64 `maxminddb:"longitude"`
MetroCode uint `maxminddb:"metro_code"`
TimeZone string `maxminddb:"time_zone"`
} `maxminddb:"location"`
Postal struct {
Code string `maxminddb:"code"`
} `maxminddb:"postal"`
RegisteredCountry struct {
GeoNameID uint `maxminddb:"geoname_id"`
IsInEuropeanUnion bool `maxminddb:"is_in_european_union"`
IsoCode string `maxminddb:"iso_code"`
Names map[string]string `maxminddb:"names"`
} `maxminddb:"registered_country"`
RepresentedCountry struct {
GeoNameID uint `maxminddb:"geoname_id"`
IsInEuropeanUnion bool `maxminddb:"is_in_european_union"`
IsoCode string `maxminddb:"iso_code"`
Names map[string]string `maxminddb:"names"`
Type string `maxminddb:"type"`
} `maxminddb:"represented_country"`
Subdivisions []struct {
GeoNameID uint `maxminddb:"geoname_id"`
IsoCode string `maxminddb:"iso_code"`
Names map[string]string `maxminddb:"names"`
} `maxminddb:"subdivisions"`
Traits struct {
IsAnonymousProxy bool `maxminddb:"is_anonymous_proxy"`
IsSatelliteProvider bool `maxminddb:"is_satellite_provider"`
} `maxminddb:"traits"`
}
先看下open函数
func Open(file string) (*Reader, error) {
reader, err := maxminddb.Open(file)
if err != nil {
return nil, err
}
dbType, err := getDBType(reader)
return &Reader{reader, dbType}, err
}
它调用了 maxminddb.Open返回了一个Reader
type Reader struct {
mmdbReader *maxminddb.Reader
databaseType databaseType
}
Reader上定义了City,County等函数
func (r *Reader) City(ipAddress net.IP) (*City, error) {
if isCity&r.databaseType == 0 {
return nil, InvalidMethodError{"City", r.Metadata().DatabaseType}
}
var city City
err := r.mmdbReader.Lookup(ipAddress, &city)
return &city, err
}
These functions are just formmdbReader.Lookup做了简单的封装.
边栏推荐
- leetcode刷题记录:7.整数反转,8.字符串转整数,9.回文数
- LeetCode 622 设计循环队列[数组 队列] HERODING的LeetCode之路
- V - memo new instructions
- LM小型可编程控制器软件(基于CoDeSys)笔记二十五:plc的数据存储区(数字量输入通道部分)
- TPAMI2022 | TransCL: based on the study the compression of the Transformer, more flexible and more powerful
- 什么是乙二醇二乙酸酯(EGDA)?
- TPAMI2022 | TransCL:基于Transformer的压缩学习,更灵活更强大
- 顺序查找和折半查找,看这篇就够了
- 力扣每日一题-第46天-344. 反转字符串
- 银保监会:人身险产品信披材料应由保险公司总公司统一负责管理
猜你喜欢
ECCV 2022 | 通往数据高效的Transformer目标检测器
JWT学习
4KMILES加入艾盛集团,以更强劲的数字商务能力,加速中国跨境电商的全域全效增长
Leetcode刷题——字符串相加相关题目(415. 字符串相加、面试题 02.05. 链表求和、2. 两数相加)
In action: 10 ways to implement delayed tasks, with code!
Brain-computer interface 003 | Musk said that he has realized a virtual self-dialogue with the cloud, and related concept shares have risen sharply
SQL Server实现group_concat功能
2022-07-27
J9数字货币论:识别Web3新的稀缺性:开源开发者
腾讯云孟凡杰:我所经历的云原生降本增效最佳实践案例
随机推荐
「面试必会」这应该是最有深度的TCP三次握手、四次挥手细节讲解
VMware虚拟机无法上网
笑话:如果你在河边等待得足够久,你会看到你的敌人的尸体漂过,是怎么翻译出来的?
磁盘分区的知识
J9数字货币论:识别Web3新的稀缺性:开源开发者
所谓武功再高也怕菜刀-分区、分库、分表和分布式的优劣
ShardingSphere-proxy +PostgreSQL实现读写分离(静态策略)
ECCV 2022 | 通往数据高效的Transformer目标检测器
日志框架学习
Office2021 安装MathType
J9 Digital Currency Theory: Identifying Web3's New Scarcity: Open Source Developers
软考 ----- UML设计与分析(下)
【LeetCode】1161. 最大层内元素和
模板的进阶
Flutter自带国际化适配自动生成方案
golang 源码分析:juju/ratelimit
PyTorch分布式backends
OpenCV开发中的内存管理问题
Caldera(一)配置完成的虚拟机镜像及admin身份简单使用
MySQL安装时一直卡在starting server