Когда я начинал писать Node.js-сервис, который должен был интегрироваться с LLM-моделью, я уже понимал, что доступ к некоторым зарубежным API из России может быть проблемой. Именно поэтому моим первоначальным выбором была модель от Yandex Cloud — Yandex GPT.

Но после того как я и мои товарищи немного пообщались с ней, стало ясно, что Yandex GPT нам не подходит. Её ответы были слишком неестественными, «нечеловеческими» — особенно это было заметно в нашем конкретном кейсе. Поэтому пришлось искать альтернативу среди зарубежных моделей. Вариант обучать собственную модель отпал сразу — опыта у меня в этом не было, а искать кого-то, кто сможет это сделать, не было времени, так как хотелось быстро запустить. Так выбор пал на Gemini API от Google, о котором было много позитивных отзывов.

Однако это означало, что нужно было как-то решить проблему доступа из России, ведь мой сервис размещён именно в Yandex Cloud.

Переносить всё на зарубежные серверы? Не хотелось совсем...

Было понятно сразу, что Gemini не даст доступ моему сервису из России, я слегка начал фрустрировать. У меня уже была работающая инфраструктура в Yandex Cloud, а времени до релиза оставалось совсем немного. Понимание того, что придётся переносить сервис или хотя бы разворачивать где-то дополнительный сервер, устанавливать окружение, настраивать деплой и разбираться с новой инфраструктурой, совсем не добавляло оптимизма.

Вдобавок я прекрасно осознавал, что любая миграция — это не просто перенос кода. Это еще и:

  • потенциальные ошибки при разворачивании,

  • необходимость перестраивать CI/CD,

  • дополнительный мониторинг нового сервера.

Чем больше я думал об этом, тем менее привлекательно это выглядело. И главное — на всё это просто не хватало времени, потому что сроки уже поджимали.

И вот, когда я уже почти начал мириться с неизбежностью миграции, мне в голову пришла совершенно другая мысль: а почему вообще нужно переносить инфраструктуру? Ведь проблема только в доступе к API, а значит, её можно решить и другим способом — например, через VPN-прокси прямо из Node.js-сервиса.

Node.js + VPN — а так можно было?

Вряд ли я первый, кто столкнулся с такой проблемой, поэтому я почти сразу начал искать подходящее решение в сторону VPN или прокси. И тут всё оказалось намного проще, чем я ожидал.

Моё приложение написано на Node.js, и первоначально я использовал стандартный встроенный fetch, который появился в последних версиях Node.js и избавляет от необходимости устанавливать внешние пакеты. Я задался вопросом: а можно ли заставить этот стандартный fetch отправлять запросы через VPN-прокси?

Он не позволял, но я нашел внешний пакет node-fetch, который гарантированно умеет работать с пакетом socks-proxy-agent.

Минимальный рабочий пример:

import fetch from 'node-fetch';
import { SocksProxyAgent } from 'socks-proxy-agent';

const proxy = 'socks5h://логин:пароль@адрес_вашего_прокси:порт';
const agent = new SocksProxyAgent(proxy);

const response = await fetch('https://generativelanguage.googleapis.com/v1beta/models/...', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ /* ваши данные */ }),
  agent,
});

const data = await response.json();
console.log(data);

Это сработало сразу же и без каких-либо дополнительных настроек.

Как я быстро поднял свой VPN-прокси

Я не хотел тратить время на сложные конфигурации и нашел простое решение — Amnezia VPN. Это бесплатный и опенсорсный инструмент, который позволяет буквально за несколько команд развернуть свой собственный VPN-сервер (например, на виртуалке в Hetzner или DigitalOcean).

За полчаса я сделал следующее:

  1. Взял минимальный VPS на зарубежном хостинге.

  2. Развернул на нём сервер Amnezia одной командой.

  3. Получил готовый SOCKS5-прокси с IP-адресом в «разрешённом» регионе.

Gemini начал отвечать сразу же, как только я подставил этот прокси в свой код.

Итого — вместо полной миграции инфраструктуры я получил полностью рабочее решение буквально за полчаса.

Но что, если VPN вдруг упадёт?

Решение получилось простое и элегантное, но возник следующий вопрос: а что если VPN-сервер упадёт? Или прокси будет заблокирован Google или самим Яндексом?

Ведь зависимость от одного единственного VPN-прокси делает всю систему ненадёжной.

Я быстро понял, что нужно добавить поддержку нескольких прокси с автоматическим переключением между ними при сбоях.

Именно так я и сделал.

