190 lecturas

Startups, ¿Realmente quieres pagar el impuesto a los microservicios?

por Oleg Pustovit15m2025/05/12
Read on Terminal Reader

Demasiado Largo; Para Leer

Los microservicios prematuros drenan la velocidad de su startup con complejidad y sobrecarga.
featured image - Startups, ¿Realmente quieres pagar el impuesto a los microservicios?
Oleg Pustovit HackerNoon profile picture

Por qué dividir su base de código demasiado temprano puede destruir silenciosamente la velocidad de su equipo - y qué hacer en su lugar.

Por qué dividir su base de código demasiado temprano puede destruir silenciosamente la velocidad de su equipo - y qué hacer en su lugar.


En una startup,your survival depends on how quickly you can iterate, ship features, and deliver value to end-usersAquí es donde la arquitectura fundamental de su startup juega un gran papel; además, cosas como su tech stack y la elección del lenguaje de programación afectan directamente a la velocidad de su equipo.La arquitectura equivocada, especialmente los microservizos prematuros, pueden dañar sustancialmente la productividad y contribuir a los objetivos perdidos en la entrega de software.


He tenido esta experiencia cuando trabajé en proyectos de campo verde para startups de etapa temprana, donde se tomaron decisiones cuestionables en términos de arquitectura de software que condujeron a servicios semi-acabados yConfiguraciones locales frágiles, sobre-ingenieras y rotas, ydemoralized teamsque luchan por mantener la complejidad innecesaria.


Antes de sumergirse en trampas específicas, aquí está lo que realmente está registrando cuando introduce microservicios prematuramente:


Microservices Early On: What You’re Paying For

Pain Point

Real-World Manifestation

Developer Cost

Deployment Complexity

Orchestrating 5+ services for a single feature

Hours lost per release

Local Dev Fragility

Docker sprawl, broken scripts, platform-specific hacks

Slow onboarding, frequent breakage

CI/CD Duplication

Multiple pipelines with duplicated logic

Extra toil per service

Cross-Service Coupling

"Decoupled" services tightly linked by shared state

Slower changes, coordination tax

Observability Overhead

Distributed tracing, logging, monitoring

Weeks to instrument properly

Test Suite Fragmentation

Tests scattered across services

Brittle tests, low confidence

Complejidad de despliegue

Orquestación de 5+ servicios para una única característica

Hours lost per release

La fragilidad de Dev

Docker spread, scripts rotos, hacks específicos de la plataforma

Slow onboarding, frequent breakage

Duplicación CI/CD

Múltiples tuberías con lógica duplicada

Extra toil per service

Servicio Cross Coupling

Servicios "desconectados" estrechamente vinculados por el estado compartido

Slower changes, coordination tax

Observación Overhead

Seguimiento distribuido, logging, monitorización

Weeks to instrument properly

Test Suite Fragmentación

Pruebas dispersas a través de servicios

Brittle tests, low confidence

Descubrimos por qué los microservicios a menudo retroceden temprano, dónde realmente ayudan, y cómo estructurar los sistemas de su startup para la velocidad y la supervivencia.

Los monolitos no son el enemigo

Si está construyendo algún producto SaaS, incluso un simple envuelto de base de datos SQL eventualmente puede traer mucha complejidad interna en la forma en que funciona su lógica empresarial; además, puede acceder a varias integraciones y tareas de fondo que permiten transformar un conjunto de datos en otro.


Con el tiempo, a veces características innecesarias, es inevitable que su aplicación pueda volverse confusa.La gran cosa sobre los monolitos es: todavía funcionan.Monoliths, even when messy, keep your team focused on what matters most:


  • Mantenerse vivo
  • Entrega de valor al cliente


La mayor ventaja de los monolitos es su simplicidad en la implementación.En general, tales proyectos se construyen en torno a marcos existentes - podría ser Django para Python,Página web.netpara C#, Nest.js para aplicaciones de Node.js, etc. Cuando se adhiere a la arquitectura monolítica, se obtiene la mayor ventaja sobre los microservicios fantásticos: un amplio apoyo de la comunidad de código abierto y los mantenedores de proyectos que diseñaron principalmente esos marcos para trabajar como un único proceso, una aplicación monolítica.


