Si Usted está Construyendo Microservices, Usted Necesita Entender Lo que es un Contexto Delimitado es

Mar 16, 2020 · 19 min leer

Foto por el Instituto Nacional del Cáncer en Unsplash

El crecimiento de microservice adopción ha provocado un resurgimiento de la popularidad de algunos previamente se pasa por alto, patrones de diseño software. Muchos de estos patrones han sido extraídos del Diseño impulsado por dominios de Eric Evans, un libro que trata tanto de la estructura del equipo como de la arquitectura de software.

Y de estos patrones, el Contexto Delimitado es quizás el más importante de entender. Como ingenieros, hemos llegado a considerar el Contexto Limitado como un patrón de diseño de arquitectura de software. Pero eso es porque lo hemos tomado un poco de su uso original. Tal como lo utiliza Evans, el Contexto Delimitado es tanto un patrón organizativo como técnico.

Es por eso que he llegado a ver el patrón de contexto delimitado como un eje en la comprensión de los microservicios. No solo cómo construirlos, sino realmente por qué los construimos en primer lugar, y cómo pueden hacer que nuestras organizaciones sean más exitosas. Si entendemos lo que son los Contextos Limitados, si adoptamos la mentalidad de Contexto Limitado tanto técnica como organizativamente, entonces podemos tener éxito en la construcción de nuestra arquitectura de microservicios.

¿Por qué migrar a microservicios?

Para empezar, hagamos un poco de ejercicio. Hágase esta pregunta: ¿Por qué construimos microservicios en primer lugar?

Tómese un momento para pensarlo. ¿Cuáles son los beneficios que primero vienen a la mente? ¿Cuáles son los principales problemas que debemos esperar resolver? Anota algunas respuestas, solo para ser honesto.

¿tienes tu respuesta? Bien. Léelo para ti mismo. ¿Conseguiste los beneficios técnicos estándar? ¿Entrega continua, escalabilidad, entornos políglotas, contenedores y nubes, y todo eso? Gran.

Pero, ¿su respuesta principal incluyó algo sobre permitir que su organización opere de manera más eficiente? Debería. Porque crear microservicios no se trata de obtener beneficios técnicos. En realidad, se trata de obtener beneficios organizacionales. Todo lo demás es un detalle de implementación.

Monolitos = código acoplado y equipos acoplados

A medida que nuestros monolitos crecen y crecen, la productividad comienza a disminuir. Hay al menos dos razones principales para ello.

Frenando nuestra velocidad

En primer lugar, cada equipo de ingeniería está contribuyendo a una base de código gigante. Como tal, los equipos se enfrentan a una probabilidad cada vez mayor de que su código entre en conflicto con el código de otros. Para ayudar a mitigar los posibles problemas que esto podría causar, instituimos procedimientos — congelaciones de código, períodos de prueba de control de calidad, trenes de liberación, etc. – que están literalmente diseñados para ralentizar nuestra productividad.

Por supuesto, estos procedimientos evitan que las características y mejoras se implementen de manera oportuna. También causan estragos en la capacidad de los ingenieros para centrarse en las prioridades de sus equipos. Si se encuentra un error durante un período de prueba, el equipo responsable debe cambiar de contexto y centrarse en resolver ese error. Si se encuentra un error grave en producción, el equipo no solo tiene que corregirlo, sino también saltar a través de aros para implementarlo en el próximo tren de lanzamiento.

El servicio de guardia se convierte en un despilfarro. Si algo sale mal con nuestro monolito, alguien tiene que estar disponible, de día o de noche, para resolver el problema. ¿Pero quién? Las organizaciones grandes con monolitos grandes generalmente se enfrentan a dos opciones:

  • Un equipo de gestión de incidentes cuyo único y triste trabajo dentro de la organización es responder a los problemas causados por el código de otros ingenieros y descubrir cómo resolverlos.
  • Un horario de guardia rotativo, en el que cada semana a un ingeniero arbitrario se le asigna el triste y lamentable trabajo de convertirse en responsable de resolver problemas que probablemente sean causados por código escrito por algún otro ingeniero, en algún otro equipo de ingeniería.

