Уявіть: інтернет-магазин показує ціну в євро українському користувачеві — і він іде до конкурента. Або сайт блокує контент для регіону, де він легальний. Неправильне визначення регіону призводить до втрати до 30% конверсії. GeoIP вирішує ці завдання, але лише за умови правильного налаштування. Визначення регіону за IP — фундамент для персоналізації контенту, регіонального ціноутворення та аналітики. Завдання виглядає простим, але в деталях багато нюансів: точність баз даних, IPv6, проксі та VPN, кешування, оновлення даних. Ми використовуємо перевірені рішення, які вже показали себе в продакшені на сотнях проєктів. Інтеграція окупається за рахунок зростання виручки. Ми не просто встановлюємо базу — ми налаштовуємо повний конвеєр: від отримання реального IP за балансувальником до кешування результатів. Нижче — як це працює на практиці, з конкретними конфігами та кодом.
Порівняння баз GeoIP
| База | Ціна | Точність (міста РФ) | Затримка | Оновлення | Окупність |
|---|---|---|---|---|---|
| MaxMind GeoLite2 | Безкоштовно | ~80% | <0.1 мс | Щотижня | Окупається зростанням конверсії |
| MaxMind GeoIP2 City | Платно | ~85-90% | <0.1 мс | Щотижня | Окупається при регіональних цінах |
| ip-api.com | Безкоштовно (45 запр/хв) | ~75% | 50-200 мс | У реальному часі | Не окупається через затримки |
Локальна база MaxMind GeoLite2 у 10 разів швидша за HTTP-API і не залежить від зовнішніх сервісів. Для e-commerce з регіональними цінами GeoIP2 City виправдовує витрати.
Чому локальна база швидша за API?
HTTP-запит до ip-api.com займає 50–200 мс — при тисячах відвідувачів це дає відчутну затримку на кожній відповіді. Локальна MMDB-база читається за <0.1 мс, не створює мережевих викликів і працює навіть при тимчасових проблемах із зовнішнім API. У підсумку ви знижуєте TTFB і покращуєте Core Web Vitals.
Встановлення бази GeoIP
apt-get install geoipupdate
# Редактируем /etc/GeoIP.conf с вашими AccountID и LicenseKey
geoipupdate
# Добавляем в crontab: 0 3 * * 3 /usr/bin/geoipupdate
Інтеграція в PHP (Laravel)
Клас-сервіс для роботи з базою, кешуванням та визначенням приватних IP:
// app/Services/GeoIpService.php
use GeoIp2\Database\Reader;
use GeoIp2\Exception\AddressNotFoundException;
use Illuminate\Support\Facades\Cache;
class GeoIpService
{
private Reader $reader;
public function __construct()
{
$this->reader = new Reader(config('geoip.database_path'));
}
public function lookup(string $ip): array
{
if ($this->isPrivateIp($ip)) {
return $this->defaultResult();
}
try {
$record = $this->reader->city($ip);
return [
'country_code' => $record->country->isoCode,
'country_name' => $record->country->name,
'region_code' => $record->subdivisions[0]?->isoCode,
'region_name' => $record->subdivisions[0]?->name,
'city' => $record->city->name,
'latitude' => $record->location->latitude,
'longitude' => $record->location->longitude,
'timezone' => $record->location->timeZone,
'is_vpn' => false,
];
} catch (AddressNotFoundException) {
return $this->defaultResult();
}
}
public function lookupCached(string $ip): array
{
return Cache::remember(
"geoip:{$ip}",
86400, // 24 години
fn() => $this->lookup($ip)
);
}
private function isPrivateIp(string $ip): bool
{
if (str_starts_with($ip, '::1') || str_starts_with($ip, 'fc') || str_starts_with($ip, 'fd')) {
return true;
}
return filter_var($ip, FILTER_VALIDATE_IP,
FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false;
}
private function defaultResult(): array
{
return [
'country_code' => config('geoip.default_country'),
'region_name' => null,
'city' => null,
'timezone' => config('app.timezone'),
];
}
}
Middleware для визначення регіону та збереження в сесії:
// app/Http/Middleware/DetectUserRegion.php
public function handle(Request $request, Closure $next): Response
{
if (!$request->session()->has('geo')) {
$ip = app(GeoIpService::class)->getClientIp($request);
$geo = app(GeoIpService::class)->lookupCached($ip);
$request->session()->put('geo', $geo);
}
View::share('userGeo', $request->session()->get('geo'));
return $next($request);
}
Як налаштувати кешування для високого навантаження?
Для сайтів із тисячами унікальних IP на годину ми використовуємо Redis з TTL 24 години. Кеш за IP скорочує кількість звернень до бази в десятки разів. У наведеному класі метод lookupCached робить це автоматично. На звичайних проєктах достатньо зберегти результат у сесії при першому візиті.
Налаштування реального IP за проксі
Nginx та Cloudflare передають оригінальний IP через заголовки. Довіряємо лише відомим діапазонам, наприклад, у Laravel 11 налаштуйте довірені проксі в bootstrap/app.php, вказавши діапазони 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16. Для Cloudflare обробляємо окремо заголовок CF-Connecting-IP.
Підтримка IPv6
MaxMind GeoLite2 підтримує IPv6. У PHP потрібно доповнити перевірку приватних адрес: код уже включено в метод isPrivateIp вище.
Типові помилки при інтеграції GeoIP
- Ігнорування приватних IP — запит до бази за адресами з локальних мереж поверне помилку. Перевіряйте через
isPrivateIp. - Відсутність кешу — при високому навантаженні кожен запит буде читати MMDB-файл, що збільшить час відповіді. Кеш у Redis знижує навантаження в десятки разів.
- Неправильна обробка проксі — якщо не налаштувати довірені проксі, реальний IP буде визначено некоректно, що зведе нанівець всю персоналізацію.
Процес роботи та вартість
| Етап | Що робимо | Результат |
|---|---|---|
| Аналітика | Вивчаємо інфраструктуру, проксі, вимоги до точності | Вибір бази та стратегії |
| Встановлення | Встановлюємо базу, налаштовуємо оновлення, код сервісу | Робочий GeoIP-модуль |
| Інтеграція | Middleware, кешування, обробка проксі | Автоматичне визначення регіону |
| Тестування | Перевірка на реальних IP, VPN, IPv6 | Звіт про точність |
| Документація | Опис експлуатації, підтримки | Готовий регламент |
Що входить у роботу
- Вибір бази даних — аналіз навантаження та вимог до точності, рекомендація GeoLite2 або GeoIP2 City.
- Встановлення та налаштування — розгортання бази, налаштування автоматичного оновлення.
- Розробка модуля — сервіс-клас, middleware, кешування.
- Обробка проксі — конфігурація довірених проксі для Nginx/Cloudflare.
- Тестування — перевірка на реальних IP, включаючи IPv6 та VPN.
- Документація — опис експлуатації та інструкція для підтримки.
Терміни реалізації — від 2 до 5 робочих днів залежно від складності інфраструктури. Вартість розраховується індивідуально після аналізу поточної архітектури. Зв'яжіться з нами для консультації — оцінимо ваш проєкт і запропонуємо оптимальне рішення. Замовте інтеграцію GeoIP під ключ — отримайте готове рішення з документацією та підтримкою. Гарантуємо точність та продуктивність.







