Масштабирование блокчейн-инфраструктуры: от ноды до WebSocket
Инфраструктура, которая нормально работала при 100 пользователях, начинает сыпаться при 10 000. Специфика блокчейн-стека в том, что узкое место часто не там, где ожидаешь: не база данных, не CPU — а RPC нода, которая не успевает отдавать eth_getLogs, или indexer, который отстаёт на 50 блоков, или WebSocket handler, который дропает соединения под нагрузкой. Масштабирование блокчейн-инфраструктуры — это отдельная дисциплина с непривычными паттернами. Мы занимаемся этим более 5 лет и гарантируем, что ваша инфраструктура выдержит любую нагрузку — пишите, оценим проект бесплатно.
Почему масштабирование блокчейн-инфраструктуры — отдельная дисциплина?
В отличие от классического веба, здесь появляются точки отказа, которые не лечатся простым добавлением серверов: состояние цепочки, лимиты WebSocket, неизменяемые данные на нодах. Каждый слой требует своего подхода — от пула нод до event-driven индексации.
Диагностика: где реальное узкое место
Прежде чем что-то масштабировать — измерьте. Типичные узкие места: latency по каждому RPC методу, queue depth у indexer'а, lag между head блоком ноды и head в вашей БД, throughput WebSocket соединений. Для сбора метрик используем Prometheus и готовые дашборды — входит в объём работ.
// Инструментация RPC вызовов class InstrumentedProvider { private metrics: Map<string, number[]> = new Map(); async call(method: string, params: any[]): Promise<any> { const start = performance.now(); try { const result = await this.provider.send(method, params); this.record(method, performance.now() - start); return result; } catch (err) { this.recordError(method); throw err; } } getPercentiles(method: string) { const samples = (this.metrics.get(method) || []).sort((a, b) => a - b); return { p50: samples[Math.floor(samples.length * 0.5)], p95: samples[Math.floor(samples.length * 0.95)], p99: samples[Math.floor(samples.length * 0.99)], count: samples.length, }; } } Как масштабировать RPC слой?
Пул нод с балансировкой
Единственная нода — single point of failure и bottleneck. Минимальная production конфигурация — три ноды с health check и round-robin с пропуском нездоровых. Для stateful операций (подписки, pending transactions) — sticky routing. Код примера ниже — используем в каждом проекте.
class NodePool { private nodes: RpcNode[]; private currentIndex = 0; private healthStatus: Map<string, boolean> = new Map(); async sendRequest(method: string, params: any[]): Promise<any> { for (let i = 0; i < this.nodes.length; i++) { const node = this.nodes[this.currentIndex % this.nodes.length]; this.currentIndex++; if (!this.healthStatus.get(node.url)) continue; try { return await node.send(method, params); } catch (err) { this.healthStatus.set(node.url, false); setTimeout(() => this.healthStatus.set(node.url, true), 30_000); } } throw new Error('All nodes unhealthy'); } } Кеширование RPC ответов
Многие запросы идентичны и кешируемы: eth_chainId (24 часа), eth_getCode (1 час — код контракта не меняется), eth_getBlockByNumber для не-latest (1 минута), eth_getTransactionReceipt (5 минут после финализации). Не кешируем latest и pending. Используем Redis — это сокращает количество запросов к ноде на 80%.
const CACHEABLE_METHODS: Record<string, number> = { 'eth_chainId': 86400, 'eth_getCode': 3600, 'eth_getBlockByNumber': 60, 'eth_getTransactionReceipt': 300, }; class CachingRpcProxy { async send(method: string, params: any[]): Promise<any> { const ttl = CACHEABLE_METHODS[method]; if (!ttl) return this.upstream.send(method, params); if (params.includes('latest') || params.includes('pending')) { return this.upstream.send(method, params); } const cacheKey = `rpc:${method}:${JSON.stringify(params)}`; const cached = await this.redis.get(cacheKey); if (cached) return JSON.parse(cached); const result = await this.upstream.send(method, params); await this.redis.setex(cacheKey, ttl, JSON.stringify(result)); return result; } } Indexing: от polling к event-driven
Проблема polling
Polling каждые 5 секунд для 10 000 адресов — 2 000 запросов в секунду. Нода захлебнётся. Переходим на событийную модель через EVM logs: один getLogs на диапазон блоков заменяет тысячи отдельных запросов. Экономия — до 90% RPC-нагрузки.
The Graph для сложной индексации
Для агрегаций по пользователям, исторических данных — The Graph subgraph. Self-hosted Graph Node на PostgreSQL 14+ с достаточным I/O. Входит в типовой объём работ: настройка субграфа, деплой, мониторинг.
WebSocket: масштабирование подписок
WebSocket stateful — nginx round-robin не подходит. Используем Redis pub/sud: отдельный сервис публикует события (новый блок, транзакция) в Redis, а WS-серверы подписываются и раздают своим клиентам. Добавление ещё одного WS-сервера — единственное, что нужно для горизонтального масштабирования.
Управление нагрузкой на ноды
Request coalescing — если 100 запросов одновременно просят один ресурс, объединяем их в один RPC вызов. Multicall — один HTTP запрос вместо 100 для balanceOf. Оба паттерна снижают нагрузку на ноду в десятки раз.
| Проблема | Решение | Сложность | Экономия RPC-нагрузки |
|---|---|---|---|
| RPC нода — bottleneck | Пул нод + балансировка | Низкая | 50%+ |
| Повторяющиеся одинаковые запросы | Request coalescing + Redis cache | Низкая | 80%+ |
| 100+ адресов — мониторинг балансов | Multicall + event indexing | Средняя | 90%+ |
| WS под нагрузкой дропает соединения | Redis pub/sub backbone | Средняя | — |
| Исторические запросы медленные | Erigon/Reth archive + query optimization | Средняя | 70%+ |
| Сложная аналитика on-chain данных | The Graph subgraph | Высокая | — |
Что входит в нашу работу
- аудит текущей архитектуры с замером latency, throughput, lag;
- проектирование решения под ваш стек (Ethereum, Polygon, Arbitrum, Solana);
- реализация: пул нод, кеширование, event-driven индексация, WebSocket-шлюз;
- интеграция мониторинга (Grafana, Prometheus, алерты);
- документация и передача доступов;
- обучение команды работе с новой инфраструктурой;
- поддержка в течение месяца после запуска.
Процесс работы
- Аналитика — профилируем текущую инфраструктуру, выявляем узкие места.
- Проектирование — выбираем паттерны, готовим схему.
- Реализация — пишем код, настраиваем сервисы.
- Тестирование — нагрузочное тестирование на ваших сценариях.
- Деплой и мониторинг — запуск с наблюдением в первые дни.
Сроки ориентировочно
От 2 до 6 недель в зависимости от сложности и количества сетей. Стоимость рассчитывается индивидуально после аудита — пишите, оценим проект за 1-2 дня.
Мы работаем с Ethereum, Polygon, Arbitrum, Optimism, BNB Chain, Solana. Опыт — 10+ проектов, более 5 лет на рынке. Гарантируем качество: все решения проходят ревью и тестирование.







