Microservicios y procedimientos almacenados

34

¿Los procedimientos almacenados se consideran una mala práctica en una arquitectura de microservicio?

Aquí están mis pensamientos:

  • La mayoría de los libros sobre microservicios recomiendan una base de datos por microservicio. Los procedimientos almacenados generalmente funcionan en una base de datos monolítica.

  • Una vez más, la mayoría de los libros de arquitectura de microservicios afirman que deben ser autónomos y estar acoplados libremente. El uso de procedimientos almacenados escritos, digamos específicamente en Oracle, combina estrechamente el microservicio con esa tecnología.

  • La mayoría de los libros de arquitectura de microservicios (que he leído) recomiendan que los microservicios estén orientados a los negocios (diseñados con diseño controlado por dominio (DDD)). Al trasladar la lógica empresarial a los procedimientos almacenados en la base de datos, este ya no es el caso.

Tiene alguna idea sobre esto?

Johnny Alpha
fuente
10
@ RandomUs1r lo siento, esto no tiene sentido para mí. ¿Por qué la estructura DB tiene que ser no relacional? Claro, puede tener referencias externas, pero su estructura interna puede ser 100% relacional
IMil
12
El problema con sus puntos es que todas sus premisas están equivocadas. La afirmación de que los microservicios deben ser autónomos y estar acoplados libremente significa, en primer lugar, que deben estar acoplados entre sí de manera flexible ; la forma en que gestiona el acoplamiento de componentes internos es una cuestión diferente, y de importancia secundaria (pero no sin importancia), especialmente si puede reemplazar todo el microservicio en una actualización. Entonces, no hay razón por la que no pueda usar sprocs dentro de esos límites. Además, DDD no prohíbe los sprocs o la mezcla de paradigmas; Algunos aspectos de algunos problemas no son los más adecuados para OO.
Filip Milovanović
3
Qué tan monolítica es su base de datos tiene que ver con su diseño e implementación de datos, no tiene nada que ver con usar o no usar procedimientos almacenados.
RBarryYoung
55
"Los procedimientos almacenados generalmente funcionan en una base de datos monolítica". Debería considerar descartar cualquier información o consejo que obtenga de cualquier fuente que haya compartido ese "hecho" con usted.
StingyJack
3
@ RandomUs1r Umm no, lo único que realmente pierde es que no puede usar restricciones de clave externa en las claves de referencia, que es más bien el objetivo de los microservicios. Por un lado, la idea de que las bases de datos NoSql son mágicamente más rápidas ha sido refutada repetidamente, pero incluso si fueran más rápidas (no lo son), también obtienes toda la infraestructura existente, el conocimiento y el código existente de forma gratuita, lo cual es enorme . CERN y muchos otros manejan terabytes de datos utilizando bases de datos relacionales muy bien. Las bases de datos NoSql tienen su uso, pero son independientes de si usa microservicios o no.
Voo

Respuestas:

45

No hay nada que prohíba o defienda explícitamente el uso de procedimientos almacenados con microservicios.

Descargo de responsabilidad: no me gustan los procedimientos almacenados del POV de un desarrollador, pero eso no está relacionado con los microservicios de ninguna manera.

Los procedimientos almacenados generalmente funcionan en una base de datos monolítica.

Creo que estás sucumbiendo a una falacia lógica.

Los procedimientos almacenados están en declive hoy en día. La mayoría de los procedimientos almacenados que todavía están en uso son de una base de código más antigua que se ha mantenido. En aquel entonces, las bases de datos monolíticas también eran mucho más frecuentes en comparación con cuando los microservicios se han vuelto populares.

Los procesos almacenados y las bases de datos monolíticas se encuentran en bases de códigos antiguas, por lo que las ves juntas más a menudo. Pero ese no es un vínculo causal. No utiliza procesos almacenados porque tiene una base de datos monololítica. No tiene una base de datos monolítica porque usa procs almacenados.

La mayoría de los libros sobre microservicios recomiendan una base de datos por microservicio.

No hay ninguna razón técnica por la que estas bases de datos más pequeñas no puedan tener procedimientos almacenados.

Como mencioné, no me gustan los procesos almacenados. Los encuentro engorrosos y resistentes al mantenimiento futuro. Creo que la difusión de sprocs en muchas bases de datos pequeñas exacerba aún más los problemas que ya no me gustan. Pero eso no significa que no se pueda hacer.

Una vez más, la mayoría de los libros de arquitectura de microservicios afirman que deben ser autónomos y estar acoplados libremente. El uso de procedimientos almacenados escritos, por ejemplo, específicamente en Oracle, combina estrechamente el microservicio con esa tecnología.

