El problema
Las interrupciones de la API de búsqueda son poco comunes pero catastróficas para las aplicaciones que dependen de datos web. La caída de un solo proveedor durante 30 minutos puede significar 30 minutos de servicio degradado, respuestas fallidas de los agentes o funciones de usuario rotas. La mayoría de los equipos solo descubren que necesitan conmutación por error después de su primera interrupción, momento en el que se apresuran a integrar un proveedor de respaldo bajo presión. El diseño proactivo de conmutación por error requiere un esfuerzo mínimo, pero rara vez se le da prioridad hasta que es demasiado tarde.
La solucion de Scavio
Cree una capa de búsqueda independiente del proveedor con conmutación por error automática antes de que la necesite. Defina un proveedor primario y secundario con interfaces de consulta compatibles. Enrute todas las llamadas de búsqueda a través de la capa de conmutación por error. Cuando el proveedor principal devuelve errores o excede los umbrales de latencia, la capa cambia automáticamente al secundario. Agregue comprobaciones de estado para restaurar el enrutamiento principal una vez que se recupere.
Antes
Antes: una aplicación utilizaba una única API de búsqueda. Durante una interrupción de 2 horas, fallaron todas las funciones dependientes de la búsqueda. El equipo dedicó el siguiente sprint a integrar un proveedor de respaldo, desviando recursos de la hoja de ruta del producto. Costo total de la interrupción: $15 000 en ingresos perdidos y tiempo de ingeniería.
Después
Después: una capa de conmutación por error se dirige a través de Scavio (primario) y un proveedor de respaldo (secundario). Durante la siguiente interrupción del proveedor, la conmutación por error se activó automáticamente y no se degradaron funciones de cara al usuario. El proveedor de reserva cuesta $5/mes en tráfico keepalive. La capa de conmutación por error tardó 2 horas en crearse.
Para quien es
Los equipos de SRE y los líderes de ingeniería construyen una infraestructura de búsqueda resistente. Cualquiera que haya experimentado una interrupción de la API de búsqueda y no quiera que vuelva a suceder.
Beneficios clave
- Búsqueda sin tiempo de inactividad con conmutación automática por error del proveedor
- 2 horas de construcción, evita costos de interrupción de más de $15 000
- El proveedor de reserva cuesta entre 5 y 30 dólares al mes para los controles de salud keepalive
- La recuperación basada en comprobaciones de estado restaura automáticamente el enrutamiento principal
- La interfaz independiente del proveedor significa que agregar un tercer proveedor lleva 10 minutos
Ejemplo en Python
import requests
import time
from typing import Optional
class SearchFailover:
def __init__(self, providers: list):
self.providers = providers
self.health = {p["name"]: True for p in providers}
self.last_check = {}
def search(self, query: str, platform: str = "google") -> Optional[dict]:
for provider in self.providers:
if not self.health.get(provider["name"], True):
if time.time() - self.last_check.get(provider["name"], 0) < 60:
continue # Skip unhealthy provider for 60s
try:
r = requests.post(
provider["url"],
headers={provider["header"]: provider["key"]},
json={"platform": platform, "query": query},
timeout=5,
)
if r.status_code == 200:
self.health[provider["name"]] = True
return {"provider": provider["name"], "data": r.json()}
self.health[provider["name"]] = False
self.last_check[provider["name"]] = time.time()
except Exception:
self.health[provider["name"]] = False
self.last_check[provider["name"]] = time.time()
return None
failover = SearchFailover([
{"name": "scavio", "url": "https://api.scavio.dev/api/v1/search", "header": "x-api-key", "key": "your_scavio_key"},
{"name": "backup", "url": "https://api.backup.dev/search", "header": "x-api-key", "key": "your_backup_key"},
])
result = failover.search("latest ai news 2026")
if result:
print(f"Provider: {result["provider"]}, Results: {len(result["data"].get("organic", []))}")Ejemplo en JavaScript
class SearchFailover {
constructor(providers) {
this.providers = providers;
this.health = Object.fromEntries(providers.map(p => [p.name, true]));
this.lastCheck = {};
}
async search(query, platform = "google") {
for (const provider of this.providers) {
if (!this.health[provider.name] && Date.now() - (this.lastCheck[provider.name] || 0) < 60000) continue;
try {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);
const res = await fetch(provider.url, {
method: "POST",
headers: { [provider.header]: provider.key, "content-type": "application/json" },
body: JSON.stringify({ platform, query }),
signal: controller.signal,
});
clearTimeout(timeout);
if (res.ok) { this.health[provider.name] = true; return { provider: provider.name, data: await res.json() }; }
this.health[provider.name] = false;
this.lastCheck[provider.name] = Date.now();
} catch (e) { this.health[provider.name] = false; this.lastCheck[provider.name] = Date.now(); }
}
return null;
}
}
const failover = new SearchFailover([
{ name: "scavio", url: "https://api.scavio.dev/api/v1/search", header: "x-api-key", key: "your_scavio_key" },
{ name: "backup", url: "https://api.backup.dev/search", header: "x-api-key", key: "your_backup_key" },
]);
const result = await failover.search("latest ai news 2026");
if (result) console.log(`Provider: ${result.provider}, Results: ${(result.data.organic || []).length}`);Plataformas utilizadas
Búsqueda web con grafo de conocimiento, PAA y resúmenes de IA
YouTube
Búsqueda de videos con transcripciones y metadatos
Amazon
Búsqueda de productos con precios, calificaciones y reseñas
Comunidad, publicaciones y comentarios en hilos de cualquier subreddit