Поддержка нескольких прокси и автоматическое переключение

Чтобы избежать зависимости от одного прокси и повысить отказоустойчивость, я решил реализовать простой механизм резервирования. Идея простая:

  • Сервис принимает список прокси.

  • Если основной прокси недоступен (возвращает ошибку или таймаут), сервис автоматически пробует следующий из списка.

  • И так до тех пор, пока не найдётся рабочий прокси или список не закончится.

Это позволило не беспокоиться о том, что VPN-сервер может внезапно упасть или попасть в бан.

NPM-пакет для всех желающих: fetch-retry-proxy

Когда я закончил с реализацией этого механизма, подумал, что наверняка не один я сталкивался с такой задачей. Чтобы другие разработчики могли быстро решить аналогичную проблему, я вынес весь этот функционал в отдельный npm-модуль:

? fetch-retry-proxy
? GitHub репозиторий с исходниками и тестами

Теперь каждый может подключить его буквально одной командой:

npm install fetch-retry-proxy

И использовать вот так:

import fetchRetryProxy from 'fetch-retry-proxy';

const proxies = [
  'socks5h://proxy1:port',
  'socks5h://proxy2:port',
  'socks5h://proxy3:port',
];

const response = await fetchRetryProxy('https://generativelanguage.googleapis.com/...', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ /* данные */ }),
}, proxies);

const data = await response.json();
console.log(data);

Таким образом, всего за несколько минут можно получить надёжное решение с автоматическим переключением между несколькими прокси-серверами.

На GitHub я также выложил исходники и тесты, чтобы было легко разобраться, как это работает, или предложить улучшения.

Итог: Всё оказалось проще, чем казалось

В итоге вместо миграции всей инфраструктуры в другую страну я получил простое и удобное решение:

  • Сервис продолжает работать в Yandex Cloud.

  • Доступ к Gemini API стабилен и защищён от перебоев.

  • Другие разработчики могут воспользоваться готовым npm-пакетом и сэкономить время.

Надеюсь, мой опыт поможет вам сэкономить нервы и время. А вы сталкивались с подобными ситуациями? Делитесь в комментариях!

P.S.

Выкатив npm-модуль я воспользовался Codex и перевел Readme на английский.

Комментарии (10)


  1. un1t
    11.07.2025 12:11

    Vpn тут не нужен же, можно просто прокси развернуть.

    Амнезия умеет работать как сокс прокси?


    1. sssrgei Автор
      11.07.2025 12:11

      Да, умеет


    1. Kassiy_Pontiy_Pilat
      11.07.2025 12:11

      Socks прокси тоже уже режут на известные адреса хостеров. На мтс сейчас ни socks ни shadowsocks и даже в последнее время vless толком не работает если адрес прокси не в россии


      1. sssrgei Автор
        11.07.2025 12:11

        Это же серверный код, вряд ли МТС как-то влияет на сервера яндекс, не через мобильную же дата центр подключен.


        1. Kassiy_Pontiy_Pilat
          11.07.2025 12:11

          Я просто пример привёл. У разных провайдеров даже в разных регионах все по-разному. Но вероятность , что гайки закрутят постепенно везде высокая. Поэтому амнезия хороший выбор


          1. sssrgei Автор
            11.07.2025 12:11

            Согласен, что стратегически это не годится, как продакшн решение, но чтобы по быстрому протестировать гипотезу, вполне.


  1. AnaSergeeva
    11.07.2025 12:11

    а как-то обрабатывается ситуация, когда к примеру все прокси разом легли или список закончился? Есть какой-то фоллбэк или сервис упадет с ошибкой?


    1. sssrgei Автор
      11.07.2025 12:11

      Сервис не упадет, а у функции выскочит исключение, которое сервис должен обработать.


  1. Jacov911
    11.07.2025 12:11

    Был уверен что прочитаю, как вы написали "прослойку" для api и развернули на том же google cloud, куда стучитесь за gemini, это было бы логичнее, как мне кажется


    1. sssrgei Автор
      11.07.2025 12:11

      Я не очень знаком с инфраструктурой Google Cloud, был один пет проект давно и немного забыл все, за 30 минут не поднял бы точно, а сервера на амнезии у меня давно используются для других нужд, поэтому мне было просто по клику получить новые креды и подключиться. Если бы я мог использовать гугл клауд, мне бы и не надо было стучаться из яндекс клауда, но там все по другому, вплоть до бд (firebase vs ydb). Если гипотеза выстрелит, то можно будет подумать над более целевым решением, может и без gemini, альтернативы есть.