Developer Week 2024 está dedicada a la puesta en producción. El lunes 1 de abril, anunciamos que D1, Queues, Hyperdrive y Workers Analytics Engine están listos para pasar a la escala de producción y disponibles de forma general. El martes 2 de abril, anunciamos lo mismo sobre nuestra plataforma de inferencia, Workers AI. Y aún no hemos terminado.
Sin embargo, la puesta en producción no depende únicamente de la escala y la fiabilidad de los servicios con los que desarrollas. También necesitas herramientas para realizar cambios de forma segura y fiable. Dependes no solo de lo que proporciona Cloudflare, sino de poder controlar y adaptar con precisión el comportamiento de Cloudflare según las necesidades de tu aplicación.
Hoy anunciamos cinco novedades que te darán más poder: implementaciones graduales, stack traces con correlaciones de código fuente en Tail Workers, una nueva API de limitación de velocidad, nuevos SDK de API y actualizaciones de Durable Objects, cada una de ellas creadas específicamente para los servicios esenciales de producción. Nosotros desarrollamos nuestros propios productos utilizando Workers, como Access, R2, KV, Waiting Room, Vectorize, Queues Stream y muchos otros. Confiamos en cada una de estas nuevas funciones para garantizar que estamos preparados para la producción, y ahora estamos encantados de ponerlas a disponibilidad de todos.
Implementa gradualmente los cambios en Workers y Durable Objects
La implementación de un Worker es casi instantánea: unos segundos y tu cambio se habrá aplicado en todas partes.
A escala de producción, cualquier cambio que realizas conlleva un mayor riesgo, tanto en términos de volumen como de expectativas. Necesitas cumplir tu SLA de disponibilidad del 99,99 %, o tienes un ambicioso SLO de latencia P90. Una implementación errónea que esté activa para la totalidad del tráfico durante apenas 45 segundos podría significar que millones de solicitudes recibieran un error. Un pequeño cambio en el código podría causar un ingente aluvión de reintentos a un backend desbordado, si toda la implementación se realiza de una sola vez. Estos son los tipos de riesgos que tenemos en cuenta y mitigamos nosotros mismos para nuestros propios servicios basados en Workers.
La forma de mitigar estos riesgos es implementar los cambios gradualmente (lo que se denomina habitualmente como implementaciones progresivas):
La versión actual de tu aplicación se ejecuta en el entorno de producción.
Implementas la nueva versión de tu aplicación en el entorno de producción, pero solo direccionas un pequeño porcentaje del tráfico a esta nueva versión, y esperas a que se "empape" en producción, controlando si hay regresiones y errores. Si algo falla, lo habrás detectado a tiempo en un pequeño porcentaje del tráfico (p. ej. el 1 %) y puede revertirse rápidamente.
Incrementa gradualmente el porcentaje hasta que la nueva versión reciba la totalidad del tráfico, momento en el que esta se habrá implementado por completo.
Hoy presentamos un método de primera clase para implementar cambios de código de forma gradual en Workers y Durable Objects a través de la API de Cloudflare, la CLI de Wrangler o el panel de control de Workers. Las implementaciones graduales están disponibles en la versión beta abierta. Puedes utilizar esta función con cualquier cuenta de Cloudflare del plan gratuito de Workers, y en breve podrás empezar a utilizarla con cuentas de Cloudflare de los planes de pago de Workers y Enterprise. Cuando esté disponible el acceso para tu cuenta, verás un banner en el panel de Workers.
Si tienes dos versiones de tu Worker o Durable Object ejecutándose simultáneamente en producción, probablemente querrás poder filtrar tus métricas, excepciones y registros según la versión. Esto te permitirá detectar los problemas de producción en una fase temprana, con la nueva versión solo implementada en un pequeño porcentaje del tráfico, o comparar las métricas de rendimiento al dividir el tráfico en dos mitades. También hemos añadido observabilidad a nivel de versión en toda nuestra plataforma:
Puedes filtrar por versión los análisis en el panel de control de Workers y a través de la API de GraphQL Analytics.
Workers Trace Events y Tail Workers incluyen el ID de versión de tu Worker, junto con los campos opcionales de mensaje de versión y etiqueta de versión.
Si utilizas wrangler tail para visualizar los registros en directo, puedes ver los registros de una versión concreta.
Puedes acceder al ID, al mensaje y a la etiqueta de versión desde el código de tu Worker, configurando el enlace Metadatos de versión.
Es posible que también quieras asegurarte de que cada cliente o usuario vea solo una versión coherente de tu Worker. Hemos añadido la Afinidad de versión para que las solicitudes asociadas a un identificador específico (p. ej., usuario, sesión o cualquier identificador único) siempre las gestione una versión coherente de tu Worker. La Afinidad de sesión, cuando se utiliza con el motor de conjunto de reglas, te proporciona un control total tanto sobre el mecanismo como sobre el identificador que se utilizan para garantizar esta persistencia.
Las implementaciones granulares ya están disponibles en la versión beta abierta. Conforme avanzamos hacia su disponibilidad general, estamos trabajando para ofrecer:
Anulaciones de versión. Invoca una versión específica de tu Worker para probarla antes de que sirva tráfico de producción. Esto te permitirá crear implementaciones azul-verde.
Cloudflare Pages. Deja que el sistema de integración y distribución continuas (CI/CD) de Cloudflare Pages avance automáticamente las implementaciones en tu nombre.
Reversiones automáticas. Revierte automáticamente las implementaciones cuando aumente la tasa de errores para una nueva versión de tu Worker.
¡Esperamos recibir tus comentarios! Dinos qué te parece mediante este formulario de comentarios o ponte en contacto con nosotros en nuestro Discord para desarrolladores en el canal #workers-gradual-deployments-beta.
Stack traces con correlaciones de código fuente en Tail Workers
La puesta en producción requiere un seguimiento de los errores y las excepciones, e intentar reducirlos a cero. Cuando se produce un error, normalmente lo primero que compruebas es el stack trace del error: las funciones concretas que se han invocado, en qué orden, desde qué línea y archivo, y con qué argumentos.
La mayor parte del código JavaScript (no solo en Workers, sino en todas las plataformas) primero se empaqueta, a menudo se transpila y luego se minifica antes de su implementación en producción. Estas tareas se realizan en segundo plano para crear paquetes más pequeños a fin de optimizar el rendimiento y realizar la conversión de Typescript a Javascript si es necesario.
Si te has encontrado alguna vez que una excepción devuelve un stack trace como: /src/index.js:1:342, significa que el error se produjo en el carácter 342 del código minificado de tu función. Evidentemente, esto no es muy útil para fines de depuración.
Las source-maps correlaciones de código fuente resuelven este problema: vuelven a asignar el código compilado y minificado al código original que escribiste. Las correlaciones de código fuente se combinan con el stack trace que ha devuelto el tiempo de ejecución de JavaScript para presentarte un stack trace que puedas leer. Por ejemplo, el siguiente stack trace muestra que el Worker ha recibido un valor nulo inesperado en la línea 30 del archivo down.ts. Este es un punto de partida útil para la depuración, y puedes desplazarte hacia abajo por el stack trace para ver las funciones que se han invocado y que han generado el valor nulo.
Así es como funciona:
Unexpected input value: null
at parseBytes (src/down.ts:30:8)
at down_default (src/down.ts:10:19)
at Object.fetch (src/index.ts:11:12)
Si estableces upload_source_maps = true en tu wrangler.toml, Wrangler generará y cargará automáticamente los archivos de correlación de código fuente cuando ejecutes wrangler deploy o wrangler versions upload.
Cuando tu Worker emite una excepción no detectada, recuperamos la correlación de código fuente y la utilizamos para correlacionar el stack trace de la excepción con las líneas del código fuente original de tu Worker.
A continuación, puedes ver este stack trace sin ofuscación en los registros en tiempo real o en Tail Workers.
A partir de hoy, en la versión beta abierta, puedes cargar correlaciones de código fuente a Cloudflare al implementar tu Worker. Para empezar, consulta la documentación. A partir del 15 de abril, el tiempo de ejecución de Workers empezará a utilizar correlaciones de código fuente para desofuscar los stack traces. Cuando los stack traces con correlaciones de código fuente estén disponibles, publicaremos una notificación en el panel de control de Cloudflare y en nuestra cuenta de X para desarrolladores de Cloudflare.
Nueva API de limitación de velocidad en Workers
Una API solo está lista para la producción si tiene un límite de velocidad adecuado. A medida que crece tu negocio, también lo hacen la complejidad y la diversidad de los límites que necesitas aplicar para equilibrar las necesidades de clientes específicos, proteger el estado de tu servicio o aplicar y ajustar límites en escenarios concretos. La propia API de Cloudflare afronta este desafío: cada una de nuestras docenas de productos, cada uno con muchos puntos finales de la API, puede necesitar aplicar distintos límites de velocidad.
Desde 2017 puedes configurar reglas de limitación de velocidad en Cloudflare. No obstante, hasta hoy la única forma de controlar esto era mediante el panel de control o la API de Cloudflare. No había sido posible definir el comportamiento en tiempo de ejecución, o escribir código en Worker que interactuara directamente con los límites de velocidad. Solo podías controlar si una solicitud tenía o no limitación de velocidad antes de que llegara a tu Worker.
Hoy presentamos una nueva API, en versión beta abierta, que te permite acceder directamente a los límites de velocidad desde tu Worker. Es muy rápida, está basada en memcached y es muy fácil de añadir a tu Worker. Por ejemplo, la siguiente configuración define un límite de velocidad de 100 solicitudes en un periodo de 60 segundos:
A continuación, en tu Worker, puedes invocar el método limit en el enlace RATE_LIMITER, proporcionando la clave que prefieras. Con la configuración anterior, este código devolverá un código de estado de respuesta HTTP 429 cuando se realicen más de 100 solicitudes a una ruta específica en un periodo de 60 segundos:
[[unsafe.bindings]]
name = "RATE_LIMITER"
type = "ratelimit"
namespace_id = "1001" # An identifier unique to your Cloudflare account
# Limit: the number of tokens allowed within a given period, in a single Cloudflare location
# Period: the duration of the period, in seconds. Must be either 60 or 10
simple = { limit = 100, period = 60 }
Ahora que Workers puede conectarse directamente a un almacén de datos como memcached, ¿qué más podríamos proporcionar? ¿Contadores? ¿Bloqueos? ¿Una caché en memoria? La limitación de velocidad es la primera de muchas primitivas que estamos estudiando ofrecer en Workers y que responden a las preguntas que llevamos años escuchando acerca de dónde se debería encontrar un estado compartido temporal que abarque muchos aislamientos de Worker. Si actualmente dependes de poner el estado en el ámbito global de tu Worker, estamos trabajando en mejores primitivas creadas específicamente para casos de uso concretos.
export default {
async fetch(request, env) {
const { pathname } = new URL(request.url)
const { success } = await env.RATE_LIMITER.limit({ key: pathname })
if (!success) {
return new Response(`429 Failure – rate limit exceeded for ${pathname}`, { status: 429 })
}
return new Response(`Success!`)
}
}
La API de limitación de velocidad en Workers está en la versión beta abierta. Para empezar a utilizarla, lee la documentación.
Nuevos SDK generados automáticamente para la API de Cloudflare
La puesta en producción implica pasar de realizar cambios mediante clics en un panel de control a hacerlos mediante programación, utilizando un enfoque de infraestructura como código, como Terraform o Pulumi, o haciendo llamadas API directamente, ya sea por tu cuenta o mediante un SDK.
La API de Cloudflare es masiva e incorpora continuamente nuevas capacidades: de media, actualizamos nuestros esquemas de API entre 20 y 30 veces al día. Sin embargo, hasta la fecha hemos estado desarrollando y manteniendo nuestros SDK de API manualmente, por lo que nos urgía automatizar estas tareas.
Eso es lo que hemos hecho, y hoy anunciamos nuevos SDK de cliente para la API de Cloudflare en tres lenguajes: Typescript, Python y Go, y próximamente en otros.
Cada SDK se genera automáticamente mediante la API de Stainless, basada en los esquemas OpenAPI que definen la estructura y las capacidades de cada uno de nuestros puntos finales de la API. Esto significa que cuando añadimos cualquier nueva funcionalidad a la API de Cloudflare, en cualquier producto de Cloudflare, estos SDK de API se vuelven a generar automáticamente y se publican nuevas versiones, lo que garantiza que son correctos y están actualizados.
Puedes instalar los SDK ejecutando uno de estos comandos:
Si utilizas Terraform o Pulumi, a nivel interno el proveedor Terraform de Cloudflare utiliza actualmente el SDK de Go existente no automatizado. Cuando ejecutas terraform apply, el proveedor Terraform de Cloudflare determina qué solicitudes de API realizar y en qué orden, y las ejecuta utilizando el SDK de Go.
// Typescript
npm install cloudflare
// Python
pip install cloudflare
// Go
go get -u github.com/cloudflare/cloudflare-go/v2
El nuevo SDK de Go generado automáticamente abre el camino para una compatibilidad más completa con Terraform en todos los productos de Cloudflare, ya que ofrece un conjunto básico de herramientas que te garantizan que son correctos y que están actualizados con los últimos cambios de la API. Estamos trabajando para que, en el futuro, cada vez que un equipo de producto de Cloudflare desarrolle una nueva función que esté disponible mediante la API de Cloudflare, esta función sea automáticamente compatible con los SDK. Verás más novedades sobre esto a lo largo de 2024.
Disponibilidad general del análisis del espacio de nombres de Durable Objetcs y WebSocket Hibernation
Muchos de nuestros propios productos, como Waiting Room, R2 y Queues, y plataformas como PartyKit, se desarrollan utilizando Durable Objects. Puedes considerar Durable Objects (implementados en todo el mundo, incluido el nuevo soporte para Oceanía) como Workers singleton que pueden proporcionar un único punto de coordinación y persistencia de estado. Son perfectos para las aplicaciones que necesitan coordinación de usuarios en tiempo real, como el chat interactivo o la edición colaborativa. Según Atlassian:
Una de nuestras nuevas capacidades son las pizarras de Confluence, con las que podemos capturar con libertad el trabajo no estructurado, como la lluvia de ideas y la planificación inicial, antes de que los equipos lo documenten de manera más formal. El equipo consideró muchas opciones para la colaboración en tiempo real y finalmente decidió utilizar Durable Objects de Cloudflare. Durable Objects ha demostrado ser la solución perfecta a este problema, con una combinación única de funcionalidades que nos ha permitido simplificar enormemente nuestra infraestructura y escalar fácilmente a un gran número de usuarios. - Atlassian
Antes no mostrábamos las tendencias analíticas asociadas en el panel de control, lo que hacía difícil comprender los patrones de uso y las tasas de error en un espacio de nombres de Durable Objects, a menos que utilizaras directamente la API de GraphQL Analytics. Hemos renovado el panel de control de Durable Objects, que ahora te permite detallar en las métricas tanto como necesites.
Desde el primer día, Durable Objects ha ofrecido compatibilidad con WebSockets, por lo que muchos clientes pueden conectarse directamente a un Durable Object para enviar y recibir mensajes.
Sin embargo, a veces las aplicaciones cliente abren una conexión WebSocket y luego no hacen... nada. Piensa en esa pestaña que tienes abierta en el navegador desde hace 5 horas y que aún no has tocado. Si utiliza WebSockets para enviar y recibir mensajes, en realidad tiene una conexión TCP de larga duración que no se utiliza para nada. Si esta conexión es a un Durable Object, este debe permanecer en ejecución, a la espera de que ocurra algo, consumiendo memoria y costándote dinero.
Inicialmente presentamos WebSocket Hibernation para resolver este problema. Hoy anunciamos que esta función pasa de su versión beta abierta a la disponibilidad general. Con WebSocket Hibernation, estableces una respuesta automática que se utilizará durante la hibernación y serializas el estado de modo que persiste tras la hibernación. Esto proporciona a Cloudflare la información que necesitamos para mantener abiertas las conexiones WebSocket de los clientes durante la "hibernación" del Durable Object, de manera que no se ejecuta activamente, ni se te factura por el tiempo de inactividad. Como resultado, tu estado siempre está disponible en memoria cuando realmente lo necesitas, pero no se mantiene innecesariamente cuando no es así. Mientras tu Durable Object esté hibernando, aunque haya clientes activos todavía conectados a través de un WebSocket, no se te facturará por esa duración.
Además, hemos respondido a los comentarios de los desarrolladores sobre los costes de los mensajes WebSocket entrantes a Durable Objects, que favorecen los mensajes más pequeños y frecuentes para la comunicación en tiempo real. A partir de hoy, los mensajes WebSocket entrantes se facturarán al equivalente de una veinteava parte de una solicitud (en lugar de que 1 mensaje equivalga a 1 solicitud, como hasta ahora). A continuación se mostramos un ejemplo de precios:
.tg {border-collapse:collapse;border-color:#ccc;border-spacing:0;} .tg td{background-color:#fff;border-color:#ccc;border-style:solid;border-width:1px;color:#333; font-family:Arial, sans-serif;font-size:14px;overflow:hidden;padding:10px 5px;word-break:normal;} .tg th{background-color:#f0f0f0;border-color:#ccc;border-style:solid;border-width:1px;color:#333; font-family:Arial, sans-serif;font-size:14px;font-weight:normal;overflow:hidden;padding:10px 5px;word-break:normal;} .tg .tg-0lax{text-align:left;vertical-align:top} .tg .tg-4kyp{color:#0E101A;text-align:left;vertical-align:top} .tg .tg-bhdc{color:#0E101A;font-weight:bold;text-align:left;vertical-align:top}
WebSocket Connection Requests | Incoming WebSocket Messages | Billed Requests | Request Billing | |
---|---|---|---|---|
Before | 10K | 432M | 432,010,000 | $64.65 |
After | 10K | 432M | 21,610,000 | $3.09 |
Solicitudes de conexión WebSocket
Mensajes WebSocket entrantes
Solicitudes facturadas
Facturación de solicitudes
Antes
10K
432M
432 010 000
64,65 USD
Después
10K
432M
21 610 000
3,09 USD
Listo para entornos de producción, sin la complejidad del entorno de producción
En la última generación de plataformas en la nube, prepararse para la puesta en producción significaba ralentizar el lanzamiento. Significaba combinar muchas herramientas desconectadas o crear equipos enteros dedicados a trabajar en las plataformas internas. Tenías que adaptar tus propias capas de productividad a plataformas que ponían obstáculos.
La plataforma para desarrolladores de Cloudflare ha crecido y está lista para la puesta en producción, con el compromiso de ser una plataforma integrada en la que los productos funcionen juntos de forma intuitiva y donde no haya 10 formas de hacer lo mismo, sin necesidad de una matriz de compatibilidad que ayude a entender qué elementos funcionan juntos. Cada una de estas actualizaciones muestra esto en la práctica, integrando nuevas funcionalidades en todos los productos y componentes de la plataforma de Cloudflare.
Con ese objetivo, queremos que nos digas no solo lo que quieres ver a continuación, sino también dónde crees que podríamos simplificar aún más, o dónde crees que nuestros productos podrían funcionar mejor juntos. Cuéntanos dónde crees que podríamos hacer más: nuestro Discord para desarrolladores de Cloudflare está siempre abierto.