Translate

jueves, 9 de diciembre de 2021

[eBook] Continuous API Management, 2nd Edition

  Me llego este mail de la gente de NGINX y les comparto : 

EBOOK

Image

The second edition of this O’Reilly eBook, sponsored by NGINX, provides maturity models for individual APIs and multi-API landscapes to help you invest the right human and company resources for the right maturity level at the right time.

How do you balance the desire for agility and speed with the need for robust and scalable operations? Four API experts show software architects, program directors, and product owners how to maximize the value of their APIs by managing them as products through a continuous lifecycle.

In this eBook you will learn:

  • Which API decisions you need to govern
  • How the continuous improvement model governs change throughout an API’s lifetime
  • About the five stages of the complete API product lifecycle
  • How to manage APIs published by your organization

miércoles, 8 de diciembre de 2021

Free Serverless App Development O'Reilly Book

 Me llego este mail de la gente de infoQ y O'Reilly y les comparto : 

December 2021

 

Sent on behalf of Cockroach Labs to InfoQ Industry Email Notice Subscribers

Cockroach Labs

In this hands-on guide, developers will learn to build production-ready serverless apps and services on Google Cloud Run.

Download Book

The 10-chapter book includes tutorials for building and deploying a variety of serverless applications across Google Cloud. Ultimately, developers will learn how serverless development can dramatically simplify the building and scaling of applications.

This guide, authored by Wietse Venema, covers:

  • How to build serverless apps on Google Cloud Run
  • How to use HTTP to create unique experiences for your users
  • How identity and access management (IAM) work in serverless environments
  • How to deploy applications across a variety of Google Cloud services
  • CockroachDB is an official partner of Google Cloud Run and Google. Here's our solution to integrating CockroachDB with Google Cloud Run.

Download it for free and start building!

Cheers,
The Cockroach Labs Team


twitterfacebooklinkedinyoutube

You have received this email because you opted-in to the "InfoQ Industry Email Notices" box when you registered to InfoQ.com, where we send infrequent notices on behalf of our partners, user groups, conferences, etc. To unsubscribe to the InfoQ Industry Email Notices, please click the following link: Unsubscribe
- - -
C4Media Inc. (InfoQ.com),
2275 Lake Shore Boulevard West,
Suite #325,
Toronto, Ontario, Canada,
M8V 3Y3

martes, 7 de diciembre de 2021

Pants, un sistema de construcción de software multilenguaje


Pants es un sistema de construcción de software escalable. Es útil para repositorios de código de todos los tamaños, pero es particularmente valioso para aquellos que contienen múltiples piezas distintas pero interdependientes.

Pants organiza las diversas herramientas y pasos que procesan su código fuente en software implementable, que incluyen:

  • Resolución de dependencia
  • Generación de código
  • Verificación de tipos y compilación
  • Pruebas
  • Linting
  • Formateo
  • packaging
  • Introspección del proyecto

Pants es similar a herramientas como make, ant, maven, gradle, sbt, bazel y otras. Su diseño se basa en ideas e inspiración de estas herramientas anteriores, al tiempo que optimiza la velocidad, la corrección y la ergonomía en los casos de uso del mundo real de hoy.

Lo que me llamo la atención es que soporta, Python, Shell, Docker, Go, Java y Scala. Esta bueno para equipos que tengan que trabajar con varios lenguajes y tecnología y pueden compilar con una sola herramienta.  

Dejo link: https://www.pantsbuild.org/

lunes, 6 de diciembre de 2021

¿Cómo saber si sus microservicios tienen el tamaño correcto?


 ¿Cómo saber si sus microservicios tienen el tamaño correcto? 

Si un microservicio es demasiado grande, es probable que vea lo siguiente:

  • Un servicio con demasiadas responsabilidades: el flujo general de la lógica empresarial en el servicio es complicado y parece estar imponiendo una gama demasiado diversa de reglas empresariales.
  • El servicio administra datos en una gran cantidad de tablas: un microservicio es el sistema de registro de los datos que administra. Si se encuentra almacenando datos en varias tablas o llegando a tablas fuera de la base de datos inmediata. Un microservicio no debe poseer más de tres a cinco tablas. Si lo hace, es probable que su servicio tenga demasiada responsabilidad.
  • Demasiados casos de prueba: los servicios pueden crecer en tamaño y responsabilidad con el tiempo. Si tiene un servicio que comenzó con una pequeña cantidad de casos de prueba y termina con cientos de casos de prueba unitarios y de integración, es posible que deba refactorizar.