En una startup inmobiliaria donde dirigí el equipo front-end, y ocasionalmente consulté al equipo backend sobre opciones tecnológicas, tuvimos una interesante evolución de una aplicación basada en Laravel.


Con el tiempo, se ha convertido en una suite rica en características que manejaba cientos de gigabytes de documentos e integrado con docenas de servicios de terceros.



El equipo se basó fuertemente en las mejores prácticas recomendadas por la comunidad Laravel.Esta disciplina se pagó, pudimos escalar significativamente las capacidades de la aplicación, mientras que todavía cumplió con las necesidades y expectativas del negocio.


Curiosamente, nunca tuvimos que desconectar el sistema de los microservicios o adoptar patrones de infraestructura más complejos. Evitamos una gran cantidad de complejidad accidental de esa manera. La simplicidad de la arquitectura nos dio un empuje.“Majestad Monolítica”, que explica por qué la simplicidad es un superpoder temprano.


La gente a menudo señala que es difícil hacer que los monolitos sean escalables, pero es mala modularizaciónpor dentroEl monolito que puede traer tales problemas.


Takeaway: A well-structured monolith keeps your team focused on shipping, not firefighting.

¿Pero no son los microservices la “mejor práctica”?

Muchos ingenieros se acercan a los microservicios temprano, pensando que son “el camino correcto”.Y seguro – a escala, pueden ayudar.


Los microservicios solo se pagan cuando tienes problemas reales de escala, grandes equipos o dominios que evolucionan de forma independiente. Antes de eso? ¿Estás pagando el precio sin obtener el beneficio: infra-duplicado, configuraciones locales frágiles y iteración lenta.SegmentFinalmenteRevertir la división de los microserviciospor esa razón exacta: demasiado costo, no suficiente valor.


Takeaway: Microservices are a scaling tool — not a starting template.

Dónde los microservicios van mal (especialmente temprano en)

En un equipo de etapa temprana que asesoré, la decisión de dividir los servicios creó más coordinación de la ingeniería PM que ganancias técnicas.La arquitectura no solo influyó en el código, sino en la forma en que planificamos, estimamos y enviamos.

Diagram: Coordination overhead grows linearly with services — and exponentially when you add product managers, deadlines, and misaligned timelines.



Aquí están los antipatrones más comunes que crecen temprano.

Los límites del servicio arbitrario

En teoría, a menudo se ven sugerencias sobre la división de sus aplicaciones por dominios de lógica empresarial - servicio de usuarios, servicio de productos, servicio de pedidos, etc. Esto a menudo se emprende de los conceptos de Diseño impulsado por dominio o arquitectura limpia - que tienen sentido a escala, pero en productos de etapa temprana, pueden ossificar la estructura prematuramente, antes de que el producto mismo sea estable o validado.


  • Bases de datos compartidas
  • Cross-Service requiere flujos de trabajo sencillos
  • El acoplamiento disfrazado como “separación”


En un proyecto, vi a un equipo separando el usuario, la autenticación y la autorización en servicios separados, lo que llevó a la complejidad de la implementación y dificultades en la coordinación del servicio para cualquier operación de API que estaban construyendo.


En realidad, la lógica empresarial no mapea directamente los límites del servicio.La separación prematura puede hacer que el sistema sea más frágil y a menudo es difícil introducir cambios rápidamente.


En su lugar, aislamiento de las garrafas quirúrgicamente - basado en el dolor de escala real, no la elegancia teórica.


Cuando he entrenado a los equipos de etapa temprana, a veces usamos banderas internas o agujeros de despliegue para simular futuras divisiones de servicio - sin la carga operativa inmediata.


Takeaway: Don’t split by theory — split by actual bottlenecks.

Repositorio e Infraestructura Sprawl

Cuando se trabaja en la aplicación, por lo general, el siguiente conjunto de cosas es importante:

  • Coherencia de estilo de código (linting)
  • Pruebas de infraestructura, incluidas las pruebas de integración
  • Configuración del entorno local
  • Documentación
  • Configuración CI/CD