Por otro lado, se puede hacer el mismo argumento para cualquier ORM que use su microservicio. No todos los ORM admitirán todas las bases de datos tampoco. El acoplamiento (específicamente su estanqueidad) es un concepto relativo. Es una cuestión de ser tan suelto como puedas ser razonablemente.

Los Sprocs sufren de acoplamiento estrecho en general, independientemente de los microservicios. Aconsejaría contra los sprocs en general, pero no particularmente porque está utilizando microservicios. Es el mismo argumento que antes: no creo que los sprocs sean el camino a seguir (en general), pero ese podría ser mi sesgo y no está relacionado con los microservicios.

La mayoría de los libros de MSA (que he leído) recomiendan que los microservicios estén orientados a los negocios (diseñados usando ddd). Al trasladar la lógica empresarial a los procedimientos almacenados en la base de datos, este ya no es el caso.

Esta siempre ha sido mi queja principal sobre sprocs: lógica de negocios en la base de datos. Incluso cuando no es la intención, tiende a terminar de alguna manera de esa manera.

Pero nuevamente, esa queja existe independientemente de si usa microservicios o no. La única razón por la que parece un problema mayor es porque los microservicios lo empujan a modernizar toda su arquitectura, y los sprocs ya no son tan favorecidos en las arquitecturas modernas.

Flater
fuente
44
No estoy seguro de si es correcto decir que los microservicios lo empujan a modernizar toda su arquitectura. Más a menudo que no, terminan siendo una capa delgada sobre un gigante de un desorden de código mal planificado. Pueden ser bastante buenos cuando están bien hechos, pero en realidad no lo empujan de ninguna manera hacia una mejor codificación que cualquier otra arquitectura. Aún así, buena respuesta. Tienes un +1 de mi parte.
T. Sar - Restablece a Monica el
11
@ T.Sar moderno no es lo mismo que mejor. Refactorizar (a microservicios o lo que sea) significa cambio. El cambio te obliga a usar tus ideas actuales. Esperamos que sean mejores ideas.
candied_orange
2
@ T.Sar: Los piratas informáticos son eternos y, por lo general, puedes abusar de cualquier sistema (moderno o no) para hacer algo que técnicamente puede manejar pero que nunca fue diseñado. Los microservicios lo instan a hacerlo de manera diferente (y así reevaluar algunos enfoques antiguos) pero no pueden aplicarlo universalmente . Con la aplicación universal, generalmente sufre en el departamento de compatibilidad / caso marginal válido.
Flater
44
@candied_orange "moderno no es lo mismo que mejor" - Creo que estoy totalmente de acuerdo con eso. Muy buen punto.
T. Sar - Restablece a Monica el
3
Moderno ni siquiera es sinónimo de "adecuado".
Laiv
24

Para escribir software es necesario que se acople estrechamente a una tecnología.

Al menos para el entorno de tiempo de ejecución proporcionado por el lenguaje de programación que se está desarrollando dentro.

En términos más generales, encontrará que su microservicio está estrechamente vinculado a varias tecnologías:

  • Network Service Framework para proporcionar implementaciones de protocolo HTTP / SSL / SOAP de alto nivel
  • Repository / ORM / DAO Framework para proporcionar persistencia.
  • Marcos de manipulación de datos para proporcionar herramientas para trabajar con datos.
  • Process / Threading / OS Framework para proporcionar acceso a los recursos del sistema operativo, como multitarea, sistema de archivos, memoria, cómputo GPU, tarjetas de expansión, etc.

Y eso es hacer un microservicio básico.

Procedimientos almacenados

Un procedimiento almacenado es simplemente otra tecnología que puede elegir usar o no usar. No hace que su código sea mágicamente monolítico o micro.

Sin embargo, lo que es es:

  • Otra tecnologia. Cada tecnología presente en la aplicación disminuye la probabilidad de que un programador determinado pueda leer, comprender y tomar decisiones acertadas de diseño para esa combinación de tecnología.
  • Un lenguaje que usa un paradigma de programación diferente. Es demasiado fácil para los no expertos intentar forzar su propia perspectiva imperativa, funcional, OO, etc., lo que a menudo conduce a resultados menos que estelares.
  • Una API Que debe mantenerse como cualquier otra clase en la base del código. También significa que la base de datos proporciona una interfaz no genérica. Esto hace que sea más difícil reemplazar el motor de la base de datos en sí mismo y aplicar de manera transparente un comportamiento genérico como el almacenamiento en caché de la memoria.
  • Un artefacto. Que debe ser versionado, probado e implementado. Esto se puede hacer, pero las bases de datos son artefactos vivos que requieren un enfoque diferente. Por lo general, no puede simplemente eliminar el original y reemplazarlo. A menudo, se necesita una orquestación cuidadosa de los cambios a lo largo del tiempo para migrar el sistema al estado deseado.