¿Qué pasa con un microservicio que es demasiado pequeño?

  • Los microservicios en una parte del dominio del problema se reproducen como conejos: si todo se convierte en un microservicio, componer la lógica empresarial a partir de los servicios se convierte en complejo y difícil porque la cantidad de servicios necesarios para realizar un trabajo crece enormemente. Un error común es cuando tiene docenas de microservicios en una aplicación y cada servicio interactúa con una sola tabla de base de datos.
  • Los microservicios se convierten en una colección de servicios CRUD (Crear, Reemplazar, Actualizar, Eliminar) simples; los microservicios son una expresión de la lógica empresarial y no una capa de abstracción sobre sus fuentes de datos. Si sus microservicios no hacen nada más que lógica relacionada con CRUD, probablemente sean demasiado pequeño y falte algo.

Una arquitectura de microservicios debe desarrollarse con un proceso evolutivo en el que sepa que no obtendrá el diseño correcto la primera vez. Por eso es mejor comenzar con un primer conjunto de servicios siendo más detallado con las iteraciones. También es importante no ser dogmático con su diseño. Puede encontrarse con limitaciones físicas en sus servicios donde tendrá que crear un servicio de agregación que combine datos porque dos servicios separados serán demasiado grandes, o cuando no existan límites claros entre las líneas de dominio de un servicio.

Al final, hay que adoptar un enfoque pragmático, en lugar de perder el tiempo tratando de obtener un diseño perfecto.


¿Como diseñar la arquitectura de microservicios?


El trabajo del arquitecto es proporcionar el andamiaje contra el cual los desarrolladores construirán su código para que todas las piezas de la aplicación encajen.

Al construir una arquitectura de microservicios, el arquitecto de un proyecto se centra en tres tareas clave:

  •   Descomposición el problema 
  •   Establecer la granularidad del servicio
  •   Definición de las interfaces de servicio

Descomposición el problema : Frente a la complejidad, la mayoría de las personas intenta dividir el problema en el que están trabajando en partes manejables. Hacen esto para no tener que tratar de encajar todos los detalles del problema en sus cabezas. En cambio, desglosan el problema de manera abstracta en algunas partes clave y luego buscan las relaciones que existen entre estas partes.
En una arquitectura de microservicios, el arquitecto divide el problema empresarial en fragmentos que representan dominios de actividad discretos. Estos fragmentos encapsulan las reglas comerciales y la lógica de datos asociada con una parte particular del dominio comercial.
Aunque desea que los microservicios encapsulen todas las reglas comerciales para realizar una sola transacción, esto no siempre es factible. A menudo, tendrá situaciones en las que necesitará grupos de microservicios que trabajen en diferentes partes del dominio empresarial para completar una transacción completa. Un arquitecto separa los límites de servicio de un conjunto de microservicios al observar dónde el dominio de datos no parece encajar.
Por ejemplo, un arquitecto puede mirar un flujo de negocios que se llevará a cabo mediante código y darse cuenta de que necesita información tanto del cliente como del producto. La presencia de dos dominios de datos discretos es una buena indicación de que hay varios microservicios en juego. La forma en que interactúan las dos partes diferentes de la transacción comercial generalmente se convierte en la interfaz de servicio para los microservicios.
Separar un dominio empresarial es una forma de arte más que una ciencia en blanco y negro. Se pueden utilizar las siguientes pautas para identificar y descomponer un problema empresarial en candidatos a microservicio:
  1. Describe el problema empresarial y escucha los sustantivos que usas para describir el problema. El uso de los mismos sustantivos una y otra vez al describir el problema suele ser una indicación de un dominio empresarial central y una oportunidad para un microservicio. 
  2. Presta atención a los verbos. Los verbos resaltan acciones y, a menudo, representan los contornos naturales del dominio de un problema. Si se encuentra diciendo "la transacción X necesita obtener datos de la cosa A y la cosa B", eso generalmente indica que hay varios servicios en juego. 
  3. Busque la cohesión de datos. A medida que divide su problema comercial en partes discretas, busque piezas de datos que estén muy relacionadas entre sí. Si de repente, durante el curso de su conversación, está leyendo o actualizando datos que son radicalmente diferentes de los que ha estado discutiendo hasta ahora, es posible que tenga otro candidato de servicio. Los microservicios deben poseer completamente sus datos.