(Mal)organizar nuestros equipos

Los monolitos se meten con nuestras organizaciones de otra manera. Toda nuestra organización está trabajando en el mismo producto grande. Pero aún tenemos que dividir la organización en equipos manejables. Así que tendemos a buscar roles funcionales para encontrar límites de equipo:

por Desgracia, este tipo de estructura organizativa de los límites de trabajo colaborativo. En lugar de trabajar juntos para resolver el verdadero problema que tenemos entre manos (por ejemplo, ¿cómo diseñamos, construimos y mantenemos la característica X?) los miembros de las diferentes áreas funcionales simplemente se enfocan en su propia parte, metafóricamente lanzando su trabajo por encima de la valla cuando han terminado. Se pierde el potencial de colaboración y sinergia, donde la calidad combinada del esfuerzo del equipo es mucho más que la suma de los miembros individuales del equipo.

También está lleno de cuellos de botella. Cuando organizamos nuestros equipos por áreas funcionales, naturalmente tendremos una desalineación en las prioridades. Digamos que el equipo de gestión de productos decidió que el proceso de pago de nuestro monolith necesita ser renovado. Programarán tiempo con el equipo de diseño para armar algunas burlas. En algún momento, las burlas se terminarán y se entregarán al equipo de frontend para implementarlas. Por supuesto, el equipo de frontend necesitará que las API sean implementadas por el equipo de backend, por lo que se bloquearán hasta que se complete. Una vez que el equipo de backend prioriza su trabajo en los nuevos servicios de pago, descubre que necesita ayuda del equipo de Administración de Bases de datos (DBA). Que, por supuesto, tiene sus propias prioridades. Por lo tanto, el equipo de backend se bloqueará hasta que se libere un DBA.

En un camino, esta estructura organizativa parece un poco como un mal diseñada, excesivamente junto arquitectura de software… ¿no?

Microservicios = código desacoplado, equipos desacoplados

Por el contrario, una arquitectura de microservicios permite la autonomía del equipo. Se hace mucho más fácil formar equipos que sean autónomos, que trabajen juntos de manera eficiente y que no estén bloqueados constantemente por dependencias de otros equipos.

Los equipos pueden hacerse cargo de su trabajo, desde el diseño hasta el desarrollo y la implementación. Cada miembro comparte la responsabilidad de lograr el objetivo de su equipo, por lo que se les incentiva a participar en algo más que «su parte». He trabajado con equipos en los que los gerentes de producto, diseñadores, ingenieros de front-end, back-end e ingenieros móviles se han unido para diseñar características de productos, lo que produce resultados mucho mejores que los que podría haber logrado una sola persona.

El equipo adquiere la responsabilidad de sus propios artefactos una vez que se implementan en producción. Esto generalmente conduce a un código de mayor calidad que es más fácil de solucionar. ¿Por qué es eso? A diferencia de un monolito, los equipos tienden a tener una visión holística de los microservicios que poseen. Por lo tanto, es mucho más fácil para el equipo anticipar problemas, agregar buenos registros y métricas para solucionar problemas cuando ocurren, y hacer un uso adecuado de los patrones de resiliencia (por ejemplo, reintentos, disyuntores y fallas, etc.) para ayudar a evitar problemas en primer lugar.

Además, dado que los equipos tienen un sentido de propiedad total sobre su trabajo, mantener sus servicios saludables y funcionando en producción se convierte menos en un calendario de lanzamientos de pesadilla, y más en fomentar su creación.

Finalmente, los equipos están trabajando hacia el mismo objetivo, en la misma línea de tiempo. Eso significa que ya no bloqueará a una persona mientras espera a que alguien en otra área funcional se libere.

Tenemos que ser intencionales con respecto a la autonomía

Pero no obtenemos estos beneficios de forma gratuita simplemente dividiendo nuestro monolito en microservicios. Echemos un vistazo a nuestro primer, ingenuo punto de vista de un microservices arquitectura:

Si somos como la mayoría de los ingenieros, nuestra idea inicial de un microservice la arquitectura es, bueno, un montón de microservices. Cada uno expone algún tipo de API (ReST, quizás) para permitir que cualquier otro servicio lea y escriba en él.

A medida que ganamos experiencia, aprendemos que no todos los microservicios sirven para el mismo propósito, o, al menos, no deberían. Y por lo tanto, al igual que nuestro monolito habían sido dispuestas en capas, así que organizamos nuestro microservices:

En este punto, hemos definido los diferentes tipos de microservices y las aplicaciones que queremos construir. Gran. Pero todavía no hemos avanzado mucho en términos de autonomía del equipo. Cada microservicio tendrá que ser propiedad de algún equipo. Y así surge la pregunta: ¿qué equipos poseerán qué microservicios?

Equipos funcionales cruzados

Nuestro primer enfoque ingenuo podría ser organizar nuestros equipos imitando nuestra estructura de organización monolítica:

Aquí, vemos equipos (en púrpura) organizados por función: diseño de UX, ingeniería de frontend, ingeniería de backend, ingenieros de datos, DBA, QA, etc.

Esto puede parecer correcto, al menos al principio. Pero demos un paso atrás y veamos el valor que estamos tratando de ofrecer a nuestros clientes. ¿Es nuestro objetivo construir cosas como las siguientes para nuestros clientes?

  • Un montón de esquemas de base de datos
  • Un montón de maquetas de interfaz de usuario
  • Un montón de microservicios que pueden comunicarse con una base de datos MySQL?

en realidad No. Esas son solo las herramientas que utilizamos para crear valor para nuestros clientes. El valor real que ofrecemos a nuestros clientes / usuarios viene en forma de características y funcionalidades como:

  • Un catálogo de productos para buscar
  • Un mecanismo para colocar artículos en un carrito de compras y posteriormente comprarlos
  • Un sistema de notificaciones para alertar a los clientes del estado de sus compras

De manera similar, no queremos organizar nuestro equipo por área funcional. Más bien, debemos definir a nuestros equipos por el valor que crean para los clientes; es decir, en todas las funciones, en los equipos multifuncionales (bien llamados).

Con equipos multifuncionales, todos trabajan juntos para crear un producto o característica específica, de principio a fin. Todos en el equipo tienen los mismos objetivos y prioridades, por lo que ninguna área funcional está bloqueada por otra. ¿El nuevo servicio de API de backend requiere algún trabajo de diseño de base de datos? Bien; el ingeniero de backend del equipo y el DBA pueden priorizar su trabajo juntos.

En su mejor momento, los equipos multifuncionales animan a los miembros a colaborar en cada fase del proyecto. Cada miembro del equipo contribuye al diseño general de la función. Los ingenieros de Frontend, backend y mobile definen conjuntamente los contratos de API. Todos hacen pruebas. Y todo el mundo comienza a estar bien versado en su dominio particular.

Y así, nuestro equipo de estructuras podrían empezar a buscar algo como esto:

Eso es mejor. Pero algo aún no se siente bien.

Claro, hemos formado equipos que probablemente serán más efectivos en la posesión de productos. Pero todavía hemos adoptado un enfoque descendente para identificar la topología de microservicios que nuestra organización tiene la intención de crear. Nos queda una gran colección de microservicios interdependientes, la mayoría de los cuales están acoplados. Simplemente los hemos asignado a diferentes equipos para construir.

Esto genera preocupaciones como:

  • ¿Cómo podemos crear API que satisfagan todas las necesidades actuales y futuras que pueda tener cualquier cliente? ¿Podemos encapsular nuestros datos cuando cualquiera de nuestros servicios pueda ser llamado por los servicios de cualquier otro equipo?
  • ¿Cuánto tiempo perderemos esperando que otros equipos implementen nuestras dependencias?
  • ¿Qué fallos de nuestros sistemas podrían ser causados por fallos en otros sistemas (fallos en cascada)?
  • ¿Podemos controlar el número de llamadas en las que pueden estar involucrados nuestros servicios? ¿Podemos asegurarnos de que nuestra organización no termine creando llamadas sincrónicas ilimitadas entre servicios, lo que llevará a tiempos de respuesta astronómicos, o peor (y sí, he visto que esto sucede) llamadas infinitamente recursivas entre servicios?
  • ¿Qué sucede si la característica específica o el espacio de problemas de nuestro equipo no son adecuados para la topología de microservicios planificada previamente?

