Skip to content

streamdp/ip-info

Folders and files

NameName
Last commit message
Last commit date

Latest commit

fa9f230 · Mar 18, 2025

History

63 Commits
Oct 5, 2024
Jan 21, 2025
Jan 21, 2025
Nov 14, 2024
Jan 3, 2025
Jan 21, 2025
Jan 21, 2025
Nov 21, 2024
Dec 22, 2024
Jan 21, 2025
Jan 21, 2025
Sep 20, 2024
Oct 4, 2024
Feb 15, 2025
Jan 21, 2025
Mar 18, 2025
Mar 18, 2025

Repository files navigation

IP-INFO

Website ip-info.oncook.top GitHub release test

Microservice for IP-based geolocation

This microservice is a small, independent software application designed to determine the geographic location of a device based on its IP address. It achieves this by using a free public database called db-ip.com (free version provides about 77% accuracy), which contains a vast amount of information linking IP addresses to specific locations.

Key features:

  • Automatic Database Updates: The microservice regularly updates its local copy of the db-ip.com database to ensure that the location data is always accurate and up-to-date.
  • Fast Lookup: It is optimized to perform quick searches within the database, allowing it to efficiently determine the location associated with a given IP address.
  • HTTP and gRPC Support: The microservice can be accessed and interacted with using both protocols, providing flexibility in how it can be integrated into other systems or applications.
  • Rate limiting: The microservice provides per-client rate limits and sends a 429 HTTP response when the client makes requests too frequently.
  • Caching: The microservice implements caching to improve availability and reduce database load.

Usage example:

Start postgresql and ip-info containers:

$ docker-compose up -d

We are waiting for the database to be updated:

$ docker logs -f ip-info-container 
IP_INFO: 2024/09/22 16:41:44 HTTP server listening at :8080
IP_INFO: 2024/09/22 16:41:44 gRPC server listening at [::]:50051
IP_INFO: 2024/09/22 16:41:45 ip database update started
IP_INFO: 2024/09/22 16:41:45 truncate ip_to_city_one table before importing update
IP_INFO: 2024/09/22 16:41:45 droping ip_to_city_one_ip_start_gist_idx index
IP_INFO: 2024/09/22 16:41:45 import ip database updates
IP_INFO: 2024/09/22 16:43:41 creating  ip_to_city_one_ip_start_gist_idx index on ip_to_city_one table
IP_INFO: 2024/09/22 16:45:18 switching backup and working tables
IP_INFO: 2024/09/22 16:45:18 updating database config
IP_INFO: 2024/09/22 16:45:18 ip database update completed, next update through 223.2h

And we can make several test requests:

$ curl localhost:8080/ip-info?ip=8.8.8.8
{
  "error": "",
  "content": {
    "ip": "8.8.8.8",
    "continent": "NA",
    "country": "US",
    "state_prov": "California",
    "city": "Mountain View",
    "latitude": -122.085,
    "longitude": 37.4223
  }
}
$ grpcurl  -plaintext -d '{"ip": "211.27.38.98"}' 127.0.0.1:50051 IpInfo/GetIpInfo
{
  "ip": "211.27.38.98",
  "continent": "OC",
  "country": "AU",
  "stateProv": "New South Wales",
  "city": "Sydney",
  "latitude": 151.209,
  "longitude": -33.8688
}

Benchmarking (i3-7100U CPU @ 2.40GHz)

IP randomization is not supported for security reasons, the difference in tests is about 10% for cases where 1 IP is requested and when the IP is requested randomly.

$ hey -c 2 -n 10000 http://127.0.0.1:8080/ip-info?ip=8.8.8.8
  Total:        3.7542 secs
  Slowest:      0.0097 secs
  Fastest:      0.0005 secs
  Average:      0.0007 secs
  Requests/sec: 2663.6510

when redis cache used:

  Total:        2.1551 secs
  Slowest:      0.0355 secs
  Fastest:      0.0003 secs
  Average:      0.0004 secs
  Requests/sec: 4640.0855

when memory cache used:

  Total:        1.0665 secs
  Slowest:      0.0032 secs
  Fastest:      0.0001 secs
  Average:      0.0002 secs
  Requests/sec: 9376.7398
