Tag Archives: programación

¿Cómo construir un microservicio?

Para escribir esta publicación decidí revisar mis anotaciones, experiencias, leer algunas referencias e incluso volver a leer algún libro que me permitiera confirmar –o reforzar– mis puntos de vista al respecto. La finalidad es compartir algo distinto y que además sea fácil de entender. Espero cumplir con ese objetivo 🙂

¿Qué no es un microservicio?

  1. Un servicio pequeño: Esta confusión se genera al creer que el tamaño tiene que ver con el número de líneas de código del programa a exponer como microservicio. No hay que confundir tamaño con nivel de [granularidad]
  1. Un API: Las [Application Program Interfaces] son una puerta para consumir o comunicarnos con un microservicio expuesto. Existe una dependencia muy marcada entre ambos elementos, pero un [API] no necesariamente involucrará el uso de microservicios.
  1. La evolución de SOA: A veces se habla de migrar arquitecturas a “algo nuevo”, cuando en realidad lo que se debe buscar es la convivencia de las mismas. Si no les ha ocurrido, encontrarán situaciones en las que será más barato (y efectivo) implementar un servicio en vez de un microservicio.

¿Cómo describiría un microservicio?

  1. Una necesidad específica de negocio: Una componentización adecuada sugiere que las funcionalidades se agrupen por [afinidad de objetivos en el negocio]. Posterior a esto, debemos dar un paso adicional y subdividir dicho componente en funcionalidades particulares que podrían generar valor al negocio. Un ejemplo aquí sería, aislar la funcionalidad de obtención de ranking financiero de un usuario, del resto de funcionalidades –o cálculos o servicios– financieros.
  1. Independiente: No se debería involucrar a otro microservicio para cumplir el objetivo del microservicio diseñado inicialmente. De acuerdo al ejemplo anterior, la obtención del ranking financiero tendría que ser resuelta de manera efectiva sin apoyo de otros elementos.
  1. Autónomo: Un microservicio debe utilizar sus propios recursos, esto implica fuentes de información e incluso el espacio donde será instalado fisicamente. Esto algunas veces no se cumple a nivel de datos y ya hace un tiempo se habla de [servicios stateless]

En términos sencillos, un microservicio es un programa que responde a una sola necesidad de negocio y que además puede instalarse y ejecutarse sin depender de la existencia de otros microservicios.

¿Qué tengo que hacer si quiero construir un microservicio?

Lo que normalmente hacemos es [buscar en la web]. Allí encontraremos muchas plantillas que, en algunos casos, brindan erroneamente el concepto de microservicio. Esto principalmente porque reflejan servicios que exponen (y soportan) más de una funcionalidad.

Creo que un diseño adecuado se puede conseguir si respetamos los principios propuestos por [Sam Newman], autor de [Building Microservices], el cual por cierto es un excelente libro. Aquí un gráfico que la propuesta y claro, un enlace a [un video] donde se explican cada uno de los principios.

¿Cómo construyo un microservicio?

Hay que tener en cuenta que lo ideal es respetar principios de diseño (en mi caso me pareció que Sam Newman lo explicaba de manera más sencilla). Ahora, si estan aprendiendo o experimentando, podrían seguir las consideraciones que definí mientras iba aprendiendo (las cuales respetan de alguna forma la propuesta del buen Sam)

  1. Requisitos de negocio: Creo que independiente a la estrategia de arquitectura, lo primero que debemos respetar es la funcionalidad a cubrir. Si esta no está cubriendo las expectativas del negocio (lo cual en algunas situaciones se relaciona con el core del negocio), no tiene sentido continuar con el diseño.
  1. Exposición: Otro elemento importante es responder ¿cómo vamos a exponer el microservicio? Aquí entrará a tallar la API que complementará el diseño que estamos realizando.
  1. Requisitos técnicos: Si se tienen cubiertos las dos primeros consideraciones, se puede continuar con el diseño de otras necesidades, como por ejemplo ¿cómo vamos a probar el microservicio? ¿cómo vamos a desplegarlo? ¿cómo vamos a manejar los errores? Aquí es donde entra la sección de herramientas complementarias.

Un diseño que estoy construyendo es el siguiente:

