Capítulo 1. La Plataforma de Aplicación

Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com

Martin Fowler y James Lewis, que propusieron inicialmente el término microservicios en , definen la arquitectura en su entrada de blog seminal como:

...una forma particular de diseñar aplicaciones de software como conjuntos de servicios desplegables independientemente. Aunque no existe una definición precisa de este estilo arquitectónico, hay ciertas características comunes en torno a la organización en torno a la capacidad empresarial, la implementación automatizada, la inteligencia en los puntos finales y el control descentralizado de lenguajes y datos.

La adopción de microservicios promete acelerar el desarrollo de software al separar las aplicaciones en componentes desarrollados e implementados de forma independiente, producidos por equipos independientes. Reduce la necesidad de coordinar y planificar lanzamientos de software a gran escala. Cada microservicio es construido por un equipo independiente para satisfacer una necesidad empresarial específica (para clientes internos o externos). Los microservicios se despliegan de forma redundante y escalada horizontalmente a través de diferentes recursos en la nube y se comunican entre sí a través de la red utilizando diferentes protocolos.

Esta arquitectura plantea una serie de retos que no se habían visto antes en las aplicaciones monolíticas. Las aplicaciones monolíticas solían desplegarse principalmente en el mismo servidor y liberarse con poca frecuencia como un evento cuidadosamente coreografiado. El proceso de liberación del software era la principal fuente de cambio e inestabilidad del sistema. En los microservicios, las comunicaciones y los costes de transferencia de datos introducen latencias adicionales y pueden degradar la experiencia del usuario final. Una cadena de decenas o cientos de microservicios trabajan ahora juntos para crear esa experiencia. Los microservicios se lanzan independientemente unos de otros, pero cada uno puede afectar inadvertidamente a otros microservicios y, por tanto, también a la experiencia del usuario final.

Gestionar este tipo de sistemas distribuidos requiere nuevas prácticas, herramientas y cultura de ingeniería. Acelerar la publicación de software no tiene por qué ir en detrimento de la estabilidad y la seguridad. De hecho, van de la mano. Este capítulo presenta la cultura de un equipo eficaz de ingeniería de plataformas y describe los componentes básicos de los sistemas fiables.

Cultura de ingeniería de plataformas

Para gestionar microservicios, una organización necesita estandarizar protocolos de comunicación específicos y marcos de apoyo. Surgen muchas ineficiencias si cada equipo necesita mantener su propio desarrollo de pila completa, así como fricciones al comunicarse con otras partes de una aplicación distribuida. En la práctica, la normalización conduce a un equipo de plataforma que se centra en proporcionar estos servicios al resto de los equipos de , que a su vez se centran en desarrollar software para satisfacer las necesidades empresariales.

Queremos proporcionar barandillas, no puertas.

Dianne Marsh, directora de herramientas de ingeniería de Netflix

En lugar de construir puertas, permite que los equipos construyan primero soluciones que les funcionen, aprendan de ellas y las generalicen al resto de la organización.

Las organizaciones que diseñan sistemas se ven obligadas a producir diseños que son copias de las estructuras de comunicación de dichas organizaciones.

Ley de Conway

La Figura 1-1 muestra una organización de ingeniería construida en torno a especialidades. Un grupo se especializa en el diseño de la interfaz y la experiencia del usuario, otro construye los servicios backend, otro gestiona la base de datos, otro trabaja en la automatización de los procesos empresariales y otro gestiona los recursos de red.

srej 0101
Figura 1-1. Organización basada en silos técnicos

La lección que suele extraer de la Ley de Conway es que los equipos interfuncionales, como los de la Figura 1-2, pueden iterar más rápido. Al fin y al cabo, cuando la estructura del equipo está alineada con la especialización técnica, cualquier nuevo requisito empresarial requerirá la coordinación de todas estas especializaciones.

srej 0102
Figura 1-2. Equipos interfuncionales