Necesitamos una forma de pensar diferente. ¿Tal vez ya exista un patrón para que lo sigamos?

Introduzca el contexto delimitado

El contexto delimitado es un patrón de diseño clave derivado del diseño basado en dominios, o DDD. Comprender el Contexto Limitado nos ayuda a formar equipos autónomos y, por extensión, arquitecturas de microservicios autónomas.

DDD describe una metodología de desarrollo de software en la que los individuos dentro de una organización trabajan juntos para definir un lenguaje común. En su libro Domain Driven Design, Eric Evans con frecuencia representa a ingenieros que trabajan con propietarios de productos para establecer un vocabulario acordado para describir cosas como productos, componentes de los productos, acciones que un producto puede realizar (o se puede realizar en el producto), partes de flujos de trabajo, etc. Este vocabulario abarca el dominio de la organización.

En muchas organizaciones grandes, sin embargo, definir un vocabulario único y consistente se vuelve inviable. En estos casos, dividimos nuestro dominio en subdominios. Ejemplos de subdominios podrían incluir:

  • Gestión de inventario
  • Descubrimiento de productos
  • Gestión de pedidos
  • Carritos de compras y caja

Como diseñadores, ingenieros, gerentes de productos, etc., se reúnen para construir un subdominio, forman su propia forma de pensar y hablar sobre el subdominio y sus componentes.

Aquí es donde DDD se encuentra con la estructura de equipo multifuncional. Aunque los miembros del equipo provienen de diferentes áreas funcionales, son responsables de su propio subdominio, y eventualmente se convierten en expertos residentes. Además, el equipo es responsable de determinar qué artefactos (microservicios, aplicaciones web, aplicaciones móviles, bases de datos e infraestructura relacionada) se necesitan para dar vida al subdominio y a los clientes de la organización.

podemos pensar en el equipo y sus artefactos, que comprende un Contexto Delimitado.

Definir el Contexto Delimitado

Mientras Evans discute los Contextos Delimitados con frecuencia en su libro, en realidad no define el patrón explícitamente. Así que intentaré hacerlo aquí:

Contexto delimitado:

Un sistema internamente consistente con límites cuidadosamente diseñados que median lo que puede entrar en el sistema y lo que puede salir de él.

En otras palabras, un contexto delimitado representa un contexto, esencialmente, un sistema que encapsula componentes cooperativos, con límites claramente definidos que rigen lo que puede entrar en el sistema y lo que puede salir de él.

las Células (esas pequeñas cosas, que en conjunto constituyen todos los seres vivos) ofrecen una buena analogía. Dentro de una célula hay todo tipo de componentes (el núcleo, los ribosomas, el citoplasma, los citoesqueletos, etc.) que están encapsulados dentro de la propia célula. Alrededor de cada célula, sin embargo, hay una membrana, que actúa como barrera entre el interior de la célula y el resto del organismo. La membrana protege a la célula de su entorno, permite que entren nutrientes específicos y permite que salgan varios subproductos.

En la misma línea, un contexto delimitado consiste en una variedad de componentes (microservicios, aplicaciones web, aplicaciones móviles, bases de datos, colas de mensajes, etc.). También sirve como una barrera lógica que encapsula esos componentes. Internamente, los componentes se pueden acoplar y pueden pasar datos libremente entre sí. Pero el Contexto Acotado ayuda a reforzar el acoplamiento suelto externamente, definiendo puntos explícitos donde:

  • los datos externos pueden entrar (tal vez a través de un consumidor suscrito a un tema de Kafka)
  • los datos internos pueden salir (tal vez a través de otro tema de Kafka, o a través de una API GET de well-design, cuidadosamente diseñada para ocultar cualquier detalle interno del sistema)