Establecer la granularidad del servicio : Una vez que tenga un modelo de datos simplificado, podemos comenzar el proceso de definir qué microservicios necesitará en la aplicación.
El objetivo es tomar estas piezas importantes de funcionalidad y extraerlas en unidades completamente autónomas que se pueden construir e implementar independientemente de cada una. Pero extraer servicios del modelo de datos implica más que volver a empaquetar el código en proyectos separados. También se trata de extraer las tablas de la base de datos real a las que acceden los servicios y permitir que solo cada servicio individual acceda a las tablas en su dominio específico. 
Después de haber dividido un dominio problemático en partes discretas, a menudo nos encontraremos  luchando para determinar si hemos logrado el nivel correcto de granularidad para los servicios. Un microservicio que sea demasiado burdo o detallado tendrá una serie de atributos reveladores.
Cuando crea una arquitectura de microservicio, la cuestión de la granularidad es importante, pero puede usar los siguientes conceptos para determinar la solución correcta:
  • Es mejor comenzar ampliamente con microservicio y refactorizar a servicios más pequeños. Es fácil exagerar cuando comienza su viaje de microservicio y convierte todo en un microservicio. Pero descomponer el dominio del problema en pequeños servicios a menudo conduce a una complejidad prematura porque los microservicios se convierten en nada más que servicios de datos detallados.
  • Concéntrese primero en cómo interactuarán sus servicios entre sí: esto ayudará a establecer las interfaces generales de su dominio de problemas. Es más fácil refactorizar de un grano demasiado grueso a un grano demasiado fino.
  • Las responsabilidades del servicio cambiarán con el tiempo a medida que aumente su comprensión del dominio del problema. A menudo, un microservicio adquiere responsabilidades como una nueva aplicación se solicita funcionalidad. Lo que comienza como un único microservicio puede convertirse en varios servicios, con el microservicio original actuando como una orquestación.
Definición de las interfaces de servicio: La última parte se trata de definir cómo los microservicios en su aplicación se comunicarán entre sí. Al construir lógica de negocios con microservicios, las interfaces para los servicios deben ser intuitivas y los desarrolladores deben conocer el ritmo de cómo funcionan todos los servicios en la aplicación aprendiendo uno o dos de los servicios en la aplicación.
En general, las siguientes pautas se pueden utilizar para pensar en el diseño de la interfaz de servicio:
  • Adopte la filosofía REST: el enfoque REST de los servicios es fundamentalmente la adopción de HTTP como el protocolo de invocación para los servicios y el uso de verbos HTTP estándar (GET, PUT, POST y DELETE). Modele sus comportamientos básicos en torno a estos verbos HTTP.
  • Use URI para comunicar la intención: el URI que usa como end-points para el servicio debe describir los diferentes recursos en su dominio de problemas y proporcionar un mecanismo básico para las relaciones de recursos dentro de su dominio de problemas.
  • Use JSON para sus solicitudes y respuestas: la notación de objetos JavaScript (en otras palabras, JSON) es un protocolo de serialización de datos extremadamente liviano y es mucho más fácil de consumir que XML.
  • Utilice códigos de estado HTTP para comunicar los resultados: el protocolo HTTP tiene una gran cantidad de códigos de respuesta estándar para indicar el éxito o el fracaso de un servicio. Aprender estos códigos de estado y, lo que es más importante, utilícelos de forma coherente en todos sus servicios.
Todas las pautas básicas conducen a una sola cosa: hacer que sus interfaces de servicio sean fáciles de entender y consumibles. Quiere que un desarrollador se siente y observe las interfaces de servicio y comience a usarlas. Si un microservicio no es fácil de consumir, los desarrolladores harán todo lo posible para solucionarlo y subvertir la intención de la arquitectura.

viernes, 3 de diciembre de 2021

Una guía práctica sobre cómo las herramientas de gestión del tráfico de Kubernetes pueden ayudarlo a resolver los desafíos de resiliencia, visibilidad y seguridad.

La gente a Nginx me mando esta guia y la comparto con ustedes.  

NEWSLETTER

[eBook] Taking Kubernetes from Test to Production

A practical guide to how Kubernetes traffic management tools – including an Ingress controller and service mesh – can help you solve the challenges of resilience, visibility, and security that come with running Kubernetes in production.

Fleet, el IDE de nueva generación de JetBrains


JetBrains Fleet es la respuesta de JetBrains a Visual Code. 

Construido desde cero, Fleet es el resultado de 20 años de experiencia en el desarrollo de IDEs. Utiliza el motor de procesamiento de código de IntelliJ, con una arquitectura de IDE distribuida y una interfaz de usuario totalmente renovada.

Fleet es un editor de texto rápido y ligero que permite navegar por el código y editarlo rápidamente cuando lo necesite. Se inicia en pocos segundos para que pueda empezar a trabajar al momento y puede transformarse fácilmente en un IDE, gracias al motor de procesamiento de código de IntelliJ, que se ejecuta de forma independiente al editor.

Fleet hereda lo que más gusta a los desarrolladores de los IDE basados en IntelliJ: la finalización contextualizada de código en el proyecto, la navegación a las definiciones y los usos, las comprobaciones de la calidad del código sobre la marcha y los arreglos rápidos.

La arquitectura de Fleet está diseñada para que sea compatible con varias configuraciones y flujos de trabajo. Puede ejecutar Fleet en su equipo directamente o trasladar algunos de los procesos —por ejemplo, el procesamiento del código— a la nube.

Fleet ofrece una experiencia multilenguaje y una asistencia inteligente para muchos lenguajes y tecnologías, que pronto se completará con nuevos complementos específicos. Gracias a los LSP, también podrá utilizar otros servicios de lenguajes en Fleet.

