{"id":17036,"date":"2025-04-17T08:48:18","date_gmt":"2025-04-17T15:48:18","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=17036"},"modified":"2025-06-13T22:04:18","modified_gmt":"2025-06-14T05:04:18","slug":"high-availability-automatic-failover-app-services","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/high-availability-automatic-failover-app-services\/","title":{"rendered":"Alta disponibilidad con conmutaci\u00f3n por error autom\u00e1tica para App Services"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">En las aplicaciones modernas, la conectividad continua es clave, especialmente para las aplicaciones m\u00f3viles que dependen de servicios backend. En este blog, veremos una soluci\u00f3n basada en Python que supervisa el estado de los servidores de servicios de aplicaciones y, si es necesario, conmuta autom\u00e1ticamente a un servidor secundario. Este c\u00f3digo de ejemplo utiliza comprobaciones de estado HTTP y puntos finales de conexi\u00f3n WebSocket para garantizar que la aplicaci\u00f3n siempre se conecte a un servicio en buen estado.<\/span><\/p>\n<h2>Visi\u00f3n general<\/h2>\n<p><span style=\"font-weight: 400;\">La soluci\u00f3n implica dos tipos de puntos finales:<\/span><\/p>\n<ol>\n<li style=\"list-style-type: none;\">\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>URL de chequeo<\/b>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Estos puntos finales (por ejemplo <\/span><span style=\"font-weight: 400;\"><code>https:\/\/...\/_ping<\/code><\/span><span style=\"font-weight: 400;\">) se sondean mediante <em>HTTP <\/em><\/span><em><span style=\"font-weight: 400;\">CABEZA<\/span><\/em><span style=\"font-weight: 400;\"> peticiones.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Determinan si el servidor de servicios de aplicaciones est\u00e1 en buen estado.<\/span><\/li>\n<\/ul>\n<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Puntos finales de conexi\u00f3n<\/b>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Se trata de las direcciones URL de WebSocket (p. ej, <\/span><span style=\"font-weight: 400;\"><code>wss:\/\/...\/primary<\/code><\/span><span style=\"font-weight: 400;\">) que tu aplicaci\u00f3n utiliza para interactuar con el backend.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">El punto final de conexi\u00f3n activo se actualiza en funci\u00f3n de los resultados de la comprobaci\u00f3n de estado.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">Si la comprobaci\u00f3n de estado del servidor primario falla consecutivamente, la l\u00f3gica de conmutaci\u00f3n por error cambiar\u00e1 la conexi\u00f3n de la aplicaci\u00f3n al servidor secundario.<\/span><\/p>\n<h2>El c\u00f3digo en detalle<\/h2>\n<p><span style=\"font-weight: 400;\">A continuaci\u00f3n se muestra el c\u00f3digo completo con comentarios en l\u00ednea y explicaciones detalladas:<\/span><\/p>\n<pre class=\"nums:false lang:python decode:true\">import logging\r\nimport threading\r\nimport requests\r\nfrom time import sleep\r\n\r\n# Configure logging to show time-stamped messages at INFO level.\r\nlogging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s: %(message)s')\r\n\r\n# --------------------------------------\r\n# Health Check URLs (App Service Servers)\r\n# --------------------------------------\r\n# These URLs are used for health checking the servers by sending HEAD requests.\r\nhealth_check_urls = {\r\n\u00a0\u00a0\u00a0\u00a0\"primary\": \"https:\/\/XXXXXXXXXXXXXX.apps.cloud.couchbase.com:4984\/_ping\",\r\n\u00a0\u00a0\u00a0\u00a0\"secondary\": \"https:\/\/XXXXXXXXXXXXXX.apps.cloud.couchbase.com:4984\/_ping\"\r\n}\r\n\r\n# -------------------------------------\r\n# Connection Endpoints (WebSocket URLs)\r\n# -------------------------------------\r\n# These endpoints are what your application actually uses for connections.\r\nconnection_urls = {\r\n\u00a0\u00a0\u00a0\u00a0\"primary\": \"wss:\/\/XXXXXXXXXXXXXX.apps.cloud.couchbase.com:4984\/primary\",\r\n\u00a0\u00a0\u00a0\u00a0\"secondary\": \"wss:\/\/XXXXXXXXXXXXXX.apps.cloud.ucouchbase.com:4984\/secondary\"\r\n}\r\n\r\n# The variable `active_cluster` tracks which server is currently active.\r\nactive_cluster = \"primary\"\r\n\r\n# This variable holds the actual WebSocket URL used by your application.\r\nactive_connection_url = connection_urls[active_cluster]\r\n\r\ndef is_cluster_healthy(url):\r\n\u00a0\u00a0\u00a0\u00a0\"\"\"\r\n\u00a0\u00a0\u00a0\u00a0Perform a health check using a HEAD request against the provided URL.\r\n\u00a0\u00a0\u00a0\u00a0Returns True if the response status is 200; otherwise, returns False.\r\n\u00a0\u00a0\u00a0\u00a0Logs the status code and headers for troubleshooting.\r\n\u00a0\u00a0\u00a0\u00a0\"\"\"\r\n\u00a0\u00a0\u00a0\u00a0try:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0response = requests.head(url, timeout=5)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.info(f\"Health Check Response for {url}\")\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.info(f\"\u00a0 Status Code: {response.status_code}\")\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.info(\"\u00a0 Headers:\")\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0for header, value in response.headers.items():\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.info(f\"\u00a0 \u00a0 {header}: {value}\")\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if response.status_code == 200:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.info(f\"{url} is healthy!\")\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return True\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.warning(f\"{url} might be unhealthy or unreachable.\")\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return False\r\n\u00a0\u00a0\u00a0\u00a0except requests.exceptions.RequestException as e:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.error(f\"Health check failed for {url}: {e}\")\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return False\r\n\r\ndef health_check_worker():\r\n\u00a0\u00a0\u00a0\u00a0\"\"\"\r\n\u00a0\u00a0\u00a0\u00a0A background worker that checks the health of the active server every 3 seconds.\r\n\u00a0\u00a0\u00a0\u00a0If the active server fails health checks for more than 9 consecutive times,\r\n\u00a0\u00a0\u00a0\u00a0the worker attempts to switch to the other server.\r\n\u00a0\u00a0\u00a0\u00a0\"\"\"\r\n\u00a0\u00a0\u00a0\u00a0global active_cluster\r\n\u00a0\u00a0\u00a0\u00a0global active_connection_url\r\n\r\n\u00a0\u00a0\u00a0\u00a0consecutive_failures = 0\r\n\r\n\u00a0\u00a0\u00a0\u00a0while True:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sleep(3)\u00a0 # Wait 3 seconds between checks.\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# Use the HTTP health check endpoint for the active cluster.\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0current_health_url = health_check_urls[active_cluster]\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.info(f\"Health check: Checking {active_cluster} at {current_health_url}...\")\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if is_cluster_healthy(current_health_url):\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0consecutive_failures = 0\u00a0 # Reset counter if healthy.\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0consecutive_failures += 1\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.warning(f\"{active_cluster} health check failed {consecutive_failures} time(s).\")\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# If failures exceed 9 consecutive attempts, try to fail over.\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if consecutive_failures &gt; 9:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.error(f\"{active_cluster} is considered down. Attempting to fail over...\")\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# Determine the new active cluster.\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new_cluster = \"secondary\" if active_cluster == \"primary\" else \"primary\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new_health_url = health_check_urls[new_cluster]\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# Check if the new cluster is healthy.\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if is_cluster_healthy(new_health_url):\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0active_cluster = new_cluster\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0# Update the connection endpoint.\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0active_connection_url = connection_urls[new_cluster]\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.warning(f\"Switched active cluster to {new_cluster}.\")\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.warning(f\"New WebSocket connection endpoint: {active_connection_url}\")\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.critical(\"Both clusters appear to be down!\")\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0consecutive_failures = 0\u00a0 # Reset the failure counter after the attempt.\r\n\r\ndef main():\r\n\u00a0\u00a0\u00a0\u00a0\"\"\"\r\n\u00a0\u00a0\u00a0\u00a0Main function to start the health-check worker in a background thread.\r\n\u00a0\u00a0\u00a0\u00a0Keeps the script running indefinitely until interrupted.\r\n\u00a0\u00a0\u00a0\u00a0\"\"\"\r\n\u00a0\u00a0\u00a0\u00a0thread = threading.Thread(target=health_check_worker, daemon=True)\r\n\u00a0\u00a0\u00a0\u00a0thread.start()\r\n\r\n\u00a0\u00a0\u00a0\u00a0logging.info(\"Health check worker started. Press Ctrl+C to exit.\")\r\n\u00a0\u00a0\u00a0\u00a0logging.info(f\"Application will initially connect to: {active_connection_url}\")\r\n\r\n\u00a0\u00a0\u00a0\u00a0try:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0while True:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sleep(1)\u00a0 # Main thread remains alive.\r\n\u00a0\u00a0\u00a0\u00a0except KeyboardInterrupt:\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0logging.info(\"Shutting down health check script.\")\r\n\r\nif __name__ == \"__main__\":\r\n\u00a0\u00a0\u00a0\u00a0main()<\/pre>\n<h2>Puntos t\u00e9cnicos clave<\/h2>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Comprobaciones de estado de los servidores App Service:<\/b><b><br \/>\n<\/b><span style=\"font-weight: 400;\">El c\u00f3digo separa el <\/span><b>puntos finales del chequeo<\/b><span style=\"font-weight: 400;\"> (utilizado para la supervisi\u00f3n) del <\/span><b>puntos finales de conexi\u00f3n<\/b><span style=\"font-weight: 400;\"> (utilizado por su aplicaci\u00f3n). Esto le permite comprobar el estado del servidor de forma independiente mientras mantiene un punto final de conexi\u00f3n estable.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Solicitudes HTTP HEAD:<\/b><b><br \/>\n<\/b><span style=\"font-weight: 400;\">Utilizando <\/span><span style=\"font-weight: 400;\">CABEZA<\/span><span style=\"font-weight: 400;\"> solicitudes a la<\/span><span style=\"font-weight: 400;\"><code>\/_ping<\/code><\/span><span style=\"font-weight: 400;\">\u00a0minimiza la transferencia de datos al tiempo que proporciona c\u00f3digos de estado y cabeceras para el diagn\u00f3stico.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Hilo de fondo:<\/b><b><br \/>\n<\/b><span style=\"font-weight: 400;\">En <\/span><span style=\"font-weight: 400;\"><code>chequeo_trabajador<\/code><\/span><span style=\"font-weight: 400;\"> se ejecuta en su propio subproceso, lo que permite una supervisi\u00f3n continua sin bloquear el subproceso principal de la aplicaci\u00f3n.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>L\u00f3gica de conmutaci\u00f3n por error:<\/b>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Un contador (<\/span><span style=\"font-weight: 400;\"><code>fracasos_consecutivos<\/code><\/span><span style=\"font-weight: 400;\">) realiza un seguimiento de los fallos consecutivos.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Si el recuento supera un umbral establecido (9 fallos), el script intenta una conmutaci\u00f3n por error comprobando el estado del servidor alternativo.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"2\"><span style=\"font-weight: 400;\">Tras una comprobaci\u00f3n de estado satisfactoria en el servidor secundario, se actualiza el punto final de conexi\u00f3n activo.<\/span><\/li>\n<\/ul>\n<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Registro:<\/b><b><br \/>\n<\/b><span style=\"font-weight: 400;\">El registro detallado proporciona informaci\u00f3n sobre el proceso de comprobaci\u00f3n de estado, incluidos el estado de respuesta HTTP, las cabeceras y los eventos de conmutaci\u00f3n por error. Esto facilita la resoluci\u00f3n de problemas y la supervisi\u00f3n.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>Adaptaci\u00f3n a su aplicaci\u00f3n<\/h2>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Puedes traducir y adaptar f\u00e1cilmente este c\u00f3digo a tu lenguaje de programaci\u00f3n preferido, como Swift y Kotlin, para adaptarlo a las necesidades de tu aplicaci\u00f3n.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Puede integrar esta secuencia de comandos o l\u00f3gica en su <\/span><b>c\u00f3digo m\u00f3vil<\/b><span style=\"font-weight: 400;\"> (iOS\/Android) o un <\/span><b>servicio backend<\/b><span style=\"font-weight: 400;\"> que actualiza el <em>activo<\/em>\u00a0punto final.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Si utiliza iOS o Android, tenga en cuenta con qu\u00e9 frecuencia y d\u00f3nde ejecuta este c\u00f3digo. Por ejemplo, las tareas en segundo plano o las notificaciones push pueden activar comprobaciones de estado en un contexto m\u00f3vil.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Si usted tiene una arquitectura de microservicios, puede ejecutar esta l\u00f3gica de conmutaci\u00f3n por error en un peque\u00f1o servicio que expone un archivo <em>URL activa actual<\/em>\u00a0a las aplicaciones m\u00f3viles, para que siempre se conecten al punto final de WSS correcto.<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>Conclusi\u00f3n<\/h2>\n<p><span style=\"font-weight: 400;\">Este c\u00f3digo de ejemplo proporciona un mecanismo sencillo pero potente para garantizar la alta disponibilidad de las aplicaciones mediante la conmutaci\u00f3n autom\u00e1tica a un servidor de copia de seguridad cuando el servidor primario deja de estar accesible. Al separar las comprobaciones de estado de los puntos finales de conexi\u00f3n, la aplicaci\u00f3n garantiza que siempre se conecta a un servidor en buen estado a trav\u00e9s de WebSocket.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">En un entorno de producci\u00f3n, es posible que tenga que adaptar y ampliar la l\u00f3gica para adaptarla a sus requisitos espec\u00edficos, las condiciones de la red y las pol\u00edticas de seguridad.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Implementar esta l\u00f3gica en su aplicaci\u00f3n m\u00f3vil o servicio backend puede mejorar enormemente el tiempo de actividad y la resistencia, garantizando que sus usuarios sigan conectados incluso durante interrupciones inesperadas del servicio.<\/span><\/p>\n<p>&nbsp;<\/p>","protected":false},"excerpt":{"rendered":"<p>In modern applications, continuous connectivity is key\u2014especially for mobile apps relying on backend services. In this blog, we\u2019ll walk through a Python-based solution that monitors the health of your app service servers and automatically fails over to a secondary server [&hellip;]<\/p>","protected":false},"author":85152,"featured_media":17039,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[10130,1815,2225,9139],"tags":[2126,1782],"ppma_author":[9941,10067],"class_list":["post-17036","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-app-services","category-best-practices-and-tutorials","category-cloud","category-python","tag-high-availability","tag-websocket"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Ensuring High Availability with Automatic Failover for App Services<\/title>\n<meta name=\"description\" content=\"Boost app reliability with Python-based automatic failover. Monitor server health and switch WebSocket connections seamlessly to keep users connected.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/es\/high-availability-automatic-failover-app-services\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Ensuring High Availability with Automatic Failover for App Services\" \/>\n<meta property=\"og:description\" content=\"Boost app reliability with Python-based automatic failover. Monitor server health and switch WebSocket connections seamlessly to keep users connected.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/high-availability-automatic-failover-app-services\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-04-17T15:48:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T05:04:18+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/04\/blog-high-availability-app-services.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2400\" \/>\n\t<meta property=\"og:image:height\" content=\"1256\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Nishant Bhatia - Cloud Architect, Rob Hadaway, Sr. Solutions Architect\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nishant Bhatia - Cloud Architect\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/\"},\"author\":{\"name\":\"Nishant Bhatia - Cloud Architect\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/14cc749fce6a626f4e615a0d53efb709\"},\"headline\":\"Ensuring High Availability with Automatic Failover for App Services\",\"datePublished\":\"2025-04-17T15:48:18+00:00\",\"dateModified\":\"2025-06-14T05:04:18+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/\"},\"wordCount\":536,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/04\/blog-high-availability-app-services.jpg\",\"keywords\":[\"High Availability\",\"websocket\"],\"articleSection\":[\"App Services\",\"Best Practices and Tutorials\",\"Couchbase Capella\",\"Python\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/\",\"name\":\"Ensuring High Availability with Automatic Failover for App Services\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/04\/blog-high-availability-app-services.jpg\",\"datePublished\":\"2025-04-17T15:48:18+00:00\",\"dateModified\":\"2025-06-14T05:04:18+00:00\",\"description\":\"Boost app reliability with Python-based automatic failover. Monitor server health and switch WebSocket connections seamlessly to keep users connected.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/04\/blog-high-availability-app-services.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/04\/blog-high-availability-app-services.jpg\",\"width\":2400,\"height\":1256},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ensuring High Availability with Automatic Failover for App Services\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/14cc749fce6a626f4e615a0d53efb709\",\"name\":\"Nishant Bhatia - Cloud Architect\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/6b3e33d8e1e728532201181a4b557ec1\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/7d3d3f6f12724ef9095e97d255b64435e9c6b3df4c0e02d34a569a65138719f2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/7d3d3f6f12724ef9095e97d255b64435e9c6b3df4c0e02d34a569a65138719f2?s=96&d=mm&r=g\",\"caption\":\"Nishant Bhatia - Cloud Architect\"},\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/nishantbhatia\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Alta disponibilidad con conmutaci\u00f3n por error autom\u00e1tica para App Services","description":"Boost app reliability with Python-based automatic failover. Monitor server health and switch WebSocket connections seamlessly to keep users connected.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/es\/high-availability-automatic-failover-app-services\/","og_locale":"es_MX","og_type":"article","og_title":"Ensuring High Availability with Automatic Failover for App Services","og_description":"Boost app reliability with Python-based automatic failover. Monitor server health and switch WebSocket connections seamlessly to keep users connected.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/high-availability-automatic-failover-app-services\/","og_site_name":"The Couchbase Blog","article_published_time":"2025-04-17T15:48:18+00:00","article_modified_time":"2025-06-14T05:04:18+00:00","og_image":[{"width":2400,"height":1256,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/04\/blog-high-availability-app-services.jpg","type":"image\/jpeg"}],"author":"Nishant Bhatia - Cloud Architect, Rob Hadaway, Sr. Solutions Architect","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Nishant Bhatia - Cloud Architect","Est. reading time":"3 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/"},"author":{"name":"Nishant Bhatia - Cloud Architect","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/14cc749fce6a626f4e615a0d53efb709"},"headline":"Ensuring High Availability with Automatic Failover for App Services","datePublished":"2025-04-17T15:48:18+00:00","dateModified":"2025-06-14T05:04:18+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/"},"wordCount":536,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/04\/blog-high-availability-app-services.jpg","keywords":["High Availability","websocket"],"articleSection":["App Services","Best Practices and Tutorials","Couchbase Capella","Python"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/","url":"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/","name":"Alta disponibilidad con conmutaci\u00f3n por error autom\u00e1tica para App Services","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/04\/blog-high-availability-app-services.jpg","datePublished":"2025-04-17T15:48:18+00:00","dateModified":"2025-06-14T05:04:18+00:00","description":"Boost app reliability with Python-based automatic failover. Monitor server health and switch WebSocket connections seamlessly to keep users connected.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/04\/blog-high-availability-app-services.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2025\/04\/blog-high-availability-app-services.jpg","width":2400,"height":1256},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/high-availability-automatic-failover-app-services\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Ensuring High Availability with Automatic Failover for App Services"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"El blog de Couchbase","description":"Couchbase, la base de datos NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/14cc749fce6a626f4e615a0d53efb709","name":"Nishant Bhatia - Arquitecto de la nube","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/6b3e33d8e1e728532201181a4b557ec1","url":"https:\/\/secure.gravatar.com\/avatar\/7d3d3f6f12724ef9095e97d255b64435e9c6b3df4c0e02d34a569a65138719f2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/7d3d3f6f12724ef9095e97d255b64435e9c6b3df4c0e02d34a569a65138719f2?s=96&d=mm&r=g","caption":"Nishant Bhatia - Cloud Architect"},"url":"https:\/\/www.couchbase.com\/blog\/es\/author\/nishantbhatia\/"}]}},"authors":[{"term_id":9941,"user_id":85152,"is_guest":0,"slug":"nishantbhatia","display_name":"Nishant Bhatia - Cloud Architect","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/7d3d3f6f12724ef9095e97d255b64435e9c6b3df4c0e02d34a569a65138719f2?s=96&d=mm&r=g","first_name":"Nishant","last_name":"Bhatia - Cloud Architect","user_url":"","author_category":"","description":""},{"term_id":10067,"user_id":85538,"is_guest":0,"slug":"rob-hadaway","display_name":"Rob Hadaway, Sr. Solutions Architect","avatar_url":{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/12\/Screenshot-2024-12-20-at-10.48.05\u202fAM.png","url2x":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2024\/12\/Screenshot-2024-12-20-at-10.48.05\u202fAM.png"},"first_name":"Rob","last_name":"Hadaway, Sr. Solutions Architect","user_url":"","author_category":"","description":"Rob Hadaway es arquitecto s\u00e9nior de soluciones en Couchbase, donde se especializa en implementar y optimizar soluciones de bases de datos escalables en entornos en la nube y locales. Con una s\u00f3lida base t\u00e9cnica y una pasi\u00f3n por la resoluci\u00f3n de problemas, Rob ha dirigido proyectos complejos con AWS EKS, Azure y Kubernetes, garantizando una integraci\u00f3n y un despliegue perfectos de las soluciones de Couchbase para clientes de diversos sectores.\r\n\r\nRob tiene una Maestr\u00eda en Ciencias en Sistemas de Informaci\u00f3n y un MBA de la Universidad de Utah. Su experiencia t\u00e9cnica abarca una amplia gama de herramientas y tecnolog\u00edas, incluyendo Python, SQL, Terraform, Docker, Kubernetes, y React.js. Cuenta con numerosas certificaciones de AWS, as\u00ed como de administrador y desarrollador de Kubernetes."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/17036","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/85152"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=17036"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/17036\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/17039"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=17036"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=17036"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=17036"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=17036"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}