package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"sync"
"time"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
type Address struct {
ID int64 `db:"id"`
IP string `db:"ip"`
City string `db:"city"`
Region string `db:"region"`
Country string `db:"country"`
}
func (a *Address) TableName() string {
return "address"
}
const (
dbUser = "root"
dbPasswd = "123456"
dbHost = "localhost"
dbPort = 3306
dbName = "go_test"
)
var db *sqlx.DB
func init() {
var err error
db, err = sqlx.Connect("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4,utf8", dbUser, dbPasswd, dbHost, dbPort, dbName))
if nil != err {
log.Fatalln(err)
}
}
func main() {
testHTTPResp()
processIP()
}
func processIP() {
var totalCount int64
err := db.Get(&totalCount, "SELECT COUNT(*) FROM address;")
if nil != err {
log.Fatalln(err)
os.Exit(1)
}
var pageSize int64
var offset int64
pageSize = 500
var wg sync.WaitGroup
for offset = 0; offset <= totalCount; offset += pageSize {
dataList := []Address{}
sql := fmt.Sprintf("SELECT id, ip FROM address ORDER BY id ASC LIMIT %d, %d;", offset, pageSize)
err = db.Select(&dataList, sql)
if nil != err {
log.Fatalln(err)
os.Exit(1)
}
wg.Add(len(dataList))
for _, item := range dataList {
go func(ip string, id int64) {
defer wg.Done()
if ip != "" {
var data HTTPResp
err = sendHTTPRequest(ip, &data)
if err == nil {
sql := fmt.Sprintf("UPDATE address SET city = '%s', region = '%s', country = '%s' WHERE id = %d;", data.City, data.Region, data.CountryName, id)
db.MustExec(sql)
}
}
}(item.IP, item.ID)
}
wg.Wait()
}
}
type HTTPResp struct {
City string `json:"city"`
Region string `json:"region"`
CountryName string `json:"country_name"`
}
func sendHTTPRequest(ip string, data *HTTPResp) error {
req, _ := http.NewRequest("GET", fmt.Sprintf("https://ipapi.co/%s/json/", ip), nil)
client := http.Client{
Timeout: 10 * time.Second,
}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
err = json.NewDecoder(resp.Body).Decode(&data)
if err != nil {
return err
}
return nil
}
func testHTTPResp() {
var data HTTPResp
err := sendHTTPRequest("112.24.40.51", &data)
if err != nil {
fmt.Println(err.Error())
}
fmt.Printf("test\ncity: %s, region: %s, country_name: %s\n", data.City, data.Region, data.CountryName)
}
go build -o ./getIPDetail ./main.go
./getIPDetail