Fleet está diseñado para detectar de forma automática la configuración de su proyecto a partir del código fuente, aprovechando al máximo el valor que obtiene del motor inteligente de procesamiento de código, de manera que se reduce al mínimo la necesidad de configurar el proyecto en el IDE.

Fleet ofrece una experiencia de usuario familiar y coherente para los diferentes tipos de proyecto, de modo que solo utilizará un IDE, sin importar el conjunto de tecnologías que emplee o el tipo de proyecto en el que esté trabajando.

Para que tanto usted como su equipo empiecen a trabajar en sus proyectos todavía más rápido, Fleet puede aprovechar la potencia de los entornos de desarrollo de Space. Su proyecto y Fleet se ejecutarán en una máquina virtual preconfigurada de alto rendimiento que se «prepara» y está lista para usar en pocos segundos. Puede conectarse a un entorno de desarrollo con Fleet desde su equipo personal en unos pocos clics y deshacerse de este al terminar la tarea.

Dejo link: https://www.jetbrains.com/es-es/fleet/

martes, 30 de noviembre de 2021

Libros gratuitos

 

Download IT Guides!

 

JAXB Tutorial

The first specification of JAXB was done in March 2003 and the work process is tracked in the Java Specification Request 31. In this specification request you can find a lot of...

 
 

JavaFX Programming Cookbook

JavaFX 2.0 and later is implemented as a native Java library, and applications using JavaFX are written in native Java code. JavaFX Script has been scrapped by Oracle, but development is...

 
 

Java Servlet Tutorial

A servlet can almost be thought of as an applet that runs on the server side-without a face. Java servlets make many Web applications possible.

Java...

 
 

Groovy Programming Cookbook

Groovy 1.0 was released on January 2, 2007, and Groovy 2.0 in July, 2012. Since version 2, Groovy can also be compiled statically, offering type inference and performance very close to...

 

lunes, 29 de noviembre de 2021

Por qué están teniendo éxito las arquitecturas de microservicios?


La historia del desarrollo de software está plagada de historias de grandes proyectos de desarrollo que, después de una inversión de millones de dólares y cientos de miles de horas de desarrollador de software, y con muchas de las mejores y más brillantes mentes de la industria trabajando en ellos, de alguna manera nunca lograron para entregar algo de valor a sus clientes y literalmente colapsó bajo su propia complejidad y peso.

Estos proyectos gigantescos tendían a seguir metodologías de desarrollo en cascada grandes y tradicionales que insistían en que todos los requisitos y el diseño de la aplicación se definieran al comienzo del proyecto. Se puso tanto énfasis en conseguir que todas las especificaciones del software fueran “correctas” que hubo poco margen para cumplir con los nuevos requisitos comerciales, o refactorizar y aprender de los errores cometidos en las primeras etapas de desarrollo.

Sin embargo, la realidad es que el desarrollo de software no es un proceso lineal de definición y ejecución, sino más bien evolutivo en el que se necesitan varias iteraciones de comunicación, aprendizaje y entrega al cliente antes de que el equipo de desarrollo realmente comprenda el problema. 

Para agravar los desafíos del uso de metodologías tradicionales, es que muchas veces la granularidad de los artefactos de software que se entregan estos proyectos: 

  • Estrechamente acoplado: la invocación de la lógica empresarial se realiza a nivel del lenguaje de programación en lugar de a través de protocolos como SOAP and REST. Esto aumenta en gran medida la posibilidad de que incluso un pequeño cambio en un componente de la aplicación pueda romper otras partes de la aplicación e introducir nuevos errores.
  • Fugas: la mayoría de las aplicaciones de software grandes administran diferentes tipos de datos. Por ejemplo, una aplicación de gestión de relaciones con el cliente (CRM) puede gestionar información sobre clientes, ventas y productos. En un modelo tradicional, estos datos se mantienen en el mismo modelo de datos y dentro del mismo almacén de datos. Aunque existen límites obvios entre los datos, con demasiada frecuencia resulta tentador salir de un dominio para acceder directamente a los datos que pertenecen a otro equipo. Este fácil acceso a los datos crea dependencias ocultas y permite que los detalles de implementación de las estructuras de datos internas de un componente se filtren a través de toda la aplicación. Incluso pequeños cambios en una sola tabla de base de datos pueden requerir un número significativo de cambios de código y pruebas de regresión en toda la aplicación.
  • Monolítico: debido a que la mayoría de los componentes de una aplicación tradicional residen en una única base de código que se comparte entre varios equipos, cada vez que se realiza un cambio en el código, se debe volver a compilar la aplicación completa, volver a ejecutar durante un ciclo de prueba completo, y redistribuido. Incluso los pequeños cambios en el código base de la aplicación, ya sean nuevos requisitos del cliente o correcciones de errores, se vuelven costosos y requieren mucho tiempo, y los grandes cambios se vuelven casi imposible de hacer de manera oportuna.