Como mencioné en una [publicación anterior], hace poco empecé un proyecto open source en el cual comparto plantillas y ejemplos de microservicios. Todo el [código fuente] que verán en dicho repositorio responde a las consideraciones de diseño que comento en esta publicación.

Hay que recordar que este diseño responde a un microservicio como unidad de trabajo. Esta acotación es importante pues queda pendiente conversar sobre la interacción con otros elementos del ecosistema. Aquí es donde se entiende que se necesitará estudiar conceptos de [orquestación y coreografía]

¿Cuáles son los próximos pasos?

No debemos olvidar que los microservicios son una técnica más dentro de las posibilidades para atender las necesidades del negocio. Esto significa de que no necesariamente serán la primera –ni la única– respuesta a los problemas a cubrir.

Habiendo dicho esto, sugiero que descarguen el [código de ejemplo] (en este momento está disponible en JavaScript, TypeScript y c#), revisar el contenido, contribuir en GitHub o bueno, darme feedback al respecto.

Quedo atento, un abrazo.

Fuente cabecera: [what are microservices?]

Código Muerto 💀

Una de las anécdotas más comunes de un proyecto de software es que siempre hay una clase o una función que será recordada por el número de líneas que esta tuvo. Estoy seguro de que al menos una vez hemos escuchado:

“No toques esa clase, tiene como 1000 líneas de código”

Developer anónimo

Este es un dato particular de acuerdo a los proyectos en los que estuve y conversaciones entre amigos. Lo que es menos común, es saber cuántas líneas de código tiene el proyecto en el que estamos trabajando.

Si en este momento nos hacemos esa pregunta o se la hacemos a otro miembro del equipo, es posible de que no consigan una respuesta concreta. Si bien es cierto no considero necesario ser 100% precisos, he notado que pocas personas se preocupan de esa métrica, a menos claro, de que haya algún costo asociado.

Si no les ha pasado, les comento que casos como este se dan desde hace mucho en proyectos donde se audita código. Sin ir muy lejos, Amazon liberó [CodeGuru], un servicio (aún en preview) que analiza el código fuente. Como es de esperar, el costo está asociado al número de líneas y no es el único producto o servicio que hace este [tipo de trabajos]

Fuente: [Amazon CodeGuru]

¿Qué es lo que regularmente encontraremos?

He participado en proyectos donde el análisis o auditoría de calidad de software era uno de los objetivos más importantes. Muchas veces el costo de servicios adquiridos –u ofrecidos– estaba relacionado al número de líneas de código (o LoC por [Lines of Code]).

En cada trabajo era común confirmar lo encontrado en proyectos anteriores:

  1. Pocas personas conocían el número de LoC o la importancia de este indicador
  1. Una práctica conocida –y en algunos casos, aceptada– era “agregar código de ejemplo, ir cambiando y probando pero guardar la versión original por si algo se malograba”
  1. Muchas veces se mantenían las carpetas de plantillas y ejemplos de las librerías y componentes de terceros que en algunos casos ya no se utilizaban

Ya en un caso concreto, estuve en un proyecto donde el desarrollo tenía más de un millón de LoC y estaba seguro de que eso no podía ser posible pues las funcionalidades del sistema no reflejaban dicha realidad.

Sabía que estaba frente a un caso de Código Muerto, pero tenía que demostrarlo.

¿Qué es Código Muerto?

Sin entrar en detalles (pues es posible que encuentren discrepancias y hasta [una canción]), el código muerto o “Dead Code” es aquel que no aporta valor al negocio.

El código muerto se puede clasificar de la siguiente manera:

  • Código que no se usa: Muy usual en los proyectos de software, algunas veces no se recuerda su objetivo inicial y por lo general ocurre pues las necesidades van cambiando y el código no se depura adecuadamente luego de cada cambio (mucho cuidado con las frases “es que no hay tiempo” o “lo vemos después”)
  • Código que se ejecuta pero que no se usa: Aquí entran los casos como los de variables asignadas o llamadas a funciones cuyo resultado no es utilizado. Esto es nocivo pues además ser código inútil, consume recursos del sistema.

¿Cómo identificar Código Muerto?

Con el paso del tiempo preparé una secuencia de análisis que me sirvió para encontrar casos de código muerto bajo la premisa de que si algo se define en el programa, este debe ser utilizado de manera efectiva. La lista puede parecer obvia, pero ya está demostrado que en tecnología no debemos confiar en las obviedades 🙂

  • Variables
  • Funciones
  • Clases
  • Comentarios (sean redundantes o código que fue comentado para ser utilizado “más adelante”)
  • Elementos de archivos de configuración (por ejemplo, secciones comentads o que ya no se utilizan)
  • Archivos de configuración
  • Librerías (componentes de terceros)
  • Elementos idénticos (funciones, clases archivos, librerías o carpetas distribuidos en ubicaciones distintas)
  • Elementos parecidos (librerías con versiones diferentes, funciones o clases que inicialmente eran una copia de la otra)
  • Carpetas y archivos varios que poco a poco quedan relegados hasta el olvido

Un hecho común en todos los casos, es que el código muerto existe debido al temor a perder código o a malograr el sistema construido. Esto tiene relación directa con el desconocimiento de que los gestores de versiones permiten volver al pasado si es que se necesita ver algo que ha sido borrado.

Otra consecuencia es que a más código muerto, más complejo será el entendimiento de nuestro sistema, la mantenibilidad será afectada y a su vez generará dependencias con un programador en particular (a veces pueden ser más personas). Recuerden, el código es de todos los miembros del equipo y mientras menos dependencias, mejor.

¿Qué herramientas debemos usar?

Puede que parezca una broma, pero un elemento muy importante es la inspección visual. A pesar de ello, esta debe pasar a segundo plano pues debemos evitar confiar totalmente de los presentimientos o “literalmente” de puntos de vista.

De acuerdo a esta premisa, lo primero que debemos hacer es trabajar con [herramientas de análisis estático] que nos brinden un enfoque acertado de lo que está ocurriendo.

A pesar de ello, hasta el momento no he encontrado una herramienta que brinde un indicador de código muerto bajo un enfoque holístico. Es así que utilizo principalmente [SonarQube] como base del trabajo a realizar.

Regresando al caso del millón de LoC, encontré pistas que me ayudaron a confirmar la existencia del temible código muerto.

Si queremos empezar con estas prácticas, algo que nos podría ayudar está incluido en las herramientas del navegador web. Una de las que ha llamado mi atención es la utilizada para analizar la cobertura de los archivos JavaScript y CSS. Esta viene en [Chrome] y no es complicado de usar/entender.

¿Qué conseguí luego de presentar lo encontrado?

El objetivo de mi trabajo en dicho proyecto, fue preparar un informe sobre lo que se estaba construyendo y sobre eso un plan de trabajo para implementar una nueva arquitectura. No me parecía adecuado llegar con una presentación llena de indicadores ni menos señalar responsables (aunque en algunos casos ese ha sido mi trabajo), así que gracias al apoyo y explicaciones que el equipo dio cuando estaba analizando el código, tenía el conocimiento necesario para “limpiarlo”, al menos en casos que parecían obvios o donde veía que complejidad baja o media.

Como este tipo de trabajos me gustan, no paré hasta eliminar 95% del código del sistema. No esperaba llegar a ese número pero más de un millón líneas era código muerto que se podía limpiar fácilmente.

Nada mejor que llegar con un informe que tenga un entregable como ese 🙂

La buena noticias es que el equipo quedó sorprendido. Cuándo me preguntaron cómo lo hice, les comenté que empecé por las obviedades (y ya saben lo que pienso de ellas :)) creo que eso los animó a seguir limpiando (luego de una segunda limpieza el código no superaba las 30 mil LoC)