Si su proyecto está estructurado como un monorepo, puede simplificar su vida al tener una configuración CI/CD central (cuando trabaja con GitHub Actions o GitLab CI).Algunos equipos separan microservicios en repositorios separados, lo que hace que sea mucho más difícil mantener la coherencia del código y el mismo conjunto de configuraciones sin esfuerzo o herramientas adicionales.


Para un equipo de tres personas, esto es brutal.El cambio de contexto entre repositorios y herramientas agrega el tiempo de desarrollo de cada característica que se envía.

Mitigación de problemas utilizando monorepos y un lenguaje de programación único

Hay varias maneras de mitigar este problema. Para proyectos tempranos, lo más importante es mantener su código en un monorepo. Esto asegura que existe una única versión de código que existe en el prod, y es mucho más fácil coordinar las revisiones de código y colaborar para equipos más pequeños.


Para los proyectos de Node.js, recomiendo usar una herramienta monorepo comonxoturborepoLos dos:

  • Simplificar la configuración de CI/CD en los subproyectos
  • Soporte de cache de construcción basado en gráficos de dependencia
  • Trate los servicios internos como bibliotecas TypeScript (a través de las importaciones ES6)


Estas herramientas ahorran tiempo de lo contrario se gastan escribiendo código adhesivo o reinventando la orquestación.

  • Los árboles de dependencia complejos pueden crecer rápidamente
  • El tuning de rendimiento es no trivial
  • Usted puede necesitar una herramienta más rápida (como el bucle) para mantener los tiempos de construcción abajo


Para resumir: Tooling likenxoturborepoproporciona a los equipos pequeños una velocidad monorepo – si está dispuesto a invertir en mantenerlos limpios.


Cuando se desarrollagomicroservicios, una buena idea temprano en el desarrollo es usar un goEl espacio de trabajo con lareplaceDirectiva engo.modFinalmente, a medida que el software escala, es posible separar sin esfuerzo gomódulos en repositorios separados.


Takeaway: A monorepo with shared infra buys you time, consistency, and sanity.

Dev local roto = Velocidad roto

If it takes three hours, a custom shell script, and a Docker marathon just to run your app locally, you've already lost velocity.


Los proyectos tempranos suelen sufrir de:

  • Documentación faltante
  • Dependencias obsoletas
  • Hacks específicos del sistema operativo (hijo, configuraciones sólo para Linux)


En mi experiencia, cuando recibí proyectos de equipos de desarrollo pasados, a menudo se desarrollaban para un sistema operativo único. Algunos desarrolladores prefirieron construir en macOS y nunca se molestaron en soportar sus scripts de shell en Windows. En mis equipos pasados, tuve ingenieros trabajando en máquinas Windows, y a menudo se requería reescribir scripts de shell o entender y revertir completamente el proceso de ingeniería para que funcionara el entorno local. Con el tiempo, estandarizamos la configuración del entorno en todos los sistemas operativos de desarrollo para reducir la fricción de embarque, una pequeña inversión que ahorró horas por nuevo ingeniero.


En otro proyecto, un desarrollador solo había creado una configuración de microservicio frágil, que el flujo de trabajo de ejecutar contenedores Docker se montó en un sistema de archivos local.


Pero embarcarse en un nuevo desarrollador front-end con un portátil Windows más antiguo se convirtió en una pesadilla.Tenían que montar diez contenedores sólo para ver la interfaz de usuario. Todo se rompió - volúmenes, red, compatibilidad con contenedores - y la configuración muy mal documentada. Esto creó un gran punto de fricción durante el embarque.


Terminamos hackeando un proxy Node.js que imitaba la configuración nginx/Docker sin contenedores. No era elegante, pero permitió que el desarrollador se desbloqueara y comenzara a contribuir.

Takeaway: If your app only runs on one OS, your team’s productivity is one laptop away from disaster.


