Aún no había visto este vídeo, la mejor explicación sobre CQRS que he escuchado en los tres años que llevo en el sector. Tengo muchas, pero muchisimas ganas de que salga el libro. Gracias por seguir compartiendo :)
Excelentes videos @NetMentor, muy claros. Me gustaría entender que tipos de mecanismos se podrían aplicar para persistir eventos ante cualquier eventualidad o perdidas que provoquen desincronización entre las bases. Gracias por tus contenidos.
Te recomiendo que mires el vídeo del patron productor/consumidor donde se menciona la dead letter queue ua-cam.com/video/SA2Htqafj-Q/v-deo.html un saludo!
Buen vídeo aunque sería más útil explicar de entrada que hace énfasis a la misma db y no "una db de lectura y otra de escritura" como si fuesen cosas separadas del todo ya que si tienes que solucionar el problema de esa forma es porque haces una mala elección de tecnologías y culpas a la estructura, solucionas el problema ? sí, pero a cambio de otro más grande. Desmenuzar tanto una arquitectura trae más problemas que soluciones, los micro servicios son buenos hasta que te das cuenta que solo es conveniente separar lo que sea necesario y no exagerar, sino tendrás muchos recursos en desuso que no estás explotando y de todos modos pagas por ellos por el % de disponibilidad que dejas en el nodo para evitar crash por falta de recursos, valga la redundancia. En donde trabajo cuando empezó la fiebre de los micro servicios tenían un micro servicio por endpoint, luego se dieron cuenta del desperdicio de recursos por idle state y ahora solo se levantan los endpoints stateless en 1 contenedor, los endpoints statefull en otro y se replican según demanda, comunicados por redis streams + la db por separado en sus propios contenedores. Y la diferencia ha sido de un 30% (+-5%) de diferencia. Lo cual al momento de pagar los VPS ha sido muy notable
Hola!! excelente la clase,una consulta veo que trabajas en el ejemplo con IntelliJ IDEA me parece?? si es asi porque ese editor y no visual studio o VScode ?
sí, trabajo con rider desde 2017 o así, de aquella VS estaba bastante mal y ya me acostumbre, en mi opinión, rider sigue siendo mejor que VS pero entiendo quien en 2023/24 pueda soportar usar visual studio. respecto a VSCode esta aún muy verde en comparación. Un saludo
Hola buenas noches, excelente video. Tuve la oportunidad de ver en un proyecto el cual usaron CQRS y 1.- Apuntaba a la misma base de datos (Es lo correcto? porque veo que en tu video haces referencia a DB separadas) 2.- Hay una separaciones de clases *pero en el mismo proyecto* para: 2.1.- Consulta 2.2.- Eliminacion 2.3.- Actualizacion 2.4.- Creacion ==> Es lo correcto? Agradezco tu orientacion. Saludos
utilizar la misma db o un solo proyecto, No es lo correcto, pero tampoco incorrecto, depende del tamaño y uso del sistema, si solo tienes uno o dos endpionts que son crud básicos, hacer dos proyectos es programar de más, así que si es pequeño pues bien; y si fuera pequeño, pero realizas 100k gets por minuto, pues habría que separarlo en otro. Al final todo son pros y contras, y hay que evaluarlos, en mi opinión, si es un servicio pequeño y no tiene un uso excesivo (no necesite escalado) puede estar bien que sea 1 pero si es grande lo suyo es tenerlo partido, principalmente para el escalado
Lo de los nombres es un debate que seguirá existiendo en los equipos, a mi personalmente no me importa que se ponga Command y Query, o bien en el namespace o en el nombre de la clase, si lo hiciéramos sabría de manera automática que se esta implementando CQRS. Yo suelo ser riguroso en los nombrados, el código se debe leer como si fuera una historia. Gracias por el contenido y por tu trabajo.
Hola, creo que al final lo que entiendo (disculpa mi simpleza), es que la ventaja de tener dos BBDD es que por ejemplo las bbdd NoSql son mucho mas optimas para las consultas que las relacionales (si no toda la parafernalia extra de estos patrones modernos seria simple redundancia gratuita) quizá parezca un poco escéptico, pero es que soy un conceptista puro, lo breve si bueno dos veces mejor . Si acaso no acierto, con gusto acepto tu corrección
esa es una otra es que las podemos escalar de forma diferente, en ciertas aplciaciones las lecturas van a ser 100 veces las escrituras, asi que podemos escalar una parte y no la otra. Luego esta el tema de que si haces event sourcing + cqrs + ddd puedes utilizar la base de datos de escritura como source of truth y hacer "pruebas" con la base de datos de lectura, ya que los datos en la de escritura serán siempre correctos. Pruebas como por ejemplo cambiar de una base de datos a otra, o migrar el servidor sin miedo a perderlo todo.
Pues hay gente que utiliza MediatR que es una libreria de . NET que representa el patron mediador para notificar que un domain event esta listo y entonces tienes el handler del integration event en la misma aplicación y en memoria (en vez de tener los eventos en el service bus) , pero la gran mayoria de esta gente lo utiliza 1 a 1. Te permite hacer decoupling de la lógica pero ya está, si la comunicación va a ser 1 - n. Te permite hacer pipelines y tal, y en ese escenario yo si utilizaria mediatr. Pero para comunicaciones 1 a 1 a mi me parece excesivo, pero bueno, no esta mal del todo.
Hola, una duda, siguiendo el ejemplo de productos, si mientras se lanza el comando update de un producto llega petición query para recuperar la info del mismo producto, podría darse el caso de que la query no recupere la info actualiza del producto que realiza el command? Me cuesta acabar de ver el tema de sincronizar las bbdd de lectura/escritura. Gracias
Si, es exactamente lo que sucede y es un resultado esperado, este suceso se denomina consistencia eventual y lo veremos en el curso en un par de vídeos. Tengo una explicación en el blog: www.netmentor.es/entrada/consistencia-eventual-microservicios Un saludo !
Me alegro de que te guste! desafortunadamente tuve unos problemas personales durante el verano y no he podido hacer nada, lo intentaré retomar este invierno. Un saludo y gracias!
Gracias! Por ahora no tengo ningún libro, voy a escribir que tiene que ver con sistemas distribuidos, pero por ahora no esta escrito (con suerte para final de año) Un saludo!
Yo tengo una duda, en el código que nuestras en el video veo que al hacer el create que puede darse el caso de que emitas una publicación de un evento y que luego realmente no llegues a persistir el dato porque pueda ocurrir algún error, problema de conexion etc. Aunque lo colocaras bien, primero persistiendo y luego emitiendo el mensaje podrías tener el mismo problema pero inverso. Como lidias con esos problemas de transacionalidad?
en este caso tienes tres opciones: Si emites el evento al service bus, tu aplicación como tal ya no es responsable de que el resto funcionen bien, si el probelma es que el publicar el evento falla, entonces lo que puedes hacer es una especie de transaccón de que si el mensaje no se propaga, simplemente haces rollback de la base de datos. La segunda opción, y la más común es que cuando haces el heathcheck a rabbitMQ (o kafka o lo que uses) si da negativo te saltas todo lo que tienes en cache o en la bbdd local y haces llamadas todo el rato al otro microservicio, la infraestrucutra tendrá más carga de la habitual hasta que se arregle el problema. La última opción, aunque es más drástica y requere mucho más código, es tener un state machine, pero es mas para situaciones en las que por ejemplo se va la luz o se cae la app de repente (osea, el proceso se queda a medias) que basicamente guarda en el punto en el que la app ha parado y cuando la app vuelve a empezar, se ejecuta desde ahí. Un saludo!
@@NetMentor Tuve la misma duda, ¿cómo es el manejo de errores en este sistema?. Entiendo que creando una especie de trasacción se puede resolver no me imagino cómo implementar una transación con rabbitMQ (o cualquier otro). En la segunda opción, ¿qué codigo extra requiere? La tercer opción creo que sólo sería válida en situaciones muy especificias
Técnicamente la tercera opción la puedes conseguir implementando Microsoft Orleans (una librería de Microsoft), pero vaya, por normal general necesitas utilizar el patrón SAGA y si algo da error tener los workflows listos para "recuperar". Pero lo más normal en sistemas distribuidos es que el evento se vuelva a leer y si sigue dando error arreglarlo porque es un bug en alguna parte. Dependerá de lo crítica que sea esa parte de la aplicación en si puedes permitirte tener la información incompleta un rato o no.
No entendí la parte donde el consumer se pega a rabbit MQ y consume el mensaje, este no seria el patrón producers/consumers?, y la pregunta es porque el mensaje desaparece de RabbitMQ, no debería de quedar allí, por si algún otro consumer lo necesita?, porque el consumer va y busca el mensaje?, no es el RabbitMQ quien debería llamar ese consumer y enviarle tal mensaje?, o estoy confundido en la practica y conceptos?
Hola! CQRS y Producers/consumers son dos patrones completamente diferentes, que pueden trabajar a la vez perfectamente, ya que uno no afecta al otro. Por ejemplo, en todos los servicios que el sistema Distribt tienen, no todos cumplen CQRS, si vas al GitHub hay una imagen con etiquetas en donde se cumple cada patrón. El motivo por el que el mensaje desaparece de rabbitMQ está explicado en el vídeo de RabbitMQ (ua-cam.com/video/BYKC9w-eHN4/v-deo.html), es porque le exchange publica a las colas y las colas son 1 a 1 con la aplicación (RabbitMQ funciona diferente a Kafka, en Kafka si se queda el mensaje); El consumer va y busca el mensaje porque no es rabbitMQ el que hace un push, sino que es la app la que consume (cada X segundos) los mensajes.
@@NetMentor gracias por la respuesta, pero entonces yo no puedo tener un producers/consumers usando rabbitMQ (solo me permite 1-1)? El tener el patrón de producers/consumers solo lo proporciona el exchange que se esté usando, en el caso de kafka? ¿Ósea es un patrón que viene implementado dentro de la tecnología del broker de mensajería? ¿No es algo que nosotros tengamos que hacer?
Si puedes, te recomiendo que te mires este video ua-cam.com/video/BYKC9w-eHN4/v-deo.html Pero resumiendo, el mensaje en vez de ir a un Brooker fanout como en Kafka y de ahí se propaga lo.wie hace es ir a un "exchange" y del exchange puede ir a otros exchanges o a colas (y no es fanout como Kafka, sino que se puede configurar). Para aplicar producer /consumer necesitas pasar por las.colaas porque las apps no pueden escuchar de un exchange. Hay una opción para no borrar los.mensjaes en rabbitmq también, pero vaya que eso, es básicamente lo mismo implementado un poco diferente. Si que es verdad que depende del caso de uso, no vas a tener los mensajes para volver a ejecutarlos, pero en la práctica en Kafka se acaban borrando por tema espacio y dinero que cuesta almacenarlos.
Twitter: twitter.com/NetMentorTW
Blog: www.netmentor.es/entrada/patron-cqrs-explicado-10-minutos
Aún no había visto este vídeo, la mejor explicación sobre CQRS que he escuchado en los tres años que llevo en el sector. Tengo muchas, pero muchisimas ganas de que salga el libro.
Gracias por seguir compartiendo :)
Ya salió el libro?
Tuve unos problemas personales y lo tuve que retrasar, con suerte para fin de año..gracias !
concuerdo contigo 100% que manera mas brutal de explicar esto
Despues de ver este video siento que estoy vivo. Gracias maestro!!!
Excelente explicaciòn en castellano! Gracias
Excelente. Muy bien explicado y claro. Saludos desde Argentina. 😊
Unas Gracias se quedan cortas. Es un contenido de gran valor.
Excelente explicación, me gusta mucho tu manera de explicar.
Que buen canal me he encontrado 🫶🏽
Excelente contenido, muchas gracias!
Excelente video, muy bueno
Muy bueno! Gracias por compartir
Excelentes videos @NetMentor, muy claros. Me gustaría entender que tipos de mecanismos se podrían aplicar para persistir eventos ante cualquier eventualidad o perdidas que provoquen desincronización entre las bases.
Gracias por tus contenidos.
Te recomiendo que mires el vídeo del patron productor/consumidor donde se menciona la dead letter queue
ua-cam.com/video/SA2Htqafj-Q/v-deo.html
un saludo!
Excelente explicación, muchas gracias!
Buen vídeo aunque sería más útil explicar de entrada que hace énfasis a la misma db y no "una db de lectura y otra de escritura" como si fuesen cosas separadas del todo ya que si tienes que solucionar el problema de esa forma es porque haces una mala elección de tecnologías y culpas a la estructura, solucionas el problema ? sí, pero a cambio de otro más grande. Desmenuzar tanto una arquitectura trae más problemas que soluciones, los micro servicios son buenos hasta que te das cuenta que solo es conveniente separar lo que sea necesario y no exagerar, sino tendrás muchos recursos en desuso que no estás explotando y de todos modos pagas por ellos por el % de disponibilidad que dejas en el nodo para evitar crash por falta de recursos, valga la redundancia. En donde trabajo cuando empezó la fiebre de los micro servicios tenían un micro servicio por endpoint, luego se dieron cuenta del desperdicio de recursos por idle state y ahora solo se levantan los endpoints stateless en 1 contenedor, los endpoints statefull en otro y se replican según demanda, comunicados por redis streams + la db por separado en sus propios contenedores. Y la diferencia ha sido de un 30% (+-5%) de diferencia. Lo cual al momento de pagar los VPS ha sido muy notable
Excelente video
Excelente video, Tienes que hacer uno de kafka integrado a microservicios.
Hola! no tengo uno de kafka, pero tengo uno de rabbitMQ que al final es otro message broker, ua-cam.com/video/BYKC9w-eHN4/v-deo.html
Un saludo!
Muy buen canal, gracias por compartir
Hola!! excelente la clase,una consulta veo que trabajas en el ejemplo con IntelliJ IDEA me parece?? si es asi porque ese editor y no visual studio o VScode ?
sí, trabajo con rider desde 2017 o así, de aquella VS estaba bastante mal y ya me acostumbre, en mi opinión, rider sigue siendo mejor que VS pero entiendo quien en 2023/24 pueda soportar usar visual studio.
respecto a VSCode esta aún muy verde en comparación.
Un saludo
Hola buenas noches, excelente video.
Tuve la oportunidad de ver en un proyecto el cual usaron CQRS y
1.- Apuntaba a la misma base de datos (Es lo correcto? porque veo que en tu video haces referencia a DB separadas)
2.- Hay una separaciones de clases *pero en el mismo proyecto* para:
2.1.- Consulta
2.2.- Eliminacion
2.3.- Actualizacion
2.4.- Creacion
==> Es lo correcto?
Agradezco tu orientacion.
Saludos
utilizar la misma db o un solo proyecto, No es lo correcto, pero tampoco incorrecto, depende del tamaño y uso del sistema, si solo tienes uno o dos endpionts que son crud básicos, hacer dos proyectos es programar de más, así que si es pequeño pues bien; y si fuera pequeño, pero realizas 100k gets por minuto, pues habría que separarlo en otro. Al final todo son pros y contras, y hay que evaluarlos, en mi opinión, si es un servicio pequeño y no tiene un uso excesivo (no necesite escalado) puede estar bien que sea 1 pero si es grande lo suyo es tenerlo partido, principalmente para el escalado
Lo de los nombres es un debate que seguirá existiendo en los equipos, a mi personalmente no me importa que se ponga Command y Query, o bien en el namespace o en el nombre de la clase, si lo hiciéramos sabría de manera automática que se esta implementando CQRS. Yo suelo ser riguroso en los nombrados, el código se debe leer como si fuera una historia. Gracias por el contenido y por tu trabajo.
Hola, creo que al final lo que entiendo (disculpa mi simpleza), es que la ventaja de tener dos BBDD es que por ejemplo las bbdd NoSql son mucho mas optimas para las consultas que las relacionales (si no toda la parafernalia extra de estos patrones modernos seria simple redundancia gratuita) quizá parezca un poco escéptico, pero es que soy un conceptista puro, lo breve si bueno dos veces mejor . Si acaso no acierto, con gusto acepto tu corrección
esa es una otra es que las podemos escalar de forma diferente, en ciertas aplciaciones las lecturas van a ser 100 veces las escrituras, asi que podemos escalar una parte y no la otra.
Luego esta el tema de que si haces event sourcing + cqrs + ddd puedes utilizar la base de datos de escritura como source of truth y hacer "pruebas" con la base de datos de lectura, ya que los datos en la de escritura serán siempre correctos.
Pruebas como por ejemplo cambiar de una base de datos a otra, o migrar el servidor sin miedo a perderlo todo.
Genial, excelente contenido y muy bien explicado!
Quisiera como funcianaria el mediador en este patrón. Un saludo y gracias por los videos
Pues hay gente que utiliza MediatR que es una libreria de . NET que representa el patron mediador para notificar que un domain event esta listo y entonces tienes el handler del integration event en la misma aplicación y en memoria (en vez de tener los eventos en el service bus) , pero la gran mayoria de esta gente lo utiliza 1 a 1.
Te permite hacer decoupling de la lógica pero ya está, si la comunicación va a ser 1 - n. Te permite hacer pipelines y tal, y en ese escenario yo si utilizaria mediatr. Pero para comunicaciones 1 a 1 a mi me parece excesivo, pero bueno, no esta mal del todo.
Y si complementas la API Lectura con Redis , seria una excelente idea... Saludos !!!!
Hola, una duda, siguiendo el ejemplo de productos, si mientras se lanza el comando update de un producto llega petición query para recuperar la info del mismo producto, podría darse el caso de que la query no recupere la info actualiza del producto que realiza el command? Me cuesta acabar de ver el tema de sincronizar las bbdd de lectura/escritura. Gracias
Si, es exactamente lo que sucede y es un resultado esperado, este suceso se denomina consistencia eventual y lo veremos en el curso en un par de vídeos.
Tengo una explicación en el blog: www.netmentor.es/entrada/consistencia-eventual-microservicios
Un saludo !
@@NetMentor Perfecto, muchas gracias por aclarar las dudas
crack maquina
El video mejor explicado de CQRS. ¿Cuál es el link del libro?
Me alegro de que te guste!
desafortunadamente tuve unos problemas personales durante el verano y no he podido hacer nada, lo intentaré retomar este invierno. Un saludo y gracias!
donde se consiguen tus libros, muy buen video
Gracias! Por ahora no tengo ningún libro, voy a escribir que tiene que ver con sistemas distribuidos, pero por ahora no esta escrito (con suerte para final de año)
Un saludo!
Muy bien video, tenés algo de Elasticsearch?
Hola, no, por ahora no tengo nada de elasticSearch y no creo que ponga nada pronto ya que tengo una gran lista de cosas antes de Elastic. Un saludo
Super interesantes tus Videos Amigo!. Tienes cursos de paga?
Hola!
No, no tengo cursos de pago, pero tengo un libro que recién saqué está semana
www.netmentor.es/libros/guia-completa-desarrollo-full-stack
@@NetMentor muchas gracias amigo!
Muy bueno
Yo tengo una duda, en el código que nuestras en el video veo que al hacer el create que puede darse el caso de que emitas una publicación de un evento y que luego realmente no llegues a persistir el dato porque pueda ocurrir algún error, problema de conexion etc. Aunque lo colocaras bien, primero persistiendo y luego emitiendo el mensaje podrías tener el mismo problema pero inverso. Como lidias con esos problemas de transacionalidad?
en este caso tienes tres opciones:
Si emites el evento al service bus, tu aplicación como tal ya no es responsable de que el resto funcionen bien, si el probelma es que el publicar el evento falla, entonces lo que puedes hacer es una especie de transaccón de que si el mensaje no se propaga, simplemente haces rollback de la base de datos.
La segunda opción, y la más común es que cuando haces el heathcheck a rabbitMQ (o kafka o lo que uses) si da negativo te saltas todo lo que tienes en cache o en la bbdd local y haces llamadas todo el rato al otro microservicio, la infraestrucutra tendrá más carga de la habitual hasta que se arregle el problema.
La última opción, aunque es más drástica y requere mucho más código, es tener un state machine, pero es mas para situaciones en las que por ejemplo se va la luz o se cae la app de repente (osea, el proceso se queda a medias) que basicamente guarda en el punto en el que la app ha parado y cuando la app vuelve a empezar, se ejecuta desde ahí.
Un saludo!
@@NetMentor Tuve la misma duda, ¿cómo es el manejo de errores en este sistema?.
Entiendo que creando una especie de trasacción se puede resolver no me imagino cómo implementar una transación con rabbitMQ (o cualquier otro).
En la segunda opción, ¿qué codigo extra requiere?
La tercer opción creo que sólo sería válida en situaciones muy especificias
Técnicamente la tercera opción la puedes conseguir implementando Microsoft Orleans (una librería de Microsoft), pero vaya, por normal general necesitas utilizar el patrón SAGA y si algo da error tener los workflows listos para "recuperar".
Pero lo más normal en sistemas distribuidos es que el evento se vuelva a leer y si sigue dando error arreglarlo porque es un bug en alguna parte. Dependerá de lo crítica que sea esa parte de la aplicación en si puedes permitirte tener la información incompleta un rato o no.
No entendí la parte donde el consumer se pega a rabbit MQ y consume el mensaje, este no seria el patrón producers/consumers?, y la pregunta es porque el mensaje desaparece de RabbitMQ, no debería de quedar allí, por si algún otro consumer lo necesita?, porque el consumer va y busca el mensaje?, no es el RabbitMQ quien debería llamar ese consumer y enviarle tal mensaje?, o estoy confundido en la practica y conceptos?
Hola! CQRS y Producers/consumers son dos patrones completamente diferentes, que pueden trabajar a la vez perfectamente, ya que uno no afecta al otro. Por ejemplo, en todos los servicios que el sistema Distribt tienen, no todos cumplen CQRS, si vas al GitHub hay una imagen con etiquetas en donde se cumple cada patrón.
El motivo por el que el mensaje desaparece de rabbitMQ está explicado en el vídeo de RabbitMQ (ua-cam.com/video/BYKC9w-eHN4/v-deo.html), es porque le exchange publica a las colas y las colas son 1 a 1 con la aplicación (RabbitMQ funciona diferente a Kafka, en Kafka si se queda el mensaje);
El consumer va y busca el mensaje porque no es rabbitMQ el que hace un push, sino que es la app la que consume (cada X segundos) los mensajes.
@@NetMentor gracias por la respuesta, pero entonces yo no puedo tener un producers/consumers usando rabbitMQ (solo me permite 1-1)? El tener el patrón de producers/consumers solo lo proporciona el exchange que se esté usando, en el caso de kafka? ¿Ósea es un patrón que viene implementado dentro de la tecnología del broker de mensajería? ¿No es algo que nosotros tengamos que hacer?
Si puedes, te recomiendo que te mires este video ua-cam.com/video/BYKC9w-eHN4/v-deo.html
Pero resumiendo, el mensaje en vez de ir a un Brooker fanout como en Kafka y de ahí se propaga lo.wie hace es ir a un "exchange" y del exchange puede ir a otros exchanges o a colas (y no es fanout como Kafka, sino que se puede configurar).
Para aplicar producer /consumer necesitas pasar por las.colaas porque las apps no pueden escuchar de un exchange.
Hay una opción para no borrar los.mensjaes en rabbitmq también, pero vaya que eso, es básicamente lo mismo implementado un poco diferente.
Si que es verdad que depende del caso de uso, no vas a tener los mensajes para volver a ejecutarlos, pero en la práctica en Kafka se acaban borrando por tema espacio y dinero que cuesta almacenarlos.