Una arquitectura basada en microservicios adopta un enfoque diferente para brindar funcionalidad. Específicamente, las arquitecturas basadas en microservicios tienen estas características:

  • Restringido: los microservicios tienen un único conjunto de responsabilidades y su alcance es limitado. Los microservicios adoptan la filosofía UNIX de que una aplicación no es más que una colección de servicios donde cada servicio hace una cosa y hace esa cosa realmente bien.
  • Poco acoplado: una aplicación basada en microservicios es una colección de pequeños servicios que solo interactúan entre sí a través de una especificación y no de implementación. Cada microservicio tiene una interfaz bien definida, utilizando un protocolo de invocación no propietario (por ejemplo, HTTP y REST). Siempre que la interfaz del servicio no cambie, los propietarios del microservicio tienen más libertad para realizar modificaciones en el servicio que en una arquitectura de aplicación tradicional.
  • Abstración: los microservicios poseen por completo sus estructuras y fuentes de datos. Los datos que pertenecen a un microservicio solo pueden ser modificados por ese servicio. El control de acceso a la base de datos que contiene los datos del microservicio se puede bloquear para permitir que solo el servicio acceda a ella.
  • Independiente: cada microservicio en una aplicación de microservicio se puede compilar e implementar independientemente de los otros servicios utilizados en la aplicación. Esto significa que los cambios se pueden aislar y probar mucho más fácilmente que con una aplicación monolítica.

¿Por qué estos atributos de la arquitectura de microservicios son importantes para el desarrollo basado en la nube? Las aplicaciones basadas en la nube en general tienen :

  • Una base de usuarios grande y diversa: los diferentes clientes desean funciones diferentes y no quieren tener que esperar un ciclo de lanzamiento de aplicaciones prolongado antes de poder comenzar a usar estas funciones. Los microservicios permiten que las características se entreguen rápidamente, porque cada servicio tiene un alcance pequeño y se accede a él a través de una interfaz bien definida.
  • Requisitos de tiempo de actividad extremadamente altos: debido a la naturaleza descentralizada de los microservicios, las aplicaciones basadas en microservicios pueden aislar más fácilmente fallas y problemas apartes de una aplicación sin eliminar la aplicación completa. Esto reduce el tiempo de inactividad general de las aplicaciones y las hace más resistentes a los problemas.
  • Requisitos de volumen desiguales: las aplicaciones tradicionales implementadas dentro de las cuatro paredes de un centro de datos corporativo generalmente tienen patrones de uso consistentes que emergen con el tiempo. Esto simplifica la planificación de la capacidad para este tipo de aplicaciones. Pero en una aplicación basada en la nube, un simple tweet en Twitter o una publicación en Slashdot puede impulsar la demanda de una aplicación basada en la nube por las nubes.

Debido a que las aplicaciones de microservicio se dividen en pequeños componentes que se pueden implementar de forma independiente entre sí, es mucho más fácil enfocarse en los componentes que están bajo carga y escalen esos componentes horizontalmente en varios servidores en una nube.

Aunque se necesita más que personal técnico para entregar una aplicación completa, creo que la base para el desarrollo exitoso de microservicios comienza con las perspectivas de tres roles críticos:

  • El arquitecto: el trabajo del arquitecto es ver el panorama general y comprender cómo se puede descomponer una aplicación en microservicios individuales y cómo los microservicios interactuarán para ofrecer una solución.
  • El desarrollador de software: el desarrollador de software escribe el código y comprende en detalle cómo funcionarán el lenguaje y los marcos de desarrollo del lenguaje.
  • El ingeniero de DevOps: el ingeniero de DevOps aporta inteligencia sobre cómo se implementan y administran los servicios no solo en la producción, sino también en todos los los entornos de no producción. Las palabras clave del ingeniero de DevOps son coherencia y repetibilidad en todos los entornos.


viernes, 26 de noviembre de 2021

Primeros pasos con Apache Kafka parte 21

Seguimos con Kafka

Hasta ahora nos hemos centrado en aprender la API del consumidor, pero solo hemos analizado algunas de las propiedades de configuración, solo los obligatorios bootstrap.servers, group.id, key.deserializer y value.deserializer. Toda la configuración del consumidor está documentada en la documentación de Apache Kafka. La mayoría de los parámetros tienen una razón pueden tener valores predeterminados y no requieren modificación, pero algunos tienen implicaciones en el rendimiento y la disponibilidad de los consumidores. Echemos un vistazo a algunas de las propiedades más importantes.

fetch.min.bytes

