Масштабування блокчейн-інфраструктури: від ноди до 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/sub: окремий сервіс публікує події (новий блок, транзакція) в 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 років на ринку. Гарантуємо якість: всі рішення проходять рев'ю та тестування.







