Multi-source routing 2026: маршрутизация заказов между поставщиками
Production B2B-фулфилмент цифровых товаров не зависит от одного поставщика. Эксклюзивный supplier — это single point of failure: один даунтайм, и все ваши заказы fail. Правильный архитектурный паттерн — multi-source routing с автоматическим выбором лучшего варианта на каждый запрос.
1. Latency-weighted routing
Самый простой вариант — выбирать поставщика с минимальной p95 delivery latency. Хранить historical-метрики в Redis sliding window:
type SupplierStats = { p95Ms: number; failureRate: number; stock: number };
async function pickSupplier(sku: string): Promise<string> {
const candidates = await getSuppliersForSku(sku);
const stats = await Promise.all(
candidates.map(s => redis.hgetall(`sup:${s.id}:stats`))
);
const scored = candidates.map((s, i) => ({
id: s.id,
score: 1 / (parseFloat(stats[i].p95Ms) + 1),
}));
return scored.sort((a, b) => b.score - a.score)[0].id;
}
Этого достаточно для 80% сценариев. Latency-метрики обновляются каждые 30 секунд из реальных webhook-таймингов.
2. Stock-aware routing
Если у поставщика inventory < buffer (например, <50 кодов для популярного SKU) — лучше не использовать его как primary, даже если latency хорошая. Stock buffer защищает от race condition «4 одновременных заказа на 3 кода».
function isViableSupplier(s: SupplierStats, qty: number): boolean {
const buffer = Math.max(50, qty * 3); // 3x safety margin
return s.stock >= buffer && s.failureRate < 0.05;
}
FoxReload пушит inventory-snapshot каждые 60 секунд во внутренний кэш. Партнёры через GET /v1/catalog/inventory могут получать тот же снэпшот для собственного routing.
3. Cost-optimised routing
Если SLA позволяет (например, fulfilment до 5 минут — норма для B2B), оптимизируйте по wholesale-cost. Формула:
score = (1 / wholesale_cost) * sla_multiplier
where sla_multiplier = 1 if p95 < target else 0
Это даёт жёсткий SLA-гарантия + минимальный cost. На больших объёмах (>10k заказов/день) экономия 1.5–3% к marginal cost.
4. Failover и circuit breaker
Health-check pattern:
| Сигнал | Threshold | Action |
|---|---|---|
| 5xx rate за 5 мин | >5% | Mark DEGRADED |
| Timeout rate | >2% | Mark DEGRADED |
| Heartbeat fail | 3 × подряд | Mark DOWN |
| Recovery | 5 × успешных | Mark HEALTHY |
Circuit breaker pattern (Polly/resilience4j-style):
import CircuitBreaker from 'opossum';
const breaker = new CircuitBreaker(callSupplier, {
timeout: 8000,
errorThresholdPercentage: 50,
resetTimeout: 120000, // 2 min
});
breaker.fallback(() => fallbackSupplier());
При open-state 100% traffic уходит на fallback — 2 минуты cooldown, потом half-open canary check, потом recovery.
CTA
FoxReload агрегирует 40+ supplier-pool под одним API, с auto-routing и failover. Получите доступ и переведите фулфилмент на multi-source.