Esta propiedad permite que un consumidor especifique la cantidad mínima de datos que desea recibir del corredor al buscar registros. Si un corredor recibe una solicitud de registros de un consumidor, pero los nuevos registros suman menos bytes que min.fetch.bytes, el corredor esperará hasta que haya más mensajes disponibles antes de devolver los registros al consumidor. Esto reduce la carga tanto para el consumidor como para el corredor, ya que tienen que manejar menos mensajes de ida y vuelta en los casos en que los temas no tienen mucha actividad nueva (o para horas de menor actividad del día). Deberá establecer este parámetro más alto que el predeterminado si el consumidor está usando demasiada CPU cuando no hay muchos datos disponibles, o reducir la carga de los intermediarios cuando tiene una gran cantidad de consumidores.

fetch.max.wait.ms

Al establecer fetch.min.bytes, le indica a Kafka que espere hasta que tenga suficientes datos para enviar antes de responder al consumidor. fetch.max.wait.ms te permite controlar cuánto tiempo esperar. De forma predeterminada, Kafka esperará hasta 500 ms. Esto da como resultado hasta 500 ms de latencia adicional en caso de que no haya suficientes datos fluyendo al tema de Kafka para satisfacer la cantidad mínima de datos para devolver. Si desea limitar la latencia potencial (generalmente debido a que los SLA controlan la latencia máxima de la aplicación), puede establecer fetch.max.wait.ms en un valor más bajo. Si establece fetch.max.wait.ms en 100 ms y fetch.min.bytes en 1 MB, Kafka recibirá una solicitud de recuperación del consumidor y responderá con datos cuando tenga 1 MB de datos para devolver o después de 100 ms, lo que ocurra primero.

max.partition.fetch.bytes

Esta propiedad controla el número máximo de bytes que el servidor devolverá por partición. El valor predeterminado es 1 MB, lo que significa que cuando KafkaConsumer.poll () devuelve ConsumerRecords, el objeto de registro utilizará como máximo un máximo de partición.fetch.bytes por partición asignada al consumidor. Entonces, si un tema tiene 20 particiones y tiene 5 consumidores, cada consumidor deberá tener 4 MB de memoria disponible para Consumer Records. En la práctica, querrá asignar más memoria ya que cada consumidor necesitará manejar más particiones si otros consumidores del grupo fallan. máx. partition.fetch.bytes debe ser más grande que el mensaje más grande que aceptará un corredor (determinado por la propiedad max.message.size en la configuración del corredor), o el corredor puede tener mensajes que el consumidor no podrá consumir, en los caso que el consumidor se cuelgue tratando de leerlos. Otra consideración importante al establecer max.partition.fetch.bytes es la cantidad de tiempo que le toma al consumidor procesar los datos. Como recordará, el consumidor debe llamar a poll () con la frecuencia suficiente para evitar el tiempo de espera de la sesión y el reequilibrio posterior. Si la cantidad de datos que devuelve un solo poll () es muy grande, el consumidor puede tardar más en procesar, lo que significa que no llegará a la siguiente iteración del ciclo de sondeo a tiempo para evitar un tiempo de espera de sesión. Si esto ocurre, las dos opciones son reducir el máx. partición.fetch.bytes o para aumentar el tiempo de espera de la sesión.

session.timeout.ms

La cantidad de tiempo que un consumidor puede estar fuera de contacto con los corredores mientras aún se considera vivo es de 3 segundos. Si pasa más de session.timeout.ms sin que el consumidor envíe un latido al coordinador del grupo, se considera muerto y el coordinador del grupo activará un reequilibrio del grupo de consumidores para asignar particiones del consumidor muerto a los otros consumidores del grupo. . Esta propiedad está estrechamente relacionada con heartbeat.interval.ms. heartbeat.interval.ms controla la frecuencia con la que el método poll () de KafkaConsumer enviará un latido al coordinador del grupo, mientras que session.timeout.ms controla cuánto tiempo puede pasar un consumidor sin enviar un latido. Por lo tanto, esas dos propiedades generalmente se modifican juntas: heatbeat.interval.ms debe ser menor que session.timeout.ms, y generalmente se establece en un tercio del valor de tiempo de espera. Entonces, si session.timeout.ms es de 3 segundos, heartbeat.interval.ms debería ser de 1 segundo. Establecer session.timeout.ms por debajo del valor predeterminado permitirá a los grupos de consumidores detectar y recuperarse de fallas antes, pero también puede causar reequilibrios no deseados como resultado de que los consumidores tarden más en completar el ciclo de sondeo o la recolección de basura. Configurar session.timeout.ms más alto reducirá la posibilidad de un reequilibrio accidental, pero también significa que tomará más tiempo detectar una falla real.

auto.offset.reset

Esta propiedad controla el comportamiento del consumidor cuando comienza a leer una partición para la cual no tiene una compensación comprometida o si la compensación comprometida que tiene no es válida (generalmente porque el consumidor estuvo inactivo durante tanto tiempo que el registro con esa compensación ya estaba obsoleto en el corredor). El valor predeterminado es "más reciente", lo que significa que, sin una compensación válida, el consumidor comenzará a leer los registros más recientes (registros que se escribieron después de que el consumidor comenzó a ejecutar). La alternativa es "la más temprana", lo que significa que, sin un desplazamiento válido, el consumidor leerá todos los datos de la partición, comenzando desde el principio.