$ ghz -c 2 -n 10000 127.0.0.1:50051 --call IpInfo.GetIpInfo -d '{"ip":"8.8.8.8"}' --insecure 
  Total:        6.73 s
  Slowest:      8.95 ms
  Fastest:      0.61 ms
  Average:      1.09 ms
  Requests/sec: 1485.69

when redis cache used:

  Total:        4.40 s
  Slowest:      3.55 ms
  Fastest:      0.37 ms
  Average:      0.63 ms
  Requests/sec: 2270.86

when memory cache used:

  Total:        3.04 s
  Slowest:      2.41 ms
  Fastest:      0.19 ms
  Average:      0.37 ms
  Requests/sec: 3285.49

Rate limiting

You could choose limiter between redis_rate (redis should be present) and golimiter, using -limiter-provider flag or IP_INFO_LIMITER_PROVIDER environment variable. To enable rate limiting run ip-info microservice with the -enable-limiter flag or IP_INFO_ENABLE_LIMITER environment variable. The default rate limit value is 10 requests per second per client, you can adjust it with the -rate-limit flag or IP_INFO_RATE_LIMIT environment variable.

version: "3.4"
services:
   ip-info:
      image: streamdp/ip-info:v0.2.0
      container_name: ip-info
      environment:
         - IP_INFO_DATABASE_URL=postgresql://postgres:postgres@postgres:5432/dbip?sslmode=disable
         - IP_INFO_ENABLE_LIMITER=true
         - IP_INFO_RATE_LIMIT=15 # default 10 requests per second per client
         - IP_INFO_LIMITER_PROVIDER=redis_rate # default "golimiter"
         - REDIS_URL=redis://:qwerty@redis:6379/0
      ports:
         - "8080:8080"
         - "50051:50051"
      restart: always
   
   redis:
      image: redis
      container_name: redis
      ports:
         - "6379:6379"
      command: redis-server --save "" --maxmemory 64mb --maxmemory-policy allkeys-lfu --requirepass qwerty
      restart: always
$ docker-compose up -d

Caching

Caching in-memory with microcache library is enabled by default, to disable you need to run ip-info microservice with the -disable-cache flag or IP_INFO_DISABLE_CACHE=true environment variable. The default TTL value is 3600 seconds, you can adjust it with the -cache-ttl flag or IP_INFO_CACHE_TTL environment variable. You could choose cache provider between redis and microcache, using -cache-provider flag or IP_INFO_CACHE_PROVIDER environment variable.

version: "3.4"
services:
   ip-info:      
      environment:
         - IP_INFO_CACHE_TTL=1800 # default 3600 seconds
         - IP_INFO_CACHE_PROVIDER=redis # default "microcache"
         - REDIS_URL=redis://:qwerty@redis:6379/0

Help

You can see all available command flags when you run the application with the -h flag.

$ ./bin/app -h
ip-info is a microservice for IP location determination

Usage of ./bin/app:
  -cache-provider string
        where to store cache entries: redis, microcache (default "microcache")
  -cache-ttl int
        cache ttl in seconds (default 3600)
  -disable-cache
        disable cache
  -enable-limiter
        enable rate limiter
  -grpc-port int
        grpc server port (default 50051)
  -grpc-read-timeout int
        gRPC server read timeout (default 5000)
  -h    display help
  -http-port int
        http server port (default 8080)
  -http-read-timeout int
        http server read timeout (default 5000)
  -limiter-provider string
        what use to limit queries: redis_rate, golimiter (default "golimiter")
  -rate-limit int
        rate limit, rps per client (default 10)
  -rate-limit-ttl int
        rate limit entries ttl in seconds (default 60)
  -read-header-timeout int
        http server read header timeout (default 5000)
  -redis-db int
        redis database
  -redis-host string
        redis host (default "127.0.0.1")
  -redis-port int
        redis port (default 6379)
  -v    display version
  -write-timeout int
        http server write timeout (default 5000)

Contributing

Contributions are welcome! If you encounter any issues, have suggestions for new features, or want to improve ip-info, please feel free to open an issue or submit a pull request on the project's GitHub repository.

License

ip-info is released under the GPL 3.0 License. See the LICENSE file for complete license details.

Support project

DigitalOcean referral link.