Un contexto delimitado también representa a su equipo multifuncional. El equipo está formado por varios miembros del equipo (diseñadores, ingenieros de frontend/backend/mobile, gerentes de producto, ingenieros de datos e ingenieros de control de calidad, etc.). Internamente, estos miembros trabajan en cooperación para lograr los mismos objetivos coherentes. Además, estos miembros del equipo están (o deberían estar) encapsulados para que tengan una dependencia mínima de otros equipos.

Por lo tanto, en lugar de comenzar a nivel organizacional y definir todas las aplicaciones y microservicios que esperamos crear, creamos equipos en torno a nuestros subdominios, lo que permite a esos equipos hacer crecer sus subdominios y definir lo que se necesita crear. Si se hace correctamente, tendemos a ver que varios Contextos Limitados en la organización crecen orgánicamente, en lugar de ser estructuras rígidas predefinidas.

Implicaciones para romper el monolito

La Ley de Conway nos dice que las organizaciones diseñan sistemas de software que imitan la estructura de comunicación de su organización. Eso a menudo resulta ser cierto, por lo que debemos ser reflexivos sobre cómo estructuramos nuestra organización a medida que comenzamos a crear microservicios.

De hecho, a estas alturas, una imagen debería estar emergiendo en tu mente. A medida que nos movemos de monolito a microservicios, debemos comenzar a pensar verticalmente (dividiendo el monolito por sus subdominios) en lugar de horizontalmente (dividiendo el monolito por sus capas funcionales).

Debemos de dividir las cosas no como los que tenemos en la izquierda, pero a medida que nos hacemos a la derecha

En otras palabras, no deberíamos empezar por sustituir el monolito de la capa de acceso a datos con datos microservices. Más bien, deberíamos comenzar dividiendo una función completa (como el proceso de pago, o quizás la búsqueda de productos). Cada característica representará un Contexto Delimitado. Y cada uno será dividido por un equipo multidisciplinario dedicado.

Además, ese equipo debe centrarse en su tarea, que es:

  • replicar fielmente la funcionalidad existente,
  • o (mejor) construir una experiencia totalmente nueva y mejorada para sus clientes.

Como parte del proceso, el equipo debe diseñar el sistema que mejor se adapte a la tarea.

Por ejemplo, podríamos decidir quitar nuestra funcionalidad de búsqueda de productos de nuestro monolito. En última instancia, el equipo de búsqueda de productos podría diseñar un sistema que incluya:

  • Consumidores de Kafka que escuchan una serie de temas externos de Kafka para actualizar su propio sistema interno de registro (SoR) de productos.
  • un editor de Kafka que introduce cambios en su SoR en un tema interno de Kafka
  • otro consumidor de Kafka que escucha ese tema interno y actualiza un índice de búsqueda elástica
  • un punto final GraphQL para búsquedas de forma libre que consulta Elastic Search
  • un punto final ReST que recupera productos individuales por ID
  • una aplicación web rediseñada que utiliza esos puntos finales para permitir a los clientes buscar productos y explorar los detalles del producto
  • aplicaciones que usan esos endpoints
  • Un editor de Kafka que envía mensajes, representar consultas distintas realizadas por clientes, a un tema externo de Kafka, para su uso por cualquier otro contexto delimitado (por ejemplo, análisis) que pueda estar interesado

Cómo podría ser el diseño de nuestro Contexto Delimitado de búsqueda de productos, encapsulado en rojo,

A medida que comenzamos a despegar más y más partes verticales de nuestro monolito, otros equipos construyen sus propios Contextos delimitados. Estos contextos acotados podrían terminar pareciendo bastante diferentes unos de otros.

Cada equipo determina cómo aprovechar mejor resolver su tarea en mano