enable.auto.commit

Este parámetro controla si el consumidor confirmará las compensaciones automáticamente y su valor predeterminado es verdadero. Configúrelo en falso si prefiere controlar cuándo se confirman las compensaciones, lo cual es necesario para minimizar los duplicados y evitar la pérdida de datos. Si establece enable.auto.commit en true, es posible que también desee controlar la frecuencia con la que se confirmarán las compensaciones mediante auto.commit.interval.ms.

division.assignment.strategy

Aprendimos que las particiones se asignan a los consumidores en un grupo de consumidores. Un PartitionAssignor es una clase que, dados los consumidores y los temas a los que se suscribieron, decide qué particiones se asignarán a qué consumidor. De forma predeterminada, Kafka tiene dos estrategias de asignación:

  • Range: Asigna a cada consumidor un subconjunto consecutivo de particiones de cada tema al que se suscribe. Entonces, si los consumidores C1 y C2 están suscritos a dos temas, T1 y T2, y cada uno de los temas tiene tres particiones, luego a C1 se le asignarán las particiones 0 y 1 de los temas T1 y T2, mientras que a C2 se le asignará la partición 2 de esos temas. Debido a que cada tema tiene un número impar de particiones y la asignación se realiza para cada tema de forma independiente, el primer consumidor termina con más particiones que el segundo. Esto sucede siempre que se utiliza la asignación de rango y el número de consumidores no divide el número de particiones en cada tema de forma ordenada.
  • RoundRobin: Toma todas las particiones de todos los temas suscritos y las asigna a los consumidores de forma secuencial, una por una. Si C1 y C2 se describieron anteriormente, usaron RoundRobin asignación, C1 tendría las particiones 0 y 2 del tema T1 y la partición 1 del tema T2. C2 tendría la partición 1 del tema T1 y las particiones 0 y 2 del tema T2. En general, si todos los consumidores están suscritos a los mismos temas (un escenario muy común), la asignación de RoundRobin terminará con todos los consumidores con el mismo número de particiones (o como máximo una diferencia de partición). 
division.assignment.strategy permite elegir una estrategia de asignación de partición. El valor predeterminado es org.apache.kafka.clients.consumer.RangeAssignor, que implementa la estrategia de rango descrita anteriormente. Puede reemplazarlo con org.apache.kafka.clients.consumer.RoundRobinAssignor. Una opción más avanzada es implementar su propia estrategia de asignación, en cuyo caso partition.assignment.strategy debe apuntar al nombre de su clase.

client.id

Esta puede ser cualquier cadena y será utilizada por los intermediarios para identificar los mensajes enviados desde el cliente. Se utiliza en registros y métricas, y para cuotas.

registros.max.poll.

Esto controla el número máximo de registros que devolverá una sola llamada a poll (). Esto es útil para ayudar a controlar la cantidad de datos que su aplicación necesitará procesar en el ciclo de sondeo. 

receive.buffer.bytes y send.buffer.bytes

Estos son los tamaños de los búferes de envío y recepción de TCP que utilizan los sockets al escribir y leer datos. Si se establecen en -1, se utilizarán los valores predeterminados del sistema operativo. Puede ser una buena idea aumentarlos cuando los productores o consumidores se comunican con intermediarios en un centro de datos diferente, porque esos enlaces de red suelen tener mayor latencia y menor ancho de banda.

sábado, 20 de noviembre de 2021

Ejemplo de microservicio con Spring boot y Spring Cloud


Vamos hacer un hola mundo con microservicios y Spring boot. Ojo usamos algunas tecnologías, no todo porque es un hola mundo: 

//Removed other imports for conciseness

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;


@SpringBootApplication

@RestController

@RequestMapping(value="hello")

@EnableCircuitBreaker //Enables the service to use the Hystrix and Ribbon libraries

@EnableEurekaClient //Service discovery 

public class Application {

public static void main(String[] args) {

    SpringApplication.run(Application.class, args);

    }


    @HystrixCommand(threadPoolKey = "helloThreadPool")

    public String helloRemoteServiceCall(String firstName, String lastName){

        ResponseEntity<String> restExchange = restTemplate.exchange( 

            "http://logical-service-id/name/[ca]{firstName}/{lastName}",

             HttpMethod.GET,

             null, String.class, firstName, lastName);

        return restExchange.getBody();

}


    @RequestMapping(value="/{firstName}/{lastName}", method = RequestMethod.GET)

    public String hello( @PathVariable("firstName") String firstName,

        @PathVariable("lastName") String lastName) {

         return helloRemoteServiceCall(firstName, lastName)

    }

}