Sin embargo, es obvio que también hay desperdicio en este sistema, concretamente que los especialistas de cada equipo desarrollan capacidades independientemente unos de otros. Netflix no tenía ingenieros de fiabilidad de sitios dedicados por equipo, como promueve Google en Site Reliability Engineering editado por Betsy Beyer et al. (O'Reilly). Tal vez debido a un mayor grado de homogeneidad en el tipo de software que escribían los equipos de producto (principalmente Java, principalmente microservicios de escala horizontal sin estado), la centralización de las funciones de ingeniería de producto era más eficiente. ¿Tu organización se parece más a Google, que trabaja en tipos de productos muy diferentes, desde coches automatizados a búsquedas, pasando por hardware móvil o navegadores? ¿O se parece más a Netflix, compuesta por una serie de aplicaciones empresariales escritas en un puñado de lenguajes que se ejecutan en una variedad limitada de plataformas?

Los equipos interfuncionales y los equipos completamente aislados están en los extremos opuestos del espectro. Una ingeniería de plataforma eficaz puede reducir la necesidad de un especialista por equipo para cierto conjunto de problemas. Una organización con ingeniería de plataforma dedicada es más bien un híbrido, como en la Figura 1-3. Un equipo de ingeniería de plataforma central es más fuerte cuando considera a los equipos de producto como clientes a los que hay que ganarse constantemente y ejerce poco o ningún control sobre el comportamiento de sus clientes.

srej 0103
Figura 1-3. Equipos de producto con ingeniería de plataforma dedicada

Por ejemplo, cuando la instrumentación de monitoreo se distribuye por toda la organización como una biblioteca común incluida en cada microservicio, se comparte el conocimiento de los indicadores de disponibilidad que tanto ha costado conseguir y que se sabe que son ampliamente aplicables. Cada equipo de producto puede dedicar sólo un poco de tiempo a añadir indicadores de disponibilidad que sean exclusivos de su dominio empresarial. Puede comunicarse con el equipo central de monitoreo para obtener información y asesoramiento sobre cómo construir señales eficaces, según sea necesario.

En Netflix, la corriente cultural más fuerte era "libertad y responsabilidad", definida en una baraja cultural un tanto famosa de 2001. Yo era miembro del equipo de herramientas de ingeniería, pero no podíamos exigir que todos los demás adoptaran una herramienta de compilación determinada. Un pequeño equipo de ingenieros gestionaba clusters Cassandra en nombre de muchos equipos de producto. Hay una eficacia en esta concentración de herramientas de compilación o conocimientos de Cassandra, un centro de comunicación natural a través del cual fluían los problemas indiferenciados con estos productos y se transferían las lecciones a los equipos centrados en los productos.

El equipo de herramientas de compilación de Netflix, en su punto más bajo, estaba formado por sólo dos ingenieros que atendían los intereses de otros 700 ingenieros mientras cambiaban entre las herramientas de compilación recomendadas (de Ant a Gradle) y realizaban dos grandes actualizaciones de Java (de Java 6 a 7 y de Java 7 a 8), entre otras rutinas diarias. Cada equipo de producto era completamente dueño de su compilación. Debido a la "libertad y responsabilidad", no podíamos fijar una fecha concreta para retirar por completo las herramientas de compilación basadas en Ant. No podíamos fijar una fecha concreta para que cada equipo actualizara su versión de Java (salvo en la medida en que un nuevo modelo de licencia de Oracle lo hiciera por nosotros). El imperativo cultural nos llevó a centrarnos tanto en la experiencia del desarrollador que los equipos de producto querían migrar con nosotros. Exigía un nivel de esfuerzo y empatía que sólo podía garantizarse impidiéndonos absolutamente establecer requisitos duros.

Cuando un ingeniero de plataforma como yo sirve a los intereses de equipos de productos tan diversos en una especialidad técnica concreta como la creación de herramientas, inevitablemente surgen patrones. Mi equipo vio que el mismo guión se repetía una y otra vez con problemas de dependencias binarias, versiones de plug-ins, problemas de flujo de trabajo de lanzamiento, etc. Al principio trabajamos para automatizar el descubrimiento de estos patrones y emitir advertencias en la salida de la compilación. Sin la cultura de libertad y responsabilidad, tal vez nos habríamos saltado las advertencias y nos habríamos limitado a fallar la compilación, obligando a los equipos de producto a solucionar los problemas. Esto habría sido satisfactorio para el equipo de herramientas de compilación: no seríamos responsables de responder a preguntas relacionadas con fallos sobre los que intentamos advertir a los equipos. Pero desde el punto de vista del equipo de producto, cada "lección" que aprendiera el equipo de herramientas de creación sería perjudicial para ellos en momentos aleatorios, y especialmente perjudicial cuando tuvieran prioridades más urgentes (aunque temporales).

El enfoque más suave, sin advertencias de fallo, fue sorprendentemente ineficaz. Los equipos rara vez prestaban atención a los registros de las compilaciones que funcionaban, independientemente del número de advertencias emitidas. E incluso si veían las advertencias, intentar arreglarlas suponía un riesgo: una compilación que funciona con advertencias es mejor que una que funciona mal sin advertencias. Como resultado, las advertencias de desaprobación cuidadosamente elaboradas podían ser ignoradas durante meses o años.

El enfoque de "guardarraíles, no puertas" exigió que nuestro equipo de herramientas de construcción pensara en cómo podíamos compartir nuestros conocimientos con los equipos de producto de forma que fueran visibles para ellos, requirieran poco tiempo y esfuerzo para actuar y redujeran el riesgo de acompañarnos por el camino pavimentado. El conjunto de herramientas que surgió de esto era casi exagerado en su enfoque de la experiencia del desarrollador.

En primer lugar, escribimos herramientas que pudieran reescribir el código Groovy de las compilaciones de Gradle para autoremediar patrones comunes. Esto era mucho más difícil que limitarse a emitir advertencias en el registro. Requería hacer modificaciones en el árbol sintáctico abstracto que preservara la indentación en la lógica de construcción imperativa, un problema imposible de resolver en general, pero sorprendentemente eficaz en casos concretos. Sin embargo, la autorremediación era opcional, mediante el uso de un sencillo comando que los equipos de producto podían ejecutar para aceptar las recomendaciones.

A continuación, escribimos una instrumentación de monitoreo que informaba de los patrones que eran potencialmente remediables, pero para los que los equipos de producto no aceptaban la recomendación. Podíamos monitorizar cada patrón perjudicial en la organización a lo largo del tiempo, y observar cómo disminuía su impacto a medida que los equipos aceptaban las soluciones. Cuando llegábamos a la larga cola de un pequeño número de equipos que simplemente no aceptaban, sabíamos quiénes eran, así que podíamos acercarnos a sus mesas y trabajar con ellos individualmente para escuchar sus preocupaciones y ayudarles a avanzar. (Lo hice tanto que empecé a llevar mi propio ratón encima). Había una correlación sospechosa entre los ingenieros de Netflix que utilizaban trackballs y los ingenieros de Netflix que estaban en la cola larga de aceptación de las soluciones). En última instancia, esta comunicación proactiva estableció un vínculo de confianza que hizo que nuestras futuras recomendaciones parecieran menos arriesgadas.

Llegamos a extremos bastante extremos para mejorar la visibilidad de las recomendaciones sin recurrir a romper las compilaciones para llamar la atención de los desarrolladores. La salida de la compilación se coloreaba y estilizaba cuidadosamente, a veces con indicadores visuales como marcas de verificación Unicode y marcas X que eran difíciles de pasar por alto. Las recomendaciones siempre aparecían al final de la compilación porque sabíamos que eran lo último que se emitía en el terminal y nuestras herramientas de CI se desplazaban por defecto hasta el final de la salida del registro cuando los ingenieros examinaban la salida de la compilación. Enseñamos a Jenkins a hacerse pasar por un terminal TTY para colorear la salida de la compilación, pero ignorando las secuencias de escape del movimiento del cursor para seguir serializando el progreso de la tarea de compilación.

Crear este tipo de experiencia era técnicamente costoso, pero compáralo con las dos opciones:

Cultura de libertad y responsabilidad

Nos llevó a crear una autoremediación de autoayuda con monitoreo que nos ayudó a comprender a los equipos que tenían dificultades y a comunicarnos con ellos.

Cultura de control centralizado

Probablemente nos habrían llevado a romper las construcciones con impaciencia porque "éramos dueños" de la experiencia de construcción. Los equipos se habrían distraído de sus otras prioridades para adaptarse a nuestro deseo de una experiencia de compilación coherente. Cada cambio, al carecer de autoremediación, nos habría generado muchas más preguntas como equipo de herramientas de compilación. La cantidad total de trabajo para cada cambio habría sido mucho mayor.