¿Qué es lo que aprendí?

  • Es posible que este tipo de trabajos sea incomprendido al principio, pero se consigue mucho enseñando con el ejemplo. En dicho proyecto tenía que preparar una arquitectura que aproveche lo que ya estaba construido, pero ante las sospechas de código muerto, decidí detenerme un momento y evaluar cómo eliminarlo, primero por mi cuenta y luego con el equipo.
  • Lo que he encontrado en muchos casos, es que hay pocas intenciones de refactorización que a veces no se dan por el uso desmedido de frameworks y herramientas. Lo que creo que se debe hacer es sentar una base medible de lo que está sucediendo sin olvidar que lo más se hace en un proyecto de software es la construcción del mismo. Si es así ¿por qué no saber cómo va creciendo nuestro código?
  • La automatización de pruebas es muy importante pero esta se debe postergar si hay casos obvios de código muerto, he comprobado que a veces resulta más rápido borrar (sin miedo) que ponermos a programar un caso de prueba.
  • Siempre debemos utilizar un gestor de versiones (personalmente prefiero Git sobre GitHub) y tenerlo enlazado a un motor de automatización (como [Jenkins] o [Azure DevOps], ambos me parecen buenos y Azure DevOps es más sencillo de configurar) que ayude a tener visibilidad de la integración continua.
  • El equipo de desarrollo pasa a otro nivel de conocimiento, pues además de entender la importancia de prácticas de limpieza de código muerto se abre una nueva puerta hacia la calidad del producto.
  • Si la confianza y comunicación son las adecuadas, este tipo de situaciones se convierten en anécdotas del equipo.