Cada uno de estos es un costo real. En algunos casos el costo es justificable, en otros no lo es.

Pagaría casi el mismo conjunto de costos al alojar un motor de secuencias de comandos. La única reducción es que puede elegir el mismo paradigma de programación que el idioma del host.

Lógica de negocios

Mover las reglas comerciales a la base de datos es una mala práctica. Simplemente no por los procedimientos almacenados.

Es una mala práctica, porque la base de datos y la lógica de negocios operan en diferentes niveles de corte.

  • Una base de datos en aplicaciones maduras puede estar en uso durante décadas. En general, estos sistemas tendrán el motor actualizado periódicamente, pero la base de datos en sí se migró. No fue asesinado y reconstruido desde el principio. No hay ninguna razón por la que un micro servicio no pueda ser igualmente longevo.

  • Compare décadas con la rapidez con la que cambian las reglas comerciales. En mi experiencia, una regla comercial antigua tiene quizás unos pocos años, pero la mayoría cambia rápidamente, y nunca se sabe cuál cambiará a continuación. Un nuevo requisito de un regulador, un producto antiguo que se retira del servicio, cambios en el membrete, cambios en la cantidad de empleados que se reportan a un jefe, etc., etc., etc.

Si la lógica de negocios se distribuye a través de las capas de corte, particularmente en una capa más lenta y de mayor duración, generará resistencia al cambio. Este no es necesariamente algo malo. Después de todo, la única base de datos que tiene cero lógica de negocios es una tienda triple.

El simple acto de especificar un esquema de tabla es mover la lógica empresarial a la base de datos.

Arquitectura

Usted está luchando con el uso de la herramienta adecuada para el problema apropiado, sin necesidad de demasiadas herramientas, ni haciendo que sea demasiado difícil de resolver, para hacer y mantener una solución.

Esto no es facil.

Pero pensemos lo impensable, ¿cómo mantendría la lógica empresarial distribuida en varios idiomas?

  • Un catálogo ... para que se pueda rastrear y mantener la implementación de cada regla de negocio.
  • Pruebas ... que podrían usarse contra cada regla comercial independientemente de dónde y cómo se implementó.
  • Una implementación de referencia ... de modo que cuando se encuentran discrepancias, existe una fuente de verdad (o al menos una fuente de debate).

Pero esto también tiene un costo.

  • ¿Es mejor permitir que las reglas de negocio tengan muchas implementaciones? ¿Cada uno puede aprovechar las habilidades del equipo y las disposiciones del marco, pero necesita controles de calidad estrictos para evitar tener muchos pequeños caprichos?
  • ¿O es mejor tener una única fuente de verdad, escrita en un solo idioma? ¿Podría decirse que es más barato de implementar, pero también una fuente única de falla, un componente monolítico que resiste el cambio frente a diferentes plataformas, marcos o herramientas que aún no se han inventado?
Kain0_0
fuente
8

Prefacio mi respuesta diciendo que en realidad mantengo un par de microservicios que usan procedimientos almacenados. También he escrito muchos procedimientos almacenados en varios puntos de mi carrera, y definitivamente estoy de acuerdo en que las cosas pueden salir muy, muy mal si se usan incorrectamente.

Entonces, la respuesta corta es, no, los procedimientos almacenados no son inherentemente malos en una arquitectura de microservicio. Pero necesitas entender:

  1. Estás agregando obstáculos a la sustitución de los motores de almacenamiento. Si algunas características operativas o de rendimiento o limitaciones de características requieren que cambie los motores de almacenamiento, el costo será mayor porque estará escribiendo y probando una gran cantidad de código nuevo. La ejecución de más de un motor de almacenamiento (ya sea durante una fase de migración o para aislar actividades en función de las necesidades de rendimiento) puede presentar problemas de coherencia a menos que utilice el compromiso de dos fases (2PC), que tiene problemas de rendimiento en sí.
  2. Tienes que mantener otra API, lo que significa que tus dependencias pueden romperse. Agregar, eliminar o cambiar los tipos de parámetros en los procedimientos puede romper el código existente. Lo mismo sucede con las tablas y consultas, pero sus herramientas pueden ser menos útiles para rastrear dónde pueden salir mal las cosas. Los problemas con los procedimientos almacenados generalmente se encuentran en tiempo de ejecución, muy tarde en el proceso de desarrollo / implementación.
  3. Los permisos de su base de datos se han vuelto más complicados. ¿Se ejecuta un procedimiento como usuario conectado o como algún otro rol? Debe pensar en esto y administrarlo (con suerte de manera automatizada).
  4. Debe poder migrar a nuevas versiones de forma segura. A menudo se debe descartar y volver a crear un procedimiento. Una vez más, los permisos pueden causarle algunos problemas.
  5. La reversión de una migración fallida puede significar un esfuerzo adicional. Cuando el entorno de producción se separa de los desarrolladores, las cosas se vuelven aún más difíciles.