Observe que los componentes dentro de un determinado Contexto Delimitado podría ser estrechamente unida; sin embargo, estamos cumpliendo con nuestra Limitada Contextos desconectados el uno del otro. En nuestro ejemplo, cualquier comunicación entre Contextos delimitados ocurre al pasar mensajes a través de una cola de mensajes Kafka. Es importante destacar que estamos evitando llamadas de solicitud/respuesta sincrónicas entre Contextos acotados.

Esto también es cierto con lo que queda del monolito. Ciertamente, no queremos un acoplamiento estrecho entre nuestros nuevos microservicios y nuestro monolito heredado. Así que a medida que despegamos partes del monolito, aprovechamos el paso de mensajes para permitir que las partes restantes se comuniquen con nuestros nuevos Contextos Limitados.

Comprobación de la realidad de todo este desacoplamiento

En este punto, podemos preguntarnos si es realmente posible mantener nuestros Contextos Delimitados desacoplados.

En el mundo real, ¿realmente podemos mantener a nuestros equipos protegidos de dependencias externas? ¿Nunca habrá casos en los que un equipo deba ser bloqueado por otro equipo para realizar su trabajo?

¿Y podemos crear arquitecturas de servicio para nuestros subdominios que estén completamente desacopladas de otros subdominios? ¿Realmente no hay necesidad de una aplicación en un Contexto Limitado para llamar sincrónicamente a un servicio en otro?

En realidad, puede ser imposible mantener nuestros Contextos Acotados 100% desacoplados. Pero podemos acercarnos, mucho más de lo que la mayoría de nosotros podría pensar.

Arquitecturas de la vida real

Comencemos por las arquitecturas desacopladas. A menudo creemos en la falacia de que cualquier tipo de datos debe vivir exactamente en una ubicación, y que cualquier otro sistema debe llamar directamente a esa ubicación para acceder a los datos.

Nos referimos a esto como asignar una Única Fuente de Verdad (SSoT) a nuestros datos. Pero como se describe en este artículo que analiza la idea de SSoTs, esa misma noción es, en general, un anti-patrón. En su lugar, la mayoría de los contextos delimitados deben almacenar su propia copia local de cualquier dato que necesiten usar.

Esto se ejemplifica en nuestro Contexto limitado a la búsqueda de productos de la sección anterior. Este contexto limitado, por supuesto, depende en gran medida de los datos del catálogo de productos de nuestra organización. Pero lo más probable es que los datos se generen en un Contexto Delimitado diferente (lo llamaremos Contexto Delimitado de Entrada de Producto).

Nuestro primer enfoque (ingenuo) podría ser exponer una API ReST desde el Contexto Limitado a la Entrada de Producto y forzar a los servicios dentro del Contexto Limitado a la Búsqueda de Productos a llamar a esa API. Pero podemos hacerlo mejor. En su lugar, podemos mantener los sistemas desacoplados publicando los cambios realizados por los servicios de Entrada de Productos en Kafka. Nuestros consumidores de Búsqueda de productos de Kafka luego recogen esos mensajes y actualizan las bases de datos de Búsqueda de productos.

tenga en cuenta que los dos Contextos Limitada eventualmente-en consonancia. Esto significa que habrá breves períodos de tiempo en los que un dato determinado podría ser inconsistente entre la Entrada de Productos y la Búsqueda de Productos. Por ejemplo, si el precio de los Widgets Wombat blancos aumenta de $1,99 a 2 2.49, habrá un breve período de tiempo (a menudo una cuestión de segundos, si no milisegundos) donde hay una diferencia de 50¢ en el precio del Widget Wombat Blanco en los dos Contextos limitados.

Esto conduce a los casos del mundo real en los que no tenemos otra alternativa que emparejar Contextos limitados. En algunos casos, la coherencia final no es aceptable. Por ejemplo, antes de que un cliente pueda completar su compra en línea, es posible que necesitemos asegurarnos de que todos los artículos de su carrito de compras estén, de hecho, disponibles en ese momento. Incluso entonces, a menudo podemos minimizar el acoplamiento entre los dos Contextos Acotados.

Nuestras interacciones pueden tener este aspecto:

  • A medida que el cliente utiliza la interfaz de usuario de Búsqueda de productos para encontrar productos, las bases de datos de búsqueda de productos se utilizan para recuperar información (como estilos, opiniones de clientes, precios, etc.).) sobre los productos
  • Incluso cuando el cliente comienza el proceso de pago, seguimos utilizando las bases de datos de búsqueda de productos para recuperar la información que debe mostrarse.
  • Finalmente, cuando el cliente hace clic en ese botón final de «Completar compra», hacemos una sola llamada sincrónica al Contexto Limitado a la Entrada del Producto para validar la disponibilidad de los artículos antes de completar la compra.

Otro ejemplo común que requiere consistencia inmediata relacionada con la autorización. En muchos sistemas, los tokens de seguridad deben recuperarse o validarse en cada solicitud. En esos casos, probablemente necesitemos permitir que nuestros Contextos Limitados llamen a otro Contexto Limitado orientado a la seguridad.

Estructuras de organización de la vida real

¿Qué tal equipos autónomos y multifuncionales? ¿Cuán posibles son en el mundo real?

En realidad, es un proceso de movimiento continuo hacia equipos totalmente autosuficientes. Rara vez alcanzaremos el 100% de autonomía con nuestros equipos. Pero si comenzamos organizando nuestros equipos de manera inteligente, y reconocemos y respondemos a los cuellos de botella que surgen, podemos acercarnos.

Para empezar, debemos maximizar nuestros equipos verticales y multifuncionales y minimizar el número de equipos horizontales y funcionales únicos. Eso significa resistir el impulso de formar los llamados equipos «centrales», cuya misión es crear servicios de datos comunes que consuman otros equipos orientados a productos, y en su lugar formar nuestros equipos en torno al valor empresarial que proporcionarán.

Muchas organizaciones avanzan de puntillas hacia este objetivo, formando primero equipos de gerentes de producto orientados al dominio e ingenieros de front-end y back-end. Es un comienzo. Pero, ¿a quién más deberían incluir estos equipos? La membresía exacta puede diferir entre diferentes equipos con diferentes necesidades. Pero deberíamos considerar cosas como:

  • Si nuestro equipo tiene ingenieros de front-end, lo más probable es que trabajen en estrecha colaboración con un diseñador gráfico dedicado al dominio.
  • Los ingenieros móviles, a menudo secuestrados en su propia área de la organización, deben incluirse en dominios con un componente móvil.
  • En su esclarecedor artículo sobre mallas de datos, Zhamak Dehghani lamenta que los ingenieros de datos a menudo se excluyan de los equipos multifuncionales — en detrimento de los ingenieros de datos y de los propios equipos multifuncionales.

Una vez que hayamos determinado la composición de nuestros equipos, deberíamos estar atentos a los cuellos de botella. ¿Hay otros equipos que bloqueen habitualmente la productividad de nuestros equipos multifuncionales?

Por ejemplo, muchas organizaciones tienen un equipo de seguridad dedicado. Esta es una buena práctica, por supuesto; las organizaciones necesitan una estrategia de seguridad coherente y una forma de garantizar la gobernanza de esa estrategia. Sin embargo, también es común que los equipos detengan su trabajo en varias etapas para permitir revisiones de seguridad de su trabajo. Incluso en la mejor de las situaciones, esto establece obstáculos para nuestros equipos como una práctica rutinaria de negocios. Además, a menudo hará que los equipos tengan que desechar todo o parte de su trabajo y comenzar de nuevo, ya que descubren requisitos de seguridad que no se habían cumplido.

Esto es claramente un mal olor. Pero, ¿cómo podemos hacer cumplir los estándares de seguridad de nuestra organización al tiempo que permitimos que los equipos permanezcan autónomos y productivos?

Podemos hacer esto agregando ingenieros de seguridad a nuestros equipos multifuncionales. Hay tres enfoques que podemos tomar:

  • Si tenemos la suerte de tener un equipo de seguridad relativamente grande, podemos asignar a cada equipo multifuncional un ingeniero de seguridad (SE) a tiempo completo.
  • Con equipos de seguridad más pequeños, cada SE puede asignar a un número de equipos multifuncionales de manera a tiempo parcial. Esto todavía permitiría al SES comprender los objetivos y diseños de los equipos, y trabajar con el equipo para cumplir con los estándares de seguridad de la organización durante todo el proceso.
  • Si no tenemos suficientes recursos de seguridad para ninguno de los dos, podemos movernos en la dirección opuesta. En lugar de incorporar a miembros del equipo de seguridad a nuestros equipos multifuncionales, podemos llevar a miembros de los equipos multifuncionales al equipo de seguridad. Cada equipo multifuncional designaría uno o dos representantes de seguridad. Los representantes se reunirían periódicamente con los servicios de seguridad y se mantendrían al corriente de los requisitos y normas de seguridad de la organización. Es posible que ellos mismos no sean expertos en seguridad. Pero podrán desempeñar el papel de ingeniero de seguridad, asegurando que sus equipos se adhieran a las prácticas de seguridad de la organización.

Gremios

Esto encaja en otro patrón organizativo que ha ido ganando terreno: gremios. El modelo de gremio nació del modelo de equipo multifuncional. Por su naturaleza, esos equipos están poblados de miembros que se especializan en diferentes funciones. Sin embargo, a menudo tiene sentido que las personas que se especializan en una función específica también se reúnan; por ejemplo, para:

  • Perfeccione sus habilidades y aprenda unos de otros
  • Descubra y establezca las mejores prácticas para su función particular
  • Dependiendo de la función, cree estándares y requisitos de la empresa

Nuestra última solución de seguridad formó efectivamente un «gremio de seguridad». Los miembros del equipo trabajaban principalmente con sus equipos verticales; pero periódicamente, algunos de ellos se reunían con el «gremio» de seguridad para discutir las prácticas y estándares de seguridad de la organización.

El modelo de gremio también funciona particularmente bien cuando se trata de arquitectura de software. En particular, con una arquitectura de microservicios, se requiere cierto nivel de gobernanza técnica en toda la organización. Sin embargo, tener un grupo de arquitectos sentados en una torre de marfil metafórica, repartiendo reglas a los equipos, generalmente es contraproducente. En su lugar, los ingenieros principales/sénior de nuestros equipos multifuncionales pueden reunirse periódicamente en un gremio de arquitectura. Allí, pueden plantear problemas de sus equipos, encontrar soluciones y establecer patrones y estándares.

Ejemplos de la vertical de la cruz-funcionales de los equipos, complementado por la horizontal gremios

los Gremios también puede ser extendido a casi todas las otras funciones. Después de todo, queremos que los diseñadores de out desarrollen y trabajen a partir de una guía de estilo de interfaz de usuario común. Queremos que nuestros ingenieros de frontend utilicen los mismos elementos de interfaz de usuario. Los ingenieros de control de calidad deben estar alineados con la forma en que se realizan las pruebas en nuestras organizaciones. Y los gerentes de producto deben estar sincronizados con la hoja de ruta general del producto de la organización.

Unirlo todo

Pasar a los microservicios puede mejorar drásticamente la productividad de nuestros equipos. Pero necesitamos entender cómo aprovechar una arquitectura de microservicios para llegar allí. De todos los patrones de diseño y conceptos relacionados con los microservicios, el Contexto Limitado es posiblemente el más importante para darnos esa comprensión.

Con una comprensión sólida del Contexto Limitado, entendemos que:

  • Nuestra estructura organizativa y nuestra arquitectura técnica van de la mano
  • Nuestros equipos orientados a productos deben tener una dependencia mínima de otros equipos, al igual que los sistemas que crean deben estar desacoplados de otros sistemas

En general, abrazar el Contexto Limitado pone en la mentalidad que necesitamos para tener éxito con nuestra arquitectura de microservicios. Asegúrese de comprender este importante patrón antes de embarcarse en su viaje a los microservicios.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.