división del monolito
De monolito a microservicios: el primer servicio fuera en 20 días
Once años de commits en un solo desplegable, cuatrocientas tablas en un solo esquema, un tren de publicación que sale una vez por trimestre. Encontramos por dónde se separan los datos de verdad, partimos primero el esquema y sacamos un servicio que compila, se despliega y lleva su propia guardia. Rails, Django, Spring, .NET, PHP o Go: el método es el mismo, y el segundo servicio va más rápido porque la parte difícil ya está hecha.
20 días para el primer servicio, y menos para el segundo
Dos servicios y una librería. El número de servicios debería coincidir con el número de equipos capaces de llevar su guardia.
Un desplegable
Un repositorio, un esquema, un tren de publicación e imports que van en círculo.
- one deployable11 years of commits
- shared schema400+ tables
- release trainquarterly
- circular importscycles
Partido
Dos servicios con sus propios esquemas, una librería para lo compartido y despliegues separados.
- billingGo · own schema
- catalogueGo · own schema
- shared kernellibrary
- deploysper service
20 días para el primer servicio, y menos para el segundo
Cómo va el trabajo
- 01días 1–4
Encontrar las costuras en los datos
Los logs de consultas enseñan qué tablas se leen juntas en la misma petición. Ahí están las fronteras, diga lo que diga la estructura de paquetes.
- 02días 3–8
Separar primero el esquema
Partir las tablas y quitar los joins que cruzan la frontera mientras todo sigue siendo un solo desplegable. Casi todo el riesgo vive en este paso, y a estas alturas todavía es reversible.
- 03días 8–15
Extraer un servicio
El que tiene menos dependencias entrantes, que rara vez es el que más molesta a la gente. Sale detrás de la misma interfaz hasta que operarlo deja de ser interesante.
- 04días 14–20
Darle su propia canalización
Repositorio propio, despliegue propio, guardia propia. Un servicio cuyas publicaciones siguen teniendo que coordinarse con el monolito no le ha dado nada, y eso se ve el día quince y no al final.
Qué hace la plataforma y qué hace una persona
| Qué hace la plataforma y qué hace una persona | Quién hace qué | Notas |
|---|---|---|
| Mapear el acceso conjunto a tablas y el acoplamiento entre módulos | Plataforma | Desde los logs de consultas y el grafo de llamadas, sobre un periodo lo bastante largo como para incluir un cierre. |
| Proponer las costuras | Los dos | La plataforma ordena las candidatas. Una persona las contrasta con las fronteras de sus equipos. |
| Romper los joins que cruzan la frontera | Plataforma | Trabajo mecánico, revisado como merge requests y entregado en trozos pequeños. |
| Elegir qué servicio va primero | Ingeniero | Quién es dueño de qué decide esto más a menudo que el código. |
| Las fronteras transaccionales | Ingeniero | Donde una transacción de base de datos cruzaba la costura, alguien tiene que decidir qué pasa cuando falla. |
| CI, despliegue y guardia | Los dos | Un servicio sin su propia canalización y su propia guardia es un módulo con saltos de red de más. |
Quién corta la costura
Decenas de migraciones, más de diez años sobre sistemas construidos por gente que ya se fue y divisiones suficientes para saber cuáles compensan. Monolitos en Rails, Django, Spring, .NET, PHP y Go, esquemas con cuatrocientas tablas y una década de joins que cruzan fronteras. La costura nunca está donde dice el diagrama de arquitectura, y encontrar la de verdad es casi todo lo que está comprando.
La primera extracción es la prueba y está acotada: un servicio, su propio esquema, su propio despliegue, en producción. Tiene una respuesta que funciona por el precio de una fase.
Preguntas que nos hacen los ingenieros
- ¿Con cuántos servicios deberíamos acabar?
- Con menos de los del diagrama de la presentación de arquitectura. Extraiga uno, opérelo en producción un trimestre y luego decida sobre el siguiente. Los equipos que planifican doce por adelantado acaban con cuatro y con mucha base de datos compartida.
- ¿Hay que reescribir en Go?
- No. Extraer y reescribir son decisiones separadas, y muchas divisiones se quedan en el lenguaje original. Donde sí reescribimos un servicio es porque ese módulo iba a reescribirse de todos modos, viviera donde viviera.
- ¿Qué pasa con el código compartido?
- Se convierte en una librería versionada con poca superficie. Cuando el núcleo compartido empieza a crecer en cada sprint, esa es la señal de que su costura estaba en el sitio equivocado, y moverla ahora sale mucho más barato que en el segundo año.
- ¿Podemos hacer esto mientras sacamos funcionalidad?
- Sí, y por eso irá más lento. El paso que hay que proteger es la separación del esquema: meter trabajo de funcionalidad ahí es como estos proyectos se quedan un año atascados con la base de datos partida por la mitad.
- ¿Y la base de datos compartida de la que todos avisan?
- Por eso el esquema va primero. Dos servicios sobre un mismo esquema son un monolito distribuido con peores modos de fallo que el punto de partida, y es la forma más común de hacer mal este trabajo.
Empiece por una extracción
El tamaño, la frecuencia de publicación y qué está forzando el cambio bastan para una primera respuesta. Volvemos con dónde parece que están las costuras y qué haría falta para el primer servicio.
Contesta un ingeniero, y la primera pregunta suele ser sobre su ritmo de publicación.