¿Cuál fue mi reflexión final?

Antes de refactorizar o hacer lo que sea en el sistema, eliminen el Código Muerto, no teman.

Un abrazo,

Fuente imagen cabecera: [Finding Dead Code]

Mi aventura en 42 Silicon Valley

Hace unos meses me animé a postular a [42 Silicon Valley] y creo que tuve suerte para ser aceptado (pues no tuve que dar examen de ingreso) o para conseguir un dormitorio gratis (aquí si tuve que esperar confirmación luego de casi dos meses)

El punto de inicio era participar en [The Piscine], el bootcamp para demostrar luego de un mes que tienes las habilidades necesarias para ingresar [al programa] que además de ser gratuito, tiene una duración de cinco años.

¿En qué consistió el bootcamp?

  • Estudiar todos los días de la semana, la mayor cantidad de horas posibles. Podías usar el material disponible o buscar en internet el material de estudio requerido para cada día.
  • Resolver las asignaciones diarias respetando el orden de cada pregunta (es decir, no puedes continuar si no terminas con una pregunta)
  • Respetar reglas de programación sobre el uso de librerías (muchas no se podían usar, te pedían construir tus propias librerías), número de líneas (25 líneas por programa), número de variables (4 por programa), sentencias (el “for” estaba prohibido) y así…
  • Terminar de programar antes de la hora límite (11.42 de la noche)
  • Tener en cuenta que cada línea de código escrita debería ser fácil de entender
  • Recibir diariamente 2 evaluaciones aleatorias que se hacían de manera presencial, lo cual te obligaba entre otras cosas a defender tu código en inglés (sí o sí tenías que hablar)
  • Realizar diariamente 2 evaluaciones (como dije, sí o sí tenías que hablar)
  • Participar en los trabajos grupales, que si bien es cierto no eran aleatorios, requerían mucha coordinación.
  • Participar en los exámenes semanales, en los que cada viernes te asignaban una computadora que no tenía acceso a internet ni a herramientas como Visual Studio Code, así que si no sabías como usar vim o comandos en Linux, estabas muerto 🙂
  • Tener en cuenta que los tres primeros exámenes durarían 4 horas y el último sería de 8 horas
  • Programar en C
  • No hacer trampa, pues si bien es cierto los problemas se pueden conseguir fácilmente, si no puedes explicarlos o se descubre que ese no es tu código, cosas malas pueden ocurrir (además de que queda en tu registro y te podrían invitarte a salir del programa)

Pues bien, fueron cuatro semanas en las que además de compartir dormitorio con dos amigos de China y uno de Kazajistán, conocí amigos de Rusia, Francia, Argentina, Brasil, China, Korea y USA. Además, en todo ese tiempo aprendí de todo un poco, inclusive como ahorrar tiempo y dinero pues a pesar de vivir gratis en el campus, necesitabas dinero para comer y allá todo era caro :O

Sí, hay una bandera de Perú 😀 y como datos anecdóticos, era el único peruano y la foto muestra a los que quedamos hasta el final pues más del 50% se retiró

¿Qué aprendí?