Un equipo eficaz de ingeniería de plataformas se preocupa profundamente por la experiencia del desarrollador, un enfoque singular que es al menos tan agudo como el enfoque que los equipos de producto ponen en la experiencia del cliente. Esto no debería sorprender: en una organización de ingeniería de plataformas bien calibrada, ¡los desarrolladores son el cliente! La presencia de una sana disciplina de gestión de productos, diseñadores expertos en experiencia de usuario e ingenieros y diseñadores de interfaz de usuario que se preocupan profundamente por su oficio deberían ser indicadores de un equipo de ingeniería de plataformas que está alineado en beneficio de sus clientes desarrolladores.

El alcance de este libro no incluye más detalles sobre la estructura de los equipos, pero consulta Team Topologies de Matthew Skelton y Manuel Pais (IT Revolution Press) para un tratamiento exhaustivo del tema.

Una vez calibrado culturalmente el equipo, la cuestión pasa a ser cómo priorizar las capacidades que un equipo de ingeniería de plataformas puede ofrecer a su base de clientes. El resto de este libro es una llamada a la acción, realizada en capacidades ordenadas de (en mi opinión) más esenciales a menos esenciales.

Monitoreo

El monitoreo de la infraestructura de tu aplicación requiere el menor compromiso organizativo de todas las etapas del viaje hacia sistemas más resistentes. Como mostraremos en los capítulos siguientes, la instrumentación de monitoreo a nivel de marco ha madurado hasta tal punto que realmente sólo necesitas encenderla y empezar a aprovecharla. La relación coste-beneficio se ha inclinado tanto hacia el beneficio que, si no haces nada más en este libro, empieza ya a monitorizar tus aplicaciones de producción. El Capítulo 2 tratará de los bloques de construcción de las métricas, y el Capítulo 4 proporcionará los gráficos y alertas específicos que puedes emplear, la mayoría basados en la instrumentación que proporcionan los frameworks de Java sin que tengas que hacer ningún trabajo adicional.

Las métricas, los registros y el rastreo distribuido son tres formas de observabilidad que permiten medir la disponibilidad del servicio y ayudan a depurar problemas complejos de los sistemas distribuidos. Antes de profundizar en el funcionamiento de cualquiera de ellas, es útil comprender qué capacidades permite cada una.

Monitoreo de la disponibilidad

Las señales de disponibilidad miden el estado general del sistema y si éste funciona según lo previsto en el gran. Se cuantifica mediante indicadores de nivel de servicio (IGS ). Estos indicadores incluyen señales de la salud del sistema (por ejemplo, el consumo de recursos) y métricas empresariales como el número de bocadillos vendidos o los inicios de streaming de vídeo por segundo. Los SLI se contrastan con un umbral llamado objetivo de nivel de servicio (SLO) que establece un límite superior o inferior en el rango de un SLI. A su vez, los SLO son una estimación algo más restrictiva o conservadora que el umbral que acuerdes con tus socios comerciales sobre un nivel de servicio que se espera que prestes, o lo que se conoce como acuerdo de nivel de servicio (SLA). La idea es que un SLO debe proporcionar cierto grado de advertencia previa sobre una inminente violación de un SLA, de modo que no llegues realmente al punto de violar ese SLA.

Las métricas son la principal herramienta de observabilidad para medir la disponibilidad. Son una medida de los SLI. Las métricas son la señal de disponibilidad más común porque representan una agregación de toda la actividad que ocurre en el sistema. Son lo suficientemente baratas como para no requerir un muestreo (descartar una parte de los datos para limitar la sobrecarga), con lo que se corre el riesgo de descartar indicadores importantes de indisponibilidad.

Las métricas son valores numéricos dispuestos en una serie temporal que representan una muestra en un momento determinado o un conjunto de sucesos individuales ocurridos en un intervalo:

Métricas

Las métricas deben tener un coste fijo, independientemente del rendimiento. Por ejemplo, una métrica que cuente las ejecuciones de un determinado bloque de código sólo debe enviar el número de ejecuciones observadas en un intervalo, independientemente de cuántas sean. Con esto quiero decir que una métrica debe enviar "se observaron N solicitudes" en el momento de la publicación, no "vi una solicitud N veces distintas" a lo largo del intervalo de publicación.

Datos métricos

Los datos de las métricas no pueden utilizarse para razonar sobre el rendimiento o la función de una solicitud individual. La telemetría métrica sustituye el razonamiento sobre una solicitud individual por el comportamiento de la aplicación en todas las solicitudes de un intervalo.

Para monitorizar eficazmente la disponibilidad de un microservicio Java, hay que monitorizar una serie de señales de disponibilidad. Las señales habituales se indican en el Capítulo 4, pero en general se dividen en cuatro categorías, conocidas en conjunto como método L-USE:1

Latencia

Es una medida del tiempo empleado en ejecutar un bloque de código. Para el microservicio común basado en REST, la latencia del punto final REST es una medida útil de la disponibilidad de la aplicación, en particular de la latencia máxima. Esto se tratará con más detalle en "Latencia".

Utilización

Medida de cuánto se consume de un recurso finito. La utilización del procesador es un indicador común de utilización. Ver "Utilización de la CPU".

Saturación

La saturación es una medida del trabajo extra que no se puede atender. "Tiempos de pausa de la recogida de basura" muestra cómo medir el montón de Java, que en momentos de excesiva presión de memoria provoca una acumulación de trabajo que no puede completarse. También es habitual monitorear pools como los de conexiones a bases de datos, peticiones, etc.

Errores

Además de tener en cuenta los aspectos puramente relacionados con el rendimiento, es esencial encontrar una forma de cuantificar la proporción de errores en relación con el rendimiento total. Entre las medidas de error se incluyen las excepciones imprevistas que producen respuestas HTTP fallidas en un punto final de servicio (ver "Errores"), pero también medidas más indirectas como la proporción de solicitudes intentadas contra un disyuntor abierto (ver "Disyuntores").

La utilización y la saturación pueden parecer similares al principio, e interiorizar la diferencia repercutirá en tu forma de pensar sobre los gráficos y las alertas de los recursos que pueden medirse de ambas formas. Un gran ejemplo es la memoria JVM. Puedes medir la memoria de la JVM como una métrica de utilización, informando sobre la cantidad de bytes consumidos en cada espacio de memoria. También puedes medir la memoria JVM en términos de la proporción de tiempo que se dedica a la recogida de basura en relación con hacer cualquier otra cosa, que es una medida de saturación. En la mayoría de los casos, cuando es posible medir tanto la utilización como la saturación, la métrica de saturación permite definir mejor los umbrales de alerta. Es difícil alertar cuando la utilización de la memoria supera el 95% de un espacio (porque la recogida de basura hará que la tasa de utilización vuelva a estar por debajo de este umbral), pero si la utilización de la memoria supera rutinaria y frecuentemente el 95%, el recogedor de basura se activará con más frecuencia, se dedicará más tiempo proporcionalmente a hacer la recogida de basura que a cualquier otra cosa, y la medida de saturación será por tanto mayor.