Tip:Idealmente, el objetivo degit clone <repo> && make upSi no es posible, entonces mantener un archivo README actualizado con instrucciones para Windows/macOS/Linux es una obligación. Hoy en día, hay algunos idiomas de programación y cadenas de herramientas que no funcionan bien en Windows (como OCaml), pero la moderna pila ampliamente popular funciona bien en cada sistema operativo ampliamente utilizado; al limitar su configuración local a un único sistema operativo, a menudo es un síntoma de una inversión insuficiente en DX.

Tecnología Mismatch

Más allá de la arquitectura, su pila de tecnología también forma cómo los microservicios se vuelven dolorosos: no todos los idiomas brillan en una arquitectura de microservicios.


  • Node.js y Python: Excelente para la iteración rápida, pero gestionar los artefactos de construcción, las versiones de dependencia y la coherencia del tiempo de ejecución entre los servicios se vuelve doloroso rápidamente.
  • Go: Compila a binarios estáticos, tiempos de construcción rápidos y sobrecarga operativa baja. más natural cuando la división es realmente necesaria.


Si buscas rendimiento, tal vez busques el JVM y su ecosistema y la capacidad de desplegar artefactos a escala y ejecutarlos en arquitecturas basadas en microservicios.Si haces iteraciones muy rápidas y prototipos rápidamente sin preocuparte de escalar tu infraestructura de implementación, eres bueno con algo como Python.


Es bastante frecuente que los equipos se den cuenta de que hay grandes problemas con su elección de tecnología que no eran evidentes inicialmente, y que tuvieron que pagar el precio de reconstruir el back-end en un lenguaje de programación diferente (como por ejemplo:Estos chicosfueron forzados a hacer algo sobre la base de código de Python 2 heredada y migraron a Go).


Pero al contrario, si realmente lo necesita, puede conectar varios lenguajes de programación con protocolos comogRPCo comunicación de mensajes asíncronos. Y a menudo es la manera de ir acerca de las cosas. Cuando llegas al punto de que quieres enriquecer tu conjunto de características con funcionalidad de Machine Learning o empleos basados en ETL, simplemente construirías por separado tu infraestructura basada en ML en Python, debido a su rico ecosistema de bibliotecas específicas de dominio, que naturalmente carece cualquier otro lenguaje de programación. Pero tales decisiones deben tomarse cuando hay suficientes cabezas para justificar este intento; de lo contrario, el pequeño equipo se atraerá eternamente a la infinita complejidad de conectar varias pilas de software juntas.


Takeaway: Match the tech to your constraints, not your ambition.

Complejidad oculta: Comunicación y monitoreo

Los microservicios introducen una red invisible de necesidades:

  • Servicio Descubrimiento
  • Versión de fuego
  • Retiros, interruptores de circuitos, fallbacks
  • El rastreo distribuido
  • Alertas y alertas centralizados


En un sistema distribuido, es "¿por qué el servicio A falla cuando la implementación de B se retarda en C por 30 segundos?" ¿Tendrías que invertir completamente en tu pila de observabilidad. Para hacerlo "correctamente", requiere instrumentar tus aplicaciones de maneras específicas, por ejemplo, integrar OpenTelemetry para soportar el rastreo, o confiar en las herramientas de tu proveedor de nube como AWS XRay si vas con un sistema sin servidor complejo.actuallyfuncionamiento en la producción.


Por supuesto, se necesita una parte de la instrumentación de la observabilidad para ser realizada en aplicaciones monolíticas, pero es mucho más sencillo que hacerlo en términos de número de servicios de una manera consistente.


Tip:Entendemos quedistributed systems No es libre.Son un compromiso con una clase completamente nueva de desafíos de ingeniería.

No es libre.

Cuando los microserviciosDo deHacer sentido

Do de