Además de respirar programación, encontré cosas muy interesantes:

  1. Resiliencia: Si hay una palabra para definir a las personas que conocí en el bootcamp, esa es la primera que podría decir. Muchos amigos tenían unas ganas de superación increibles, algunos trabajaban por las tardes o noches. Otros no lograron conseguir dormitorio, así que viajaban una o dos horas (algunos manejando) para llegar diariamente al campus. Todo por estudiar.
  1. Colaboración: Si bien es cierto encontré casos de segregación de acuerdo al país de origen o similitud de conocimientos, cuando había problemas nadie dudaba en ayudar si te acercabas a preguntar. Algunos lo hacían con muchas más ganas que otros, pero todos terminaban respondiendo al pedido de ayuda.
  1. Empatía: Algunas veces mi evaluador no sabía como decirme que me había equivocado pues le daba pena que eso afectara a mi promedio. Esto lo supe pues me puse a conversar con ellos pidiendo más detalle ya que al igual que todos, quería aprender.
  1. Humildad: Algunas personas sabían lo suficiente como para terminar el trabajo en la mitad del tiempo o menos, pero a pesar de ello ni alardeaban, ni lo demostraban cuando te tocaba evaluar su código o cuando ellos evaluaban el tuyo. Me pasó más de una vez que hubo personas que me para preguntaban como había resuelto un problema y a veces descubrían un error en su lógica o algo por mejorar en ella. Nunca se molestaban, siempre agradecían.
  1. Optimismo: Una frase con la que siempre me encontraba cuando cometía un error era “no te preocupes, es solo un test, mañana lo haremos mejor” Lo genial es que a veces ocurría con personas que acababa de conocer.
  1. Competencia sana: Si bien es cierto todos sabíamos que cada examen semanal era determinante para ser aceptado en el programa oficial y que no todos seríamos aceptados, todos nos animábamos antes de empezar cada evaluación. Al finalizar nos preguntábamos comos fue y hubo casos en los que comparábamos soluciones. En mi caso prefería ir a dormir –pues terminaba muy cansado– pero al día siguiente la conversación seguía 🙂
  1. Comunicación: Si me preguntan cuál es diferenciador con respecto a lo que he visto en el medio local (es decir, Perú), este es un elemento muy importante. Teniendo en cuenta de que los programadores no hablamos mucho, eso también ocurre fuera del país, pero la diferencia es que estando allá, me encontré con personas que además de escribir buen código, explicaban muy bien lo que hacían o en todo caso, sabían vender muy bien sus ideas. Cosa que humildemente tenemos que seguir mejorando.

¿Qué pasó después?

Como mencioné anteriormente, el examen final fue un viernes y tenía una duración de 8 horas, en mi caso terminé de programar en la séptima hora. No recuerdo el número de problemas que resolví pero sí que había programado sin descanso alguno, así que cuando sentí que necesitaba salir de ahí, fue lo que hice. La verdad es que, cuando tu cabeza no da para más, lo mejor es dejar de programar.

A las dos semanas de dar el examen estaba de viaje y con poco acceso a internet, recuerdo que cuando pude conectarme, recibí con mucha sorpresa el correo de aceptación al programa, podía irme a estudiar por tres años y si no tenía donde vivir, podía postular nuevamente para conseguir un dormitorio.

¿Qué es lo que haré?

En esta época de mi vida me gustaría volver a enseñar, mientras tanto estoy retomando mi práctica de escribir y reforzar mis conocimientos en [arquitectura] (es por eso que mi blog ha renacido), además estoy presentando una tesis para conseguir mi maestría en administración y en paralelo a esto, me puse a estudiar mi segunda maestría mientras busco un nuevo empleo.

Creo que estoy algo ocupado por el momento (o quizá algo loco), pero bueno, nunca se sabe 🙂

Un abrazo,

Microservicios y código de ejemplo

Estaba preparando una propuesta de charla de [microservicios] y mientras buscaba información para el código de ejemplo, me di con la sorpresa de que lo que encontraba en la web era de complejidad media/alta (o no se entendía) o peor aún, a pesar de que muchos (podría afirmar que más del 50%) indicaban que se trataban de microservicios, pues no lo eran.

Fuente: [microservices]

¿Cómo confirmas si estás viendo un microservicio?

