Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

🌐 中文简体 | English

ip2region golang query client

Usage

package get

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

About the query service

Starting from version 3.11.0, a dual-protocol compatible and concurrency-safe Ip2Region query service is provided. It is recommended to prioritize this method for query calls. The specific usage is as follows:

import "github.com/lionsoul2014/ip2region/binding/golang/service"

// 1. Create v4 configuration: specify the cache policy and the v4 xdb file path
// Parameter 1: Cache policy, options: service.NoCache / service.VIndexCache / service.BufferCache
// Parameter 2: xdb file path
// Parameter 3: Number of initialized searchers
v4Config, err := service.NewV4Config(service.VIndexCache, "ip2region v4 xdb path", 20)
if err != nil {
    return fmt.Errorf("failed to create v4 config: %s", err)
}

// 2. Create v6 configuration: specify the cache policy and the v6 xdb file path
v6Config, err := service.NewV6Config(service.VIndexCache, "ip2region v6 xdb path", 20)
if err != nil {
    return fmt.Errorf("failed to create v6 config: %s", err)
}

// 3. Create the Ip2Region query service using the above configurations
ip2region, err := service.NewIp2Region(v4Config, v6Config)
if err != nil {
    return fmt.Errorf("failed to create ip2region service: %s", err)
}

// 4. Export the ip2region service for concurrent dual-version IP address queries, for example:
v4Region, err := ip2region.Search("113.92.157.29")                          // Perform IPv4 query
v6Region, err := ip2region.Search("240e:3b7:3272:d8d0:db09:c067:8d59:539e") // Perform IPv6 query


// 5. When the parent service needs to be closed, close the ip2region query service as well
ip2region.Close()
Ip2Region Query Notes:
  1. The API of this query service is concurrency-safe and supports both IPv4 and IPv6 addresses; the internal implementation handles identification automatically.
  2. v4 and v6 configurations need to be created separately. You can set different cache policies for v4 and v6, or specify one as nil, which will cause queries for that IP version to return "".
  3. Please set an appropriate number of searchers based on your project's concurrency. This value is fixed during runtime; each query borrows a searcher from the pool to complete the operation and returns it afterward. If the pool is empty during borrowing, it will wait until a searcher becomes available.
  4. If the cache policy is set to service.BufferCache (Full Memory Cache), a single-instance memory searcher is used by default. This implementation is natively concurrency-safe, and the specified number of searchers will be ignored.
  5. If Close is called while the Ip2Region service is running, it will wait up to 10 seconds by default for searchers to be returned. You can also call CloseTimeout to define a custom maximum wait time.

About the Query API

The location information query API prototypes are:

Search(string | []byte) (string, error)

If a query fails, the error will contain specific error details. If successful, it returns the region string. If the specified IP cannot be found, it returns an empty string "".

About IPv4 / IPv6

This xdb query client implementation supports both IPv4 and IPv6 queries. Usage is as follows:

// For IPv4: Set the xdb path to the v4 xdb file and specify the IP version as xdb.IPv4
dbPath := "../../data/ip2region_v4.xdb"  // Or your ipv4 xdb path
version := xdb.IPv4

// For IPv6: Set the xdb path to the v6 xdb file and specify the IP version as xdb.IPv6
dbPath = "../../data/ip2region_v6.xdb"  // Or your ipv6 xdb path
version = xdb.IPv6

// The IP version of the xdb specified by dbPath must match the version specified, otherwise the query will throw an error.
// Note: The following demonstrations directly use the dbPath and version variables.

File Verification

It is recommended to actively verify the applicability of the xdb file. New features in later versions may make the current Searcher version incompatible with your xdb file. Verification helps avoid unpredictable errors during runtime. You do not need to verify every time; for example, run it during service startup or manually via command line to confirm version matching. Do not run verification every time a Searcher is created, as this will impact query response speed, especially in high-concurrency scenarios.

err := xdb.VerifyFromFile(dbPath)
if err != nil {
	// err contains the verification error
	return fmt.Errorf("xdb file verify: %w", err)
}

// The current Searcher can safely be used for query operations on the xdb specified by dbPath.

Pure File-Based Query

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

func main() {
	// Create a pure file-based query object using version and dbPath
    searcher, err := xdb.NewWithFileOnly(version, dbPath)
    if err != nil {
        fmt.Printf("failed to create searcher: %s\n", err.Error())
        return
    }

    defer searcher.Close()

    // Location info query: both IPv4 and IPv6 addresses are supported
    var ip = "1.2.3.4"  // IPv4
	// ip = "240e:3b7:3272:d8d0:db09:c067:8d59:539e" // IPv6
    var tStart = time.Now()
    region, err := searcher.Search(ip)
    if err != nil {
        fmt.Printf("failed to Search(%s): %s\n", ip, err)
        return
    }

	// IPv4 or IPv6 location information 
    fmt.Printf("{region: %s, took: %s}\n", region, time.Since(tStart))

    // Note: For concurrent use, each goroutine needs to create an independent searcher object.
}

Caching VectorIndex