Estos son algunos usos de los procedimientos almacenados que creo que a menudo valen la pena:

  1. Aplicación del historial de edición (registros de auditoría). Los disparadores se usan comúnmente para este propósito, y los disparadores son procedimientos almacenados. También es posible en algunas bases de datos no permitir las inserciones y actualizaciones por completo para el rol de la aplicación: los clientes ejecutan procedimientos que se ejecutan como un rol diferente con los permisos apropiados y que imponen todo el comportamiento necesario.
  2. Extensión de restricciones de cheques. Esto podría llevarlo al territorio de la lógica empresarial, pero hay casos en los que las herramientas de restricción integradas de una base de datos pueden no ser suficientes para lo que necesita. Muchas veces, la mejor manera de expresar cheques es con un código imperativo, y corre el riesgo de dejar que ingresen datos incorrectos si depende de que su aplicación lo haga por usted.
  3. Encapsulación de consultas complejas cuando una vista es inapropiada o demasiado complicada. He visto algunos casos en los que una vista correcta requiere un SQL extremadamente complejo que se puede expresar de manera mucho más comprensible en un procedimiento almacenado. Esto es probablemente raro, pero ocurre.

En general, sugiero que primero pruebe las vistas y recurra a los procedimientos solo cuando sea necesario. Las vistas bien diseñadas en realidad pueden funcionar como una API, abstrayendo los detalles de cómo se consultan las tablas subyacentes. Aumentar su API (vistas) con procedimientos almacenados tiene sentido en algunas circunstancias. Incluso es posible emitir JSON directamente desde una consulta SQL, evitando todo el desorden de los datos de mapeo de los resultados de la consulta al modelo de datos de su aplicación. Si es una buena idea es algo que debe determinar en función de sus propias necesidades.

Como ya debería estar administrando los recursos de su base de datos (esquema, permisos, etc.) a través de alguna herramienta automatizada, no, los procedimientos almacenados no son inherentemente malos para los microservicios.

ngreen
fuente
Creo que todos sus primeros puntos también se aplican, si escribe la lógica de negocios en, por ejemplo, un Java-Framework. Cambiar el motor DB cambiará las características de rendimiento y requerirá volver a probar y quizás reescribir declaraciones. Si escribe las sentencias SQL, por ejemplo, como cadenas en su aplicación, tiene el mismo problema con el cambio de variables que rompen cosas. Debe decidir si su aplicación utiliza un usuario técnico o usuarios individuales para conectarse a la base de datos, etc.
Falco
@Falco Creo que si está utilizando JPA exclusivamente, no debería ser demasiado difícil cambiar las bases de datos. El rendimiento definitivamente puede variar sustancialmente y siempre necesita ser probado. Un par de servicios que mantengo no son "micro" en el sentido de que pueden escanear o agregar más de millones o miles de millones de puntos de datos y devolver conjuntos de datos arbitrariamente grandes (a menudo paginados). No puedo imaginar usar JPA para ellos, pero puedo imaginar cambiar los motores de base de datos subyacentes (y reescribir el SQL) mientras mantengo la misma API.
ngreen
4

Los procedimientos almacenados son detalles de implementación. Las funciones de base de datos, lambdas o un script de shell almacenado en algún lugar del sistema de archivos son todos detalles de implementación e irrelevantes para la arquitectura.

La mayoría de los libros sobre microservicios recomiendan una base de datos por microservicio.

Ok, entonces podemos codificar los procedimientos almacenados en estas bases de datos.

una vez más, la mayoría de los libros de arquitectura de microservicios afirman que deberían ser autónomos y estar acoplados libremente