Siendo concretos, un microservicio debe:

  1. Responder a un solo trabajo, es decir, una sola funcionalidad
  2. Ser autónomo incluso en su instalación

Okey, hay [otras consideraciones] a tomar en cuenta, pero a mi entender si no pasamos los dos primeros filtros, no tiene sentido seguir avanzando.

¿Qué hice al respecto?

Sin ir en muchos detalles, se me ocurrió detener lo que estaba haciendo para ponerme a escribir códigos de ejemplo de microservicios.

Ojo, no me considero un experto pero creo que mi idea es sencilla, crear un proyecto para compartir lo que voy aprendiendo.

¿En qué consiste el proyecto?

El requitisto principal es que el código sea fácil de entender y que además permita aprender a construir microservicios. Es así que lo que tengo en mente hasta ahora es:

  • Una plantilla de código (incluye soporte de HTTP GET)
  • Código de ejemplos para:
    1. Soporte de HTTP GET
    2. Soporte de HTTP GET y parámetros
    3. Soporte de HTTP POST y parámetros
    4. Soporte de HTTP GET y Docker para desplegar el microservicio

Inicialmente pensé en escribir todo en NodeJS pero luego dije ¿Por qué no más lenguajes?

¿Qué he avanzado hasta ahora?

Pues como dije líneas arriba, me animé a escribir algo de código 🙂 El proyecto se llama microservices-templates y ya está en GitHub, aquí la url: https://github.com/jersson/microservices-templates

Si bien es cierto tengo en mente programar en al menos cinco lenguajes, decidí que no podía esperar tanto para liberar algo, así que aquí va la versión en NodeJS: https://github.com/jersson/microservices-templates/tree/master/00-node

Como podrán notar en el código, este incluye descripciones sobre como probar cada microservicio. Además, cada archivo tiene pocas líneas de código y cada una de ellas la he escrito de manera que busqué facilitar su lectura.

Este proyecto me gusta bastante y estoy seguro de que si consigo ayuda podré avanzar más rápido, así que si les interesa aprender o ya saben como escribir o mejorar lo que estoy construyendo, anímense, estaré aquí o en GitHub 🙂

Sin más que decirles me despido esperando que tengan un excelente nuevo año.

Un abrazo.

Fuente imagen cabecera:[what are microservices?]

¿Cómo practicas programación?

Les cuento que casi todo este año tuve el tiempo necesario para programar al menos dos horas al día. En términos simples, programar es uno de los hobbies que he ido desarrollando a lo largo de mi vida 🙂

En fin, como algunos saben, hace unos meses estuve en el bootcamp de [42 Silicon Valley] y si bien es cierto no he tenido la oportunidad de escribir al respecto, puedo adelantar que mi afición por la programación se reforzó de tal manera que ahora veo de forma diferente cualquier lenguaje de programación, estudio mucho más al respecto y si fuera necesario, reviso cómo hacer las cosas con la menor cantidad de librerías y/o frameworks (pues ahora casi todo se resuelve así)

Bueno, para hacer la historia corta, mi interés –y cariño– por el [lenguaje C] ha vuelto, así que he propuesto cuatro problemas que parecen simples, pero si intentas resolverlos con la menor cantidad de código, librerías y además buscas hacerlo entendible, pues ahí llega la complejidad. De estos problemas ya he resuelto dos y los he dejado en un repositorio esperando que alguien quiera unirse para al menos proponer nuevos problemas. Por mi parte ya tengo algunos en mente, pero tengo que ponerlos en limpio.

En fin, si les interesa este es el repositorio que siempre voy actualizando: https://github.com/jersson/c-problems/tree/dev

Ahora, si quieren ver cómo funciona el código y no quieren clonarlo, aquí un espacio para jugar usando el navegador https://repl.it/@jersson1/c-problems. De ser así, tengan especial atención en el archivo .replit

Como ya deben haber notado, la documentación la estoy escribiendo en inglés pues además me pareció buena oportunidad para practicar el idioma 🙂

Espero que puedan unirse y que además pasen unas excelentes fiestas navideñas.

Un abrazo,

Fuente imagen cabecera: http://offeman.com/safe-casting-pointers-in-object-pascal/