You can pre-load the vectorIndex cache and store it as a global variable. Using the global vectorIndex whenever creating a searcher reduces a fixed IO operation, accelerating queries and reducing system IO pressure.

// 1. Load VectorIndex cache from dbPath and store the vIndex variable globally in memory.
vIndex, err := xdb.LoadVectorIndexFromFile(dbPath)
if err != nil {
    fmt.Printf("failed to load vector index from `%s`: %s\n", dbPath, err)
    return
}

// 2. Create a query object with VectorIndex cache using the global vIndex.
searcher, err := xdb.NewWithVectorIndex(version, dbPath, vIndex)
if err != nil {
    fmt.Printf("failed to create searcher with vector index: %s\n", err)
    return
}

// Note: For concurrent use, all goroutines share the global read-only vIndex cache, while each goroutine creates an independent searcher object.

Caching the entire xdb file

You can pre-load the entire xdb file into memory for full memory-based queries, similar to the previous memory search.

// 1. Load the entire xdb from dbPath into memory
cBuff, err := xdb.LoadContentFromFile(dbPath)
if err != nil {
    fmt.Printf("failed to load content from `%s`: %s\n", dbPath, err)
    return
}

// 2. Create a fully memory-based query object using the global cBuff.
searcher, err := xdb.NewWithBuffer(version, cBuff)
if err != nil {
    fmt.Printf("failed to create searcher with content: %s\n", err)
    return
}

// Note: For concurrent use, searcher objects created with the entire xdb cache can be safely used for concurrency.

Compile the test program

Compile to get the xdb_searcher executable through the following method:

# cd to the golang binding root directory first
make

Query test

Query command

Test xdb queries using the ./xdb_searcher search command:

➜  golang git:(master) ✗ ./xdb_searcher search --help
./xdb_searcher search [command options]
options:
 --v4-db string            ip2region v4 binary xdb file path
 --v4-cache-policy string  v4 cache policy, default vectorIndex, options: file/vectorIndex/content
 --v6-db string            ip2region v6 binary xdb file path
 --v6-cache-policy string  v6 cache policy, default vectorIndex, options: file/vectorIndex/content
 --help                    print this help menu

Parameter parsing

  1. v4-xdb: IPv4 xdb file path, defaults to data/ip2region_v4.xdb in the repository
  2. v6-xdb: IPv6 xdb file path, defaults to data/ip2region_v6.xdb in the repository
  3. v4-cache-policy: Cache policy used for v4 queries, defaults to vectorIndex, options: file/vectorIndex/content
  4. v6-cache-policy: Cache policy used for v6 queries, defaults to vectorIndex, options: file/vectorIndex/content

Test Demo

Example: Perform query tests using the default data/ip2region_v4.xdb and data/ip2region_v6.xdb:

➜  golang git:(master) ✗ ./xdb_searcher search       
ip2region search service test program
+-v4 db: /data01/code/c/ip2region/data/ip2region_v4.xdb (vectorIndex)
+-v6 db: /data01/code/c/ip2region/data/ip2region_v6.xdb (vectorIndex)
type 'quit' to exit
ip2region>> 1.2.3.4
{region: Australia|Queensland|Brisbane|0|AU, took: 50.216µs}
ip2region>> 240e:3b7:3272:d8d0:db09:c067:8d59:539e
{region: 中国|广东省|深圳市|电信|CN, took: 100.606µs}
ip2region>> 2604:a840:3::a04d
{region: United States|California|San Jose|xTom|US, took: 99.078µs}

Enter an IPv4 or IPv6 address to perform query tests. You can also set cache-policy to file/vectorIndex/content respectively to test the performance of the three different cache implementations.

bench test

Test command

Perform automatic bench testing using the xdb_searcher bench command. This ensures that both the program and the xdb file are free of errors, and provides average query performance through a large number of queries:

➜  golang git:(fr_xdb_ipv6) ./xdb_searcher bench
./xdb_searcher bench [command options]
options:
 --db string              ip2region binary xdb file path
 --src string             source ip text file path
 --cache-policy string    cache policy: file/vectorIndex/content

v4 bench

Example: Perform ipv4 bench testing using data/ip2region_v4.xdb and data/ipv4_source.txt:

./xdb_searcher bench --db=../../data/ip2region_v4.xdb --src=../../data/ipv4_source.txt 

v6 bench

Example: Perform ipv6 bench testing using data/ip2region_v6.xdb and data/ipv6_source.txt:

./xdb_searcher bench --db=../../data/ip2region_v6.xdb --src=../../data/ipv6_source.txt 

You can set the cache-policy parameter to test the efficiency of file/vectorIndex/content cache mechanisms respectively.

Please note that the src file used for bench needs to be the same source file used to generate the corresponding xdb file.

The bench program will read the source IP file specified by src line by line, then select the start and end IPs from each IP segment for testing to ensure that the queried region information matches the original region information. There is no debug information output during the test; if an error occurs, the error message will be printed and execution will terminate. Seeing Bench finished indicates the bench was successful. Cost represents the average time for each query operation (ns).