Entre las capacidades comerciales, los ciclos de vida del desarrollo, la administración, las implementaciones, las ubicaciones del equipo, etc. Nada que ver con los detalles de implementación. Los microservicios no resuelven un problema técnico (todo lo contrario). Vienen a resolver problemas con la administración y el tiempo de comercialización. Es una estrategia, no una táctica. Una manera de fallar rápidamente con el menor costo posible. Si se demuestra que cierta capacidad comercial no tiene valor, la descartamos sin estropear otras capacidades, implementaciones, gestión de proyectos, lanzamientos ...

Tenga en cuenta que la "división" ya actúa como un agente de desacoplamiento. Digamos que tenemos dos servicios, A está respaldado por Oracle y B por MongoDB. Si no rompemos la regla de oro del desacoplamiento, debería ser posible soltar A + Oracle con efectos secundarios insignificantes en B.

El uso de procedimientos almacenados escritos, por ejemplo, específicamente en Oracle, combina estrechamente el microservicio con esa tecnología.

Puede causar el bloqueo del proveedor. Muchas veces, la empresa impone al vendedor debido a razones históricas o contractuales 1 . Es importante saber cómo no bloquear nuestro código al proveedor. Por ejemplo, algunos ORM y marcos implementan un nuevo lenguaje de consulta que oculta las funciones y características integradas de la base de datos.

Sin embargo, si nuestros servicios son lo suficientemente micro, el bloqueo de proveedores ya no es un problema, ya que afecta a una pequeña parte del conjunto. Una pequeña parte que debería poder reemplazarse (o aislarse) rápidamente.

La mayoría de los libros de MSA (que he leído) recomiendan que los microservicios estén orientados a los negocios (diseñados con DDD).

Debe ser impulsado por los negocios y aquí la cosa. No todas las empresas aprovechan DDD. DDD y microservicios se superponen en muchos puntos, pero no son causa-efecto. Podríamos terminar con un ecosistema de microservicios compuesto por servicios anémicos. O compuesto de una combinación de ambos: servicios que implementan un dominio complejo y servicios anémicos tontos que proporcionan POJO directamente desde la base de datos. No hay nada de malo en eso.

En cuanto a los libros, solo se centran en la ejecución de la estrategia. Las tácticas, cómo aprovechar la informática distribuida , cómo hacer que funcione para el éxito, pero son (generalmente) independientes de la estrategia. Las estrategias varían de una compañía a otra y rara vez dependen de los desarrolladores. Por lo tanto, todavía tenemos que extrapolar y adaptar lo que dicen los libros a nuestras necesidades, requisitos y limitaciones específicos. El objetivo es hacer que la estrategia comercial sea rentable y sostenible.

Siempre tenga en cuenta que cualquier arquitectura es un medio para un fin. Las reglas del negocio. No construimos ecosistemas de microservicios por moda o por amor al arte.

Laiv
fuente
1

Realmente no tiene nada que ver con microservicios.

Los procedimientos almacenados pueden tener sentido si su servicio tiene una arquitectura en capas de 'estilo antiguo' en la que la base de datos es la base del servicio, con acceso a datos y capas de lógica empresarial en la parte superior. La interfaz entre el servicio y la base de datos en dicha arquitectura es muy específica para los detalles más internos del servicio. Por lo general, habrá adaptadores específicos de servicio para cada tipo de base de datos compatible, y la especificidad de la API expuesta por el adaptador hace posible utilizar procedimientos almacenados en las capas subyacentes.

Hay muchos problemas con arquitecturas como esa. Lo más importante es que hace que la mayor parte de la lógica sea muy difícil de realizar pruebas unitarias. Estas arquitecturas ya no están a favor.

Si está utilizando una "arquitectura limpia", una "arquitectura de cebolla" o similar de estilo más reciente, entonces la base de datos será una dependencia inyectada , especificada en las capas externas. Como se define en las capas externas, la interfaz proporcionada para la base de datos debe ser genérica . No puede reflejar los detalles más internos del servicio, porque esos detalles deben estar ocultos de las capas más externas de la arquitectura. Definir una interfaz genérica de procedimientos almacenados que pueda funcionar con cualquier base de datos o arnés de pruebas unitarias es increíblemente difícil y no es realmente necesario, por lo que los procedimientos almacenados a menudo no son prácticos en este tipo de arquitecturas.

La relación con los microservicios es solo que los microservicios son nuevos y ascendentes, ya no hacemos monolitos, y que estos nuevos estilos arquitectónicos también son ascendentes, ya no hacemos capas planas.

Matt Timmermans
fuente