En la Tabla 1-1 se enumeran algunas señales de disponibilidad habituales.

Tabla 1-1. Ejemplos de señales de disponibilidad
SLI SLO Criterios L-USE

Uso de la CPU del proceso

<80%

Saturación

Utilización de la pila

<80% del espacio disponible en el montón

Saturación

Ratio de error de un punto final REST

<1% del total de solicitudes al punto final

Errores

Latencia máxima de un punto final REST

<100 ms

Latencia

Google tiene una visión mucho más prescriptiva sobre cómo utilizar los SLO.

El enfoque de Google sobre los SLO

Site Reliability Engineering, de Betsy Beyer et al. (O'Reilly), presenta la disponibilidad del servicio como una tensión entre imperativos organizativos contrapuestos: ofrecer nuevas funciones y ejecutar el conjunto de funciones existentes de forma fiable. Propone que los equipos de producto y los ingenieros dedicados a la fiabilidad del sitio se pongan de acuerdo sobre un presupuesto de errores que proporcione un objetivo cuantificable de lo poco fiable que se permite que sea un servicio dentro de un período de tiempo determinado. Si se supera este objetivo, el equipo debe volver a centrarse en la fiabilidad, en lugar de en el desarrollo de funciones, hasta que se alcance el objetivo.

El punto de vista de Google sobre los SLO se explica con gran detalle en el capítulo "Alerting on SLOs" de The Site Reliability Workbook editado por Betsy Beyer et al. (O'Reilly). Básicamente, los ingenieros de Google alertan sobre la probabilidad de que se agote el presupuesto para errores en un plazo determinado, y reaccionan de forma organizativa desplazando recursos de ingeniería del desarrollo de funciones a la fiabilidad, según sea necesario. La palabra "error" en este caso significa superar cualquier SLO. Podría significar superar un ratio aceptable de resultados fallidos del servidor en un microservicio RESTful, pero también podría significar superar un umbral de latencia aceptable, acercarse demasiado a descriptores de archivo abrumadores en el sistema operativo subyacente, o cualquier otra combinación de medidas. Con esta definición, el tiempo en que un servicio no es fiable en una ventana prescrita es la proporción en que no se cumplían uno o más SLO.

Tu organización no necesita tener funciones separadas para el ingeniero de producto y el ingeniero de fiabilidad del sitio para que la presupuestación de errores sea un concepto útil. Incluso un solo ingeniero que trabaje en un producto completamente solo y sea totalmente responsable de su funcionamiento puede beneficiarse de pensar en dónde pausar el desarrollo de características en favor de mejorar la fiabilidad y viceversa.

Creo que la sobrecarga del esquema de presupuesto de errores de Google es excesiva para muchas organizaciones. Empieza a medir, descubre cómo encajan las funciones de alerta en tu organización y, una vez que tengas práctica en la medición, considera si quieres seguir el proceso de Google o no.

Recopilar, visualizar y alertar sobre las métricas de la aplicación es un ejercicio de comprobación continua de la disponibilidad de tus servicios. A veces, una alerta en sí misma contendrá suficientes datos contextuales como para que sepas cómo solucionar un problema. En otros casos, querrás aislar una instancia que falla en producción (por ejemplo, sacándola del equilibrador de carga) y aplicar más técnicas de depuración para descubrir el problema. Para ello se utilizan otras formas de telemetría.

Un enfoque menos formal de los SLO

Un sistema menos formal funcionó bien en Netflix, donde los equipos de ingeniería individuales eran responsables de la disponibilidad de sus servicios, no había separación de responsabilidad entre SRE e ingeniero de producto en los equipos de producto individuales, y no había una reacción tan formalizada a los presupuestos de errores, al menos no entre organizaciones. Ningún sistema es correcto o incorrecto; encuentra un sistema que te funcione bien.

A efectos de este libro, hablaremos de cómo medir la disponibilidad en términos más sencillos: como pruebas frente a una tasa de error o ratio de error, latencias, saturación e indicadores de utilización. No presentaremos las violaciones de estas pruebas como "errores" concretos de fiabilidad que se deducen de un presupuesto de errores en una ventana de tiempo. Si luego quieres tomar esas mediciones y aplicar el presupuesto de errores y la dinámica organizativa de la cultura SRE de Google a tu organización, puedes hacerlo siguiendo las orientaciones que se dan en los escritos de Google sobre el tema.

El monitoreo como herramienta de depuración

Los registros y las trazas distribuidas, tratadas en detalle en el Capítulo 3, se utilizan principalmente para solucionar problemas, una vez que te has dado cuenta de un periodo de indisponibilidad. Las herramientas de perfilado también son señales de depuración.

Es muy común (y fácil, dado lo confuso del mercado) que las organizaciones centren toda su inversión en gestión del rendimiento en torno a herramientas de depuración. Los proveedores de gestión del rendimiento de las aplicaciones (APM) a veces pueden venderse como una solución "todo en uno", pero con una tecnología central construida enteramente sobre el rastreo o el registro y proporcionando señales de disponibilidad mediante la agregación de estas señales de depuración.

Para no destacar a ningún proveedor en particular, considera YourKit, una valiosa herramienta de perfilado (depuración) que hace bien esta tarea sin venderse como algo más. YourKit destaca por resaltar los puntos calientes de cálculo y memoria intensivos en el código Java, y tiene el aspecto de la Figura 1-4. Algunas soluciones APM comerciales populares tienen un enfoque similar, que, aunque útil, no sustituye a una señal de disponibilidad centrada.

An image of characteristic profiling tools
Figura 1-4. TuKit destaca en la elaboración de perfiles

Estas soluciones son más granulares, ya que registran de distintas formas los detalles de lo que ocurrió durante una interacción concreta con el sistema. Esta mayor granularidad conlleva un coste, que a menudo se mitiga reduciendo el muestreo o incluso desactivando por completo estas señales hasta que se necesitan.

Los intentos de medir la disponibilidad a partir de señales de registro o de rastreo te obligan, por lo general, a sacrificar precisión por coste, y ninguna de las dos cosas puede optimizarse. Esta disyuntiva existe en el caso de las trazas porque generalmente se muestrean. La huella de almacenamiento de las trazas es mayor que la de las métricas.

Aprender a esperar el fracaso

Si aún no estás monitorizando aplicaciones de cara al usuario, en cuanto empieces, es probable que te enfrentes a la aleccionadora realidad de tu software tal y como existe hoy en día. Tu impulso será mirar hacia otro lado. Es probable que la realidad sea fea.

En una mediana empresa de seguros patrimoniales, añadimos el monitoreo a la principal aplicación empresarial que utilizan los agentes de seguros de la empresa para llevar a cabo su actividad normal. A pesar de los estrictos procesos de lanzamiento y de una cultura de pruebas razonablemente sana, la aplicación manifestaba más de 5 fallos por minuto para unas 1.000 solicitudes por minuto. Desde cierto punto de vista, esto es sólo un porcentaje de error del 0,5% (tal vez aceptable y tal vez no), pero la tasa de fallos seguía siendo un shock para una empresa que pensaba que su servicio estaba bien probado.

Darse cuenta de que el sistema no va a ser perfecto cambia el enfoque de intentar serlo a monitorizar, alertar y resolver rápidamente los problemas que experimente el sistema. Ningún control del proceso en torno al ritmo de cambio producirá resultados perfectos.

Antes de seguir evolucionando el proceso de entrega y publicación, el primer paso en el camino hacia un software resistente es añadir el monitoreo a tu software tal y como se publica ahora.

Con el paso a los microservicios y los cambios en las prácticas y la infraestructura de las aplicaciones, el monitoreo se ha vuelto aún más importante. Muchos componentes no están directamente bajo el control de una organización. Por ejemplo, la latencia y los errores pueden deberse a fallos en la capa de red, la infraestructura y los componentes y servicios de terceros. Cada equipo que produce un microservicio tiene el potencial de afectar negativamente a otras partes del sistema que no están bajo su control directo.

Los usuarios finales de software tampoco esperan la perfección, pero sí quieren que su proveedor de servicios sea capaz de resolver eficazmente los problemas. Esto es lo que se conoce como la paradoja de la recuperación del servicio, cuando un usuario del servicio confía más en un servicio después de un fallo que antes del fallo.

Las empresas deben comprender y captar la experiencia de usuario que quieren ofrecer a los usuarios finales: qué tipo de comportamiento del sistema causará problemas a la empresa y qué tipo de comportamiento es aceptable para los usuarios. Site Reliability Engineering y The Site Reliability Workbook tienen más información sobre cómo elegir esto para tu empresa.

Una vez identificados y medidos, puedes adoptar el estilo Google, como se ve en "Google's approach to SLOs", o el estilo más informal "context and guardrails" de Netflix, o cualquier punto intermedio que te ayude a razonar sobre tu software o los pasos siguientes. Consulta el primer capítulo sobre Netflix en Seeking SRE de David N. Blank-Edelman (O'Reilly) para saber más sobre el contexto y los guardarraíles. Que sigas la práctica de Google u otra más sencilla depende de tu organización, del tipo de software que desarrolles y de la cultura de ingeniería que quieras promover.

Con el objetivo de no fallar nunca sustituido por el de poder cumplir los SLA, la ingeniería puede empezar a construir múltiples capas de resistencia en los sistemas, minimizando los efectos de los fallos en la experiencia del usuario final.

Un monitoreo eficaz genera confianza

En algunas empresas, la ingeniería puede seguir considerándose una organización de servicios más que una competencia empresarial básica. En la compañía de seguros con una tasa de error de cinco fallos por minuto, ésta es la actitud predominante. En muchos casos en los que la organización de ingeniería prestaba servicio a los agentes de seguros de la empresa sobre el terreno, la interacción principal entre ellos se producía mediante la notificación y el seguimiento de los problemas de software a través de un centro de llamadas.

El departamento de ingeniería priorizaba rutinariamente la resolución de errores, basándose en los defectos aprendidos del centro de llamadas, frente a las solicitudes de nuevas funciones, y hacía un poco de ambas cosas en cada versión de software. Me preguntaba cuántas veces los agentes de campo simplemente no informaban de los problemas, bien porque una creciente acumulación de errores sugería que no era un uso eficaz de su tiempo, bien porque el problema tenía una solución suficientemente buena. El problema de enterarse de los problemas principalmente a través del centro de llamadas es que la relación era totalmente unidireccional. Los socios comerciales informan e ingeniería responde (eventualmente).

Una cultura de monitoreo centrada en el usuario hace que esta relación sea más bidireccional. Una alerta puede proporcionar suficiente información contextual para reconocer que la clasificación para una clase concreta de vehículo está fallando hoy para los agentes de alguna región. Ingeniería tiene la oportunidad de llegar a los agentes de forma proactiva con suficiente información contextual para explicar al agente que el problema ya es conocido.

Entrega

Mejorar el proceso de entrega de software disminuye la posibilidad de que introduzcas más fallos en un sistema existente (o al menos te ayuda a reconocer y revertir esos cambios rápidamente). Resulta que un buen monitoreo es un requisito previo no evidente para desarrollar prácticas de entrega seguras y eficaces.

La división entre integración continua (IC) y entrega continua (EC) tiende a difuminarse por el hecho de que, con frecuencia, los equipos programan la automatización de la implementación y ejecutan estas programaciones como parte de las compilaciones de integración continua. Es fácil reutilizar un sistema de IC como herramienta flexible de automatización del flujo de trabajo de uso general. Para hacer una clara delimitación conceptual entre ambas, independientemente de dónde se ejecute la automatización, diremos que la integración continua termina en la publicación de un artefacto de microservicio en un repositorio de artefactos, y que la entrega comienza en ese punto. En la Figura 1-5, el ciclo de vida de la entrega de software se dibuja como una secuencia de eventos desde la confirmación del código hasta la implementación.

srej 0105
Figura 1-5. La frontera entre la integración y la entrega continuas

Los pasos individuales están sujetos a diferentes frecuencias y necesidades organizativas de medidas de control. También tienen objetivos fundamentalmente distintos. El objetivo de la integración continua es acelerar los comentarios de los desarrolladores, fallar rápidamente mediante pruebas automatizadas y fomentar la fusión ansiosa para evitar la integración promiscua. El objetivo de la automatización de la entrega es acelerar el ciclo de lanzamiento, garantizar el cumplimiento de las medidas de seguridad y conformidad, proporcionar prácticas de implementación seguras y escalables, y contribuir a la comprensión del entorno desplegado para el monitoreo de los activos desplegados.

Las mejores plataformas de entrega también actúan como inventario de los activos desplegados actualmente, magnificando aún más el efecto de un buen monitoreo: ayudan a convertir el monitoreo en acción. En el Capítulo 6, hablaremos de cómo puedes construir un inventario de activos de extremo a extremo, terminando con un inventario de activos desplegados, que te permita razonar sobre los detalles más pequeños de tu código hasta llegar a tus activos desplegados (es decir, contenedores, máquinas virtuales y funciones).

La Entrega Continua no significa necesariamente Implementación Continua

La implementación realmente continua (cada confirmación que pasa las comprobaciones automatizadas llega automáticamente a producción) puede ser o no un objetivo para tu organización. En igualdad de condiciones, un bucle de retroalimentación más estrecho es preferible a un bucle de retroalimentación más largo, pero conlleva costes técnicos, operativos y culturales. Todos los temas de entrega tratados en este libro se aplican a la entrega continua en general, así como a la implementación continua en particular.

Una vez que se haya implantado un monitoreo eficaz y se introduzcan menos fallos en el sistema mediante nuevos cambios en el código, podremos centrarnos en añadir más fiabilidad al sistema en funcionamiento mediante la evolución de las prácticas de gestión del tráfico.

Gestión del tráfico

Gran parte de la resistencia de un sistema distribuido se basa en la expectativa y la compensación de los fallos. El monitoreo de la disponibilidad revela estos puntos reales de fallo, el monitoreo de la depurabilidad ayuda a comprenderlos, y la automatización de la entrega ayuda a evitar que introduzcas demasiados de ellos en cualquier versión incremental. Los patrones de gestión del tráfico ayudarán a las instancias vivas a hacer frente a la realidad siempre presente de los fallos.

En el Capítulo 7, presentaremos estrategias particulares de mitigación que implican el equilibrio de la carga (plataforma, pasarela y lado del cliente) y patrones de resiliencia de las llamadas (reintentos, limitadores de velocidad, mamparas y disyuntores) que proporcionan una red de seguridad para los sistemas en funcionamiento.

Esto se aborda en último lugar porque requiere el mayor grado de esfuerzo de codificación manual por proyecto, y porque la inversión que hagas en hacer el trabajo puede guiarse por lo que aprendas de los pasos anteriores.

Capacidades no cubiertas

Ciertas capacidades que son focos comunes de los equipos de ingeniería de plataformas no se incluyen en este libro. Me gustaría destacar un par de ellas, las pruebas y la gestión de la configuración, y explicar por qué.

Automatización de pruebas

Mi opinión sobre las pruebas es que la automatización de pruebas disponible en código abierto te lleva hasta cierto punto. Cualquier inversión más allá de eso probablemente sufrirá rendimientos decrecientes. A continuación se exponen algunos problemas que ya están bien resueltos:

  • Pruebas unitarias

  • Burlas/burlas

  • Pruebas básicas de integración, incluidos contenedores de pruebas

  • Pruebas de contrato

  • Construir herramientas que ayuden a separar los conjuntos de pruebas computacionalmente caros de los baratos

Hay un par de problemas más que creo que merece la pena evitar, a menos que realmente dispongas de muchos recursos (tanto computacionales como en tiempo de ingeniería) para gastar. Las pruebas por contrato son un ejemplo de técnica que cubre parte de lo que prueban ambas, pero de una forma mucho más barata:

  • Pruebas descendentes (es decir, cada vez que se realice una confirmación en una biblioteca, crea todos los demás proyectos que dependan de esta biblioteca, tanto directa como indirectamente, para determinar si el cambio provocará un fallo descendente).

  • Pruebas de integración de extremo a extremo de conjuntos completos de microservicios

Estoy muy a favor de las pruebas automatizadas de diversos tipos y muy recelosa de toda la empresa. A veces, al sentir la presión social de los entusiastas de las pruebas que me rodean, puede que haya seguido la moda de las pruebas del momento durante un tiempo: cobertura de pruebas del 100%, desarrollo basado en el comportamiento, esfuerzos por implicar a socios empresariales que no son ingenieros en la especificación de las pruebas, Spock, etc. Algunos de los trabajos de ingeniería más inteligentes del ecosistema Java de código abierto han tenido lugar en este espacio: considera el uso creativo que hace Spock de la manipulación del código de bytes para conseguir tablas de datos y cosas por el estilo.

Tradicionalmente, al trabajar con aplicaciones monolíticas, las versiones de software se consideraban la principal fuente de cambios en el sistema y, por tanto, de posibles fallos. Se hacía hincapié en asegurarse de que el proceso de lanzamiento de software no fallara. Se dedicaron muchos esfuerzos a garantizar que los entornos de nivel inferior reflejaran la producción para verificar que las versiones de software pendientes fueran estables. Una vez implementado y estable, se suponía que el sistema permanecería estable.

Siendo realistas, esto nunca ha sido así. Los equipos de ingeniería adoptan y redoblan las prácticas de pruebas automatizadas como remedio contra el fracaso, sólo para que éste persista obstinadamente. En primer lugar, la dirección es escéptica respecto a las pruebas. Cuando las pruebas no detectan los problemas, la poca fe que tenían desaparece. Los entornos de producción tienen la obstinada costumbre de divergir de los entornos de prueba de formas sutiles y, al parecer, siempre catastróficas. En este momento, si me obligaras a elegir entre tener una cobertura de pruebas cercana al 100% y un sistema de monitoreo de la producción evolucionado, elegiría ansiosamente el sistema de monitoreo. Esto no se debe a que piense menos en las pruebas, sino a que, incluso en empresas tradicionales razonablemente bien definidas cuyas prácticas no cambian con rapidez, el 100% de cobertura de pruebas es mítico. El entorno de producción simplemente se comportará de forma diferente. Como le gusta decir a Josh Long "No hay lugar como ese".

Un monitoreo eficaz nos avisa cuando un sistema no funciona correctamente debido a condiciones que podemos prever (es decir, fallos de hardware o indisponibilidad del servicio descendente). También aumenta continuamente nuestro conocimiento del sistema, lo que puede dar lugar a pruebas que cubran casos que antes no imaginábamos.

La práctica de pruebas por capas puede limitar la aparición de fallos, pero nunca eliminarlos, ni siquiera en las industrias con las prácticas de control de calidad más estrictas. Medir activamente los resultados en la producción reduce el tiempo de descubrimiento y, en última instancia, de corrección de los fallos. Las pruebas y el monitoreo juntos son entonces prácticas complementarias que reducen la cantidad de fallos que experimentan los usuarios finales. En el mejor de los casos, las pruebas evitan clases enteras de regresiones, y el monitoreo identifica rápidamente las que inevitablemente quedan.

Nuestras suites de pruebas automatizadas demuestran (en la medida en que no contengan ellas mismas errores lógicos) lo que sabemos sobre el sistema. El monitoreo de la producción nos muestra lo que ocurre. Aceptar que las pruebas automatizadas no lo cubren todo debería ser un gran alivio.

Dado que el código de la aplicación siempre contendrá fallos derivados de interacciones imprevistas, factores ambientales como la limitación de recursos, y pruebas imperfectas, un monitoreo eficaz podría considerarse incluso más un requisito que las pruebas para cualquier aplicación de producción. Una prueba demuestra lo que creemos que ocurrirá. El monitoreo muestra lo que ocurre.

Ingeniería del caos y verificación continua

Existe toda una disciplina en torno a la verificación continua de que tu software se comporta como esperas, introduciendo fallos controlados (experimentos de caos) y verificando. Como los sistemas distribuidos son complejos, no podemos prever todas sus innumerables interacciones, y esta forma de prueba ayuda a sacar a la superficie propiedades emergentes inesperadas de los sistemas complejos.

La disciplina general de la ingeniería del caos es amplia, y como se trata en detalle en Chaos Engineering de Casey Rosenthal y Nora Jones (O'Reilly), no entraré en ella en este libro.

Configuración como código

La Aplicación de 12 Factores enseña que la configuración debe estar separada del código. La forma básica de este concepto, la configuración almacenada como variable de entorno o recuperada al inicio desde un servidor de configuración centralizado como Spring Cloud Config Server, creo que es lo suficientemente sencilla como para no requerir ninguna explicación aquí.

El caso más complicado que implica la configuración dinámica -por la que los cambios en una fuente de configuración central se propagan a las instancias en ejecución, influyendo en su comportamiento- es en la práctica excesivamente peligroso y debe manejarse con cuidado. Junto con el cliente de configuración de código abierto Netflix Archaius (que está presente en las dependencias de Netflix de Spring Cloud y en otros lugares) había un servidor Archaius propietario que servía para este propósito. Las consecuencias imprevistas derivadas de la propagación de la configuración dinámica a las instancias en ejecución provocaron una serie de incidentes de producción de tal magnitud que los ingenieros de entrega escribieron todo un proceso de análisis canario en torno al alcance y el despliegue incremental de los cambios de configuración dinámica, utilizando las lecciones que habían aprendido del análisis canario automatizado para diferentes versiones de código. Esto va más allá del alcance de este libro, ya que muchas organizaciones nunca obtendrán un beneficio lo suficientemente sustancial del análisis canario automatizado de los cambios de código como para que ese esfuerzo merezca la pena.

La entrega declarativa es una forma totalmente distinta de configuración como código, popularizada de nuevo por el auge de Kubernetes y sus manifiestos YAML. Los comienzos de mi carrera me dejaron una sospecha permanente sobre la integridad de las soluciones sólo declarativas. Creo que siempre hay un lugar tanto para la configuración imperativa como para la declarativa. Trabajé en un sistema de administración de pólizas para una compañía de seguros que consistía en una API backend que devolvía respuestas XML y un frontend de transformaciones XSLT de estas respuestas API en HTML/JavaScript estático para ser renderizado en el navegador.

Se trataba de un extraño esquema de plantillas. Sus defensores argumentaban que el XSLT confería al renderizado de cada página una naturaleza declarativa. Y, sin embargo, resulta que el propio XSLT es Turing completo con una convincente prueba de existencia. El punto típico a favor de la definición declarativa es la simplicidad que conduce a una amenidad para la automatización como el análisis estático y la corrección. Pero como en el caso de XSLT, estas tecnologías tienen una forma aparentemente inevitable de evolucionar hacia la completitud de Turing. Las mismas fuerzas están en juego con JSON(Jsonnet) y Kubernetes(Kustomize). Estas tecnologías son indudablemente útiles, pero no puedo ser otra voz en el coro que reclama una configuración puramente declarativa. Sin llegar a este punto, no creo que este libro pueda aportar gran cosa.

Encapsular capacidades

Por muy criticada que esté actualmente la programación orientada a objetos (POO), uno de sus conceptos fundamentales es la encapsulación. En la POO, la encapsulación consiste en agrupar el estado y el comportamiento dentro de una unidad, por ejemplo, una clase en Java. Una idea clave es ocultar el estado de un objeto al exterior, lo que se denomina ocultación de información. En cierto modo, la tarea del equipo de ingeniería de la plataforma es realizar una tarea similar de encapsulación de buenas prácticas de resiliencia para los equipos de desarrolladores de sus clientes, ocultando la información no para que no la controlen, sino para liberarles de la responsabilidad de ocuparse de ella. Quizá el mayor elogio que un equipo central puede recibir de un ingeniero de producto sea "no tengo que preocuparme de lo que haces".

Los capítulos siguientes van a presentar una serie de buenas prácticas tal y como yo las entiendo. El reto para ti, como ingeniero de plataforma, es ofrecerlas a tu organización de forma mínimamente intrusiva, construir "barandillas, no puertas". Mientras lees, piensa en cómo puedes encapsular los conocimientos que tanto te ha costado adquirir y que son aplicables a todas las aplicaciones empresariales, y en cómo puedes ofrecerlos a tu organización.

Si el plan implica obtener la aprobación de un ejecutivo suficientemente poderoso y enviar un correo electrónico a toda la organización exigiendo la adopción en una fecha determinada, es una puerta. Sigues queriendo la aprobación de tus dirigentes, pero tienes que ofrecer una funcionalidad común de un modo que se parezca más a una barandilla:

Dependencias explícitas en tiempo de ejecución

Si tienes una biblioteca central que cada microservicio incluye como dependencia en tiempo de ejecución, es casi seguro que éste es tu mecanismo de entrega. Activa métricas clave, añade etiquetado de telemetría común, configura el rastreo, añade patrones de gestión del tráfico, etc. Si haces un uso intensivo de Spring, utiliza clases de autoconfiguración. Del mismo modo, puedes condicionar la configuración con CDI si utilizas Java EE.

Clientes de servicios como dependencias

Especialmente para los patrones de gestión del tráfico (fallbacks, lógica de reintentos, etc.), considera la posibilidad de que sea responsabilidad del equipo que produce el servicio producir también un cliente de servicio que interactúe con él. Al fin y al cabo, el equipo que lo produce y gestiona sabe mejor que nadie dónde están sus puntos débiles y sus posibles fallos. Esos ingenieros son probablemente los más indicados para formalizar ese conocimiento en una dependencia del cliente, de forma que cada consumidor de su servicio lo utilice de la manera más fiable.

Inyectar una dependencia en tiempo de ejecución

Si el proceso de implementación está relativamente estandarizado, tienes la oportunidad de inyectar dependencias de tiempo de ejecución en el entorno desplegado. Este fue el enfoque empleado por el equipo buildpack de Cloud Foundry para inyectar una implementación de métricas de plataforma en las aplicaciones Spring Boot que se ejecutan en Cloud Foundry. Tú puedes hacer algo parecido.

Antes de encapsular con demasiada impaciencia, busca un puñado de equipos y practica esta disciplina explícitamente en código en un puñado de aplicaciones. Generaliza lo que aprendas.

Malla de servicio

Como último recurso, encapsula la funcionalidad común de la plataforma en procesos sidecar (o contenedores) junto a la aplicación, que cuando se emparejan con un plano de control que los gestiona se denomina malla de servicios.

La malla de servicios es una capa de infraestructura externa al código de la aplicación que gestiona la interacción entre microservicios. Una de las implementaciones más reconocibles hoy en día es Istio. Estos "sidecars" realizan funciones como la gestión del tráfico, el descubrimiento de servicios y el monitoreo en nombre del proceso de la aplicación, de modo que la aplicación no necesita estar al tanto de estas preocupaciones. En el mejor de los casos, esto simplifica el desarrollo de la aplicación, a cambio de una mayor complejidad y coste en la implementación y ejecución del servicio.

En un horizonte temporal suficientemente largo, las tendencias en la ingeniería de software suelen ser cíclicas. En el caso de la fiabilidad de los sitios web, el péndulo oscila desde una mayor responsabilidad de las aplicaciones y los desarrolladores (por ejemplo, Netflix OSS, DevOps) a la responsabilidad centralizada del equipo de operaciones. El aumento del interés por la malla de servicios representa un cambio de vuelta a la responsabilidad centralizada del equipo de operaciones.

Istio promueve el concepto de gestionar y propagar políticas a través de un conjunto de microservicios desde su plano de control centralizado, a instancias de un equipo especializado en comprender las ramificaciones de estas políticas.

La venerable suite OSS de Netflix (cuyas piezas importantes tienen encarnaciones alternativas como Resilience4j para la gestión del tráfico, HashiCorp Consul para el descubrimiento, Micrometer para la instrumentación de métricas, etc.) se ocupó de estas aplicaciones. En gran medida, sin embargo, el impacto en el código de la aplicación era sólo la adición de una o más dependencias binarias, momento en el que alguna forma de autoconfiguración se hacía cargo y decoraba la lógica de la aplicación que, de otro modo, permanecería intacta. El inconveniente obvio de este enfoque es la compatibilidad lingüística, ya que la compatibilidad con cada patrón de fiabilidad del sitio requiere implementaciones de bibliotecas en cada lenguaje/marco que utilice la organización.

La Figura 1-6 muestra una visión optimista del efecto de este ciclo de ingeniería sobre el valor derivado. Con un poco de suerte, en cada transición de la descentralización a la centralización y viceversa, aprendemos de los beneficios del ciclo anterior y los encapsulamos por completo. Por ejemplo, Istio podría encapsular completamente los beneficios de la pila OSS de Netflix, sólo para que el siguiente impulso de descentralización desbloquee un potencial que era irrealizable en la implementación de Istio. Esto ya está en marcha en Resilience4j, por ejemplo, con el debate sobre formas adaptativas de patrones como los mamparos que responden a indicadores específicos de la aplicación.

srej 0106
Figura 1-6. La naturaleza cíclica de la ingeniería de software, aplicada a la gestión del tráfico

El dimensionamiento de los sidecares también es delicado, dada esta falta de conocimiento específico del dominio. ¿Cómo sabe un sidecar que un proceso de aplicación va a consumir 10.000 peticiones por segundo, o sólo 1? Si ampliamos la escala, ¿cómo dimensionamos por adelantado el plano de control de los sidecares sin saber cuántos sidecares existirán finalmente?

Los Sidecars se limitan al conocimiento del mínimo común denominador

Un proxy sidecar siempre será más débil cuando el conocimiento específico del dominio de la aplicación sea la clave para el siguiente paso en la resiliencia. Por definición, al estar separados de la aplicación, los sidecares no pueden codificar ningún conocimiento este dominio específico de la aplicación sin que sea necesaria la coordinación entre la aplicación y el sidecar. Es probable que eso sea al menos tan difícil como implementar la funcionalidad proporcionada por el sidecar en una biblioteca específica del lenguaje que pueda incluir la aplicación.

Creo que la automatización de pruebas disponible en código abierto te lleva hasta cierto punto. Cualquier inversión más allá de eso es probable que sufra de rendimientos decrecientes, como se discute en "Rastreo en Service Mesh ", y en contra del uso de sidecars para la gestión del tráfico, como en "Implementación en Service Mesh", por impopulares que puedan ser estas opiniones. Estas implementaciones tienen pérdidas en comparación con lo que puedes conseguir mediante una dependencia binaria incluida explícitamente o inyectada en el tiempo de ejecución, y ambas añaden un grado mucho mayor de funcionalidad que sólo resulta prohibitivo en términos de costes si tienes que dar soporte a un número significativo de lenguajes distintos (e incluso entonces, no estoy convencido).

Resumen

En este capítulo hemos definido la ingeniería de plataformas como, al menos, una frase marcadora de las funciones de la ingeniería de fiabilidad que trataremos a lo largo del resto del libro. El equipo de ingeniería de plataforma es más eficaz cuando tiene un enfoque orientado al cliente (donde el cliente son otros desarrolladores de la organización) en lugar de uno de control. Prueba las herramientas, la vía de adopción de esas herramientas y cualquier proceso que desarrolles según la regla de "barandillas, no puertas".

En última instancia, diseñar tu plataforma es en parte diseñar tu organización. ¿Por qué quieres que te conozcan?

1 Conocí los criterios de USO por la descripción que hizo Brendan Gregg de su método de monitoreo de sistemas Unix. En ese contexto, la medición de la latencia no es tan granular, por eso falta la L.

Get SRE con Microservicios Java now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.