La anotación @EnableCircuitBreaker le dice que el microservicio Spring va a utilizar las bibliotecas de Netflix Hystrix en su aplicación. La anotación @EnableEurekaClient dice que el  microservicio se registre con un agente de Eureka Service Discovery y que utilizará el descubrimiento de servicios para buscar puntos finales de servicios REST remotos en su código. La configuración se lleva a cabo en un archivo de propiedades que le indicará al servicio simple la ubicación y el número de puerto de un servidor Eureka para contactar. Usamos Hystrix cuando declaramos el método de saludo:

@HystrixCommand(threadPoolKey = "helloThreadPool")
public String helloRemoteServiceCall(String firstName, String lastName)

La anotación @HystrixCommand hace dos cosas. Primero, cada vez que se llama al método helloRemoteServiceCall, no se invocará directamente. En cambio, el método se delegará a un grupo de subprocesos administrado por Hystrix. Si la llamada tarda demasiado (el valor predeterminado es un segundo), Hystrix interviene e interrumpe la llamada. Esta es la implementación del patrón de circuit breaker . Lo segundo que hace esta anotación es crear un grupo de subprocesos llamado helloThreadPool que es administrado por Hystrix. Todas las llamadas al método helloRemoteServiceCall solo se producirán en este grupo de subprocesos y se aislarán de cualquier otra llamada de servicio remoto que se realice.

Lo último a tener en cuenta es lo que ocurre dentro del método helloRemoteServiceCall. La presencia de @EnableEurekaClient le ha dicho a Spring Boot que va a usar una clase RestTemplate modificada (no es así como la Spring RestTemplate estándar funcionaría de fábrica) cada vez que realiza una llamada de servicio REST. Esta clase RestTemplate le permitirá pasar un ID de servicio lógico para el servicio que está intentando invocar:

ResponseEntity<String> restExchange = restTemplate.exchange(http://logical-service-id/name/{firstName}/{lastName}

La clase RestTemplate se pondrá en contacto con el servicio de Eureka y buscará la ubicación física de una o más de las instancias del servicio "nombre". Como consumidor del servicio, su código nunca tiene que saber dónde se encuentra ese servicio.

Además, la clase RestTemplate está usando la biblioteca Ribbon de Netflix. Ribbon recuperará una lista de todos los puntos finales físicos asociados con un servicio. Cada vez que el cliente llama al servicio, realiza un "round-robins" de la llamada a las diferentes instancias del servicio en el cliente sin tener que pasar por un equilibrador de carga centralizado. Al eliminar un equilibrador de carga centralizado y trasladarlo al cliente, elimina otro punto de falla (el equilibrador de carga baja) en la infraestructura de su aplicación.



viernes, 19 de noviembre de 2021

Apache Pulsar



Apache Pulsar es una plataforma de transmisión y mensajería distribuida cloud-native creada originalmente por Yahoo! y ahora un proyecto de top-level de Apache Software Foundation

Las características clave de Pulsar son :

  • Soporte nativo para múltiples clústeres en una instancia de Pulsar, con replicación geográfica perfecta de mensajes entre clústeres.
  • Latencia de publicación y de extremo a extremo muy baja.
  • Escalabilidad perfecta a más de un millón de temas o topicos.
  • Una API de cliente simple y que se puede implementar en Java, Go, Python y C ++.
  • Múltiples tipos de suscripción (exclusiva, compartida y conmutación por error) para temas.
  • Entrega de mensajes garantizada con almacenamiento de mensajes persistente proporcionado por Apache BookKeeper.
  • Pulsar Functions, un framework liviano sin servidor, ofrece la capacidad de procesamiento de flujar de datos.
  • Pulsar IO, es un framework de conexión que se basa en Pulsar Functions, hace que sea más fácil mover datos dentro y fuera de Apache Pulsar.
  • El almacenamiento por niveles.

Si queremos levantar Pulsar con Docker es tan fácil como hacer : 

$ docker run -it \
  -p 6650:6650 \
  -p 8080:8080 \
  --mount source=pulsardata,target=/pulsar/data \
  --mount source=pulsarconf,target=/pulsar/conf \
  apachepulsar/pulsar:2.8.1 \
  bin/pulsar standalone

Veamos un ejemplo en Python, primero debemos instalar el cliente de pulsar : 

$ pip install pulsar-client

Y luego podemos hacer un cliente productor : 

import pulsar

client = pulsar.Client('pulsar://localhost:6650')
producer = client.create_producer('my-topic')

for i in range(10):
    producer.send(('hello-pulsar-%d' % i).encode('utf-8'))

client.close()

Y luego un consumidor : 

import pulsar

client = pulsar.Client('pulsar://localhost:6650')
consumer = client.subscribe('my-topic',
                            subscription_name='my-sub')

while True:
    msg = consumer.receive()
    print("Received message: '%s'" % msg.data())
    consumer.acknowledge(msg)

client.close()

Y listo!!

Dejo link: https://pulsar.apache.org/