A pesar de las dificultades mencionadas con los microservicios, hay momentos en los que la desconexión a nivel de servicio es realmente muy beneficiosa.


  • Aislamiento de carga de trabajo: un ejemplo común de esto sería en las mejores prácticas de AWS en el uso de notificaciones de eventos de S3 - cuando una imagen se carga a S3, desencadena un proceso de cambio de imagen / OCR, etc. Por qué es útil: podemos desconectar bibliotecas obscuras de procesamiento de datos en un servicio aislado y hacer que la API se concentre únicamente en el procesamiento de imágenes y la generación de salida de los datos cargados.
  • Necesidades de Escalabilidad Divergente: Imagínese que está construyendo un producto de IA. Una parte del sistema (API web) que desencadena las cargas de trabajo de ML y muestra los resultados pasados no es intensiva en recursos, es ligera, porque interactúa principalmente con la base de datos. Por el contrario, el modelo de ML que se ejecuta en GPU es realmente pesado de ejecutar y requiere máquinas especiales con soporte de GPU con configuración adicional.
  • Diferentes requisitos de tiempo de ejecución: — Supongamos que tienes una parte heredada del código escrito en C++. Tienes 2 opciones — mágicamente convertirlo en tu lenguaje de programación principal o encontrar formas de integrarlo con una base de código. Dependiendo de la complejidad de esa aplicación heredada, tendrías que escribir código adhesivo, implementando redes adicionales / protocolos para establecer interacciones con ese servicio, pero la línea de fondo es — probablemente tendrás que separar esta aplicación como un servicio separado debido a incompatibilidades de tiempo de ejecución.


Organismos de ingeniería a gran escala han luchado con desafíos similares. por ejemplo, el equipo de ingeniería de Uberdocumentaron su cambio a una arquitectura de microservicios orientada al dominio— no de pureza teórica, sino en respuesta a la verdadera complejidad a través de los equipos y el escalado de las fronteras. Su post es un buen ejemplo de cómo los microservicios pueden funcionar cuando usted tiene la madurez organizacional y el control operativo para apoyarlos.


En un proyecto, que también sucede a ser un inmueble, teníamos código de un equipo anterior que ejecuta cargas de trabajo de análisis basadas en Python que cargan datos en db MS-SQL, encontramos que sería un desperdicio construir sobre él una aplicación Django.El código tenía diferentes dependencias de tiempo de ejecución y era bastante auto-aislado, por lo que lo manteníamos separado y solo lo revisábamos cuando algo no funcionaba como se esperaba. Esto funcionaba para nosotros incluso para un pequeño equipo, porque este servicio de generación de análisis era una parte que requería cambios o mantenimiento raros.


Takeaway: Use microservices when workloads diverge — not just because they sound clean.

Guía práctica para startups

Si estás enviando tu primer producto, aquí está el playbook que recomiendo:

  • Comience monolítico. Elija un marco común y concéntrese en hacer las funciones. Todos los marcos conocidos son más que suficientes para construir alguna API o sitio web y servir a los usuarios. No siga el hype, adhiera a la manera aburrida de hacer las cosas; puede agradecer a sí mismo más tarde.
  • No te preocupes por dividir tu código en múltiples repositorios.He trabajado con los fundadores que querían separar el repositorio para reducir el riesgo de que los contratistas copiaran IP —una preocupación válida.Pero en la práctica, añadió más fricción que seguridad: construcciones más lentas, CI/CD fragmentado y mala visibilidad entre los equipos.La protección IP marginal no valía la pena el arrastre operativo, especialmente cuando los controles de acceso adecuados dentro de un monorepo eran más fáciles de gestionar.Para los equipos de etapa temprana, la claridad y la velocidad tienden a importar más que los beneficios teóricos de seguridad.
  • Instalación local sencilla. Hacer el trabajo de maquillaje. Si se necesita más, ser muy específico en los pasos, grabar un vídeo / Loom, y agregar capturas de pantalla. Si su código va a ser ejecutado por un desarrollador internado o junior, probablemente llegará a un bloqueo, y usted pasará el tiempo explicando cómo solucionar un problema. He encontrado que documentar todos los posibles problemas para cada sistema operativo elimina el tiempo gastado en aclarar por qué ciertas cosas en una configuración local no funcionaron.
  • Invertir temprano en CI/CD. Incluso si se trata de un HTML simple que puedes enviar manualmente a un servidor, puedes automatizar esto y confiar en el control de fuente con CI/CD para hacerlo.Cuando la configuración se automatiza adecuadamente, simplemente te olvidas de tu infraestructura de integración continua y te enfocas en las características.He visto a muchos equipos y fundadores cuando trabajan con equipos subcontratados a menudo son baratos en CI/CD, y eso resulta en que el equipo se desmoraliza y se molesta por los procesos de implementación manual.
  • División quirúrgica. División sólo cuando resuelva claramente un doloroso bloqueo de botella. De lo contrario, invierte en modularidad y pruebas dentro del monolito - es más rápido y más fácil de mantener.


Y sobre todo:optimize for developer velocity.


Velocity is your startup’s oxygen.Los microservicios prematuros secan ese oxígeno lentamente - hasta que un día, no puedes respirar.


Takeaway: Start simple, stay pragmatic, and split only when you must.

Si usas un enfoque basado en microservicios

Tuve proyectos basados en microservicios creados antes de lo que deberían haber sido hechos, y aquí están las siguientes recomendaciones que podría dar sobre eso:


  • Evalúa tu pila técnica que potencia tu arquitectura basada en micro-servicios. Invierta en herramientas de experiencia de desarrollador. Cuando tienes separación basada en servicios, ahora tienes que pensar en automatizar tu pila de microservicios, automatizando la configuración en entornos locales y de producción. En ciertos proyectos, tuve que construir un CLI separado que realiza tareas administrativas en el monorepository. Un proyecto que había contenido 15-20 implementaciones de microservicios, y para el entorno local, tuve que crear una herramienta de cli para generar archivos docker-compose.yml de forma dinámica a un arranque de un solo comando sin precedentes para el desarrollador regular.
  • Concéntrese en protocolos de comunicación confiables en torno a la comunicación de servicio. Si se trata de mensajes asíncronos, asegúrese de que sus esquemas de mensajes sean consistentes y estandarizados. Si se trata de REST, concéntrese en la documentación de OpenAPI. Los clientes de comunicación interservicios deben implementar muchas cosas que no salen de la caja: retiros con retrocesos exponenciales, temporales. Un cliente gRPC típico de huesos desnudos requiere que factorice manualmente esas cosas adicionales para asegurarse de que no sufre de errores transitorios.
  • Asegúrese de que la configuración de la unidad, las pruebas de integración y las pruebas end-to-end sean estables y se ajusten a la cantidad de separaciones de nivel de servicio que introduzca en su base de código.
  • En proyectos más pequeños que utilizan cargas de trabajo basadas en microservicios, es probable que utilice por defecto una biblioteca compartida con ayudantes comunes para instrumentar su código de observación y comunicación de una manera consistente. Una consideración importante aquí es mantener su biblioteca compartida lo más pequeña posible. Cualquier cambio importante obliga a una reconstrucción en todos los servicios dependientes, incluso si no están relacionados.
  • Añadir registros de JSON estructurados y crear diferentes identificadores de correlación para deshabilitar las cosas una vez que su aplicación se implementa. Incluso los ayudantes básicos que emiten información de registro rica (hasta que instrumentó su aplicación con las instalaciones de registro / seguimiento adecuadas) a menudo ahorran tiempo descubriendo flujos de usuarios frágiles.


Para resumir: si todavía está buscando microservicios, debe comprender de antemano el impuesto que va a pagar en términos de tiempo de desarrollo y mantenimiento adicionales para hacer que la configuración sea viable para cada ingeniero de su equipo.


Takeaway: If you embrace complexity, invest fully in making it manageable.

Conclusión

Premature microservices are a tax you can’t afford. Stay simple. Stay alive.Sólo se divide cuando el dolor lo hace evidente.


Survive first. Scale later. Choose the simplest system that works — and earn every layer of complexity you add.

Recursos relacionados

  • Monólito primero - Martin Fowler
  • El Majestoso Monólito - DHH / Basecamp
  • Adiós a los microservicios: De 100 niños con problemas a 1 superestrella - Segmento Eng.
  • Deconstruyendo el Monolito - Shopify Eng.
  • Arquitectura de microservicios orientada al dominio — Uber Eng.
  • Go + Servicios = Un Proyecto Goliat - Khan Academy


Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks