Re: [Python-es] Ejemplo de microservicios (Sistema distribuido)

2017-04-28 Por tema Luciano Andino
El 27 de abril de 2017, 9:20, Yamila Moreno Suárez 
escribió:

> Buenas!
>
> Yo desconozco si existe un framework para lo que necesitas, aunque me
> sorprendería por la naturaleza de la arquitectura que planteas. En todo
> caso, he hecho aplicaciones similares y nuestra solución ha sido:
>
> 1 aplicación de API. Esta API la puedes hacer con Flask (tiene bibliotecas
> para levantar APIs), con Django (usando Django Rest Framework) o "a pelo",
> es decir, usas un micro-framework que resuelve el enrutamiento y poco más,
> y el resto (validaciones, conexión, sesiones, clases de bbdd, mapeos,
> servicios, etc) lo haces a mano siguiendo una arquitectura bastante
> estricta y controlada. Hay opciones en muchísimos lenguajes, si el que más
> conoces es python, vas a poder elegir cómodamente.
>
> 1 aplicación de backend. Al igual que el API tienes muchas opciones
> basadas en python, o en otros lenguajes.
>
> Con esto, puedes:
> - crear una imagen del back y levantar tantos contenedores como necesites
> - crear una imagen del api y levantar tantos contenedores como necesites
> - No comentas nada de bbdd, entiendo que está resuelta por otro sistema y
> que tú vas a conectarte a ella como sea.
>

Buenas tardes Yamila (a los que leen y quisieran responder también), antes
que nada, gracias por tu tiempo en contestar. Si no fui claro u omití algo
es porque todavía no tengo en claro todo.

En mi caso cuento con la experiencia de haber hecho un API REST como
frontend utilizando Flask y en la universidad me pidieron que implemente
oauth2 sin la librería oauth, es decir yo mismo crear el token y refresh
token y con esto, comunicarme con otro servicio (sería un backend),
utilizando formato REST y un token válido para recuperar datos de ese
backend (o actualizar).

Con esto me refiero a que ese backend es una "aplicacion.py" código
spaguetti o "chorizo" de más de mil lineas que se me hizo complicado de
seguir y de defender ante el profesor (con el agregado que estoy cursando
en una universidad de Moscú y el idioma es complicado).

Para dar una idea del proyecto, hice una traducción [1] del ruso al español
y por lo que entiendo, debo poder instanciar ese backend. Si en mi código
spaguetti anterior tenía en la base "sqlite.db" las tablas "Usuario",
"Habitación" y "Reserva", teniendo esta última, claves que hacían
referencia a las dos primeras. Imagino que en una topología de servicios,
ahora tendría (cada una corriendo en un puerto diferente):

1) "ServicioUsuarios.py" que brinda información de usuarios (y actualiza).
2) "ServicioHabitaciones.py" que brinda información de habitaciones.
3) "ServicioReservas.py" que informa sobre reservas (siempre con token
válido: listado completo, pasando un ID de usuario dice que reserva tiene,
o poder reservar una habitación, etc.

Imagino que cada servicio tiene sus tablas pero por ejemplo el
"ServicioReservas" no tiene información de usuarios, sólo una tabla de
reservas que lista o actualiza según se requiera. Es decir ya no tengo la
estructura de BD completa como tenía en la versión monolítica.

No tengo en claro si para estos tres servicios necesito en el backend otro
servicio que los administre o el frontend "va derecho".

También se me ocurre que la tabla usuarios estará primero en el Frontend y
que luego, cuando el usuario se interese por hacer uso de servicios de
determinado "Hotel" (backend específico), actualizaría la tabla de Usuarios
de ese servicio a través de su "ServicioUsuarios.py".

No sé si hice un embrollo, esto es bastante nuevo para mí y no sé bien cómo
dividir las tablas y qué replicar.

[1] https://drive.google.com/file/d/0B_2ALCPIGxPxblRqUFRFMERQcDQ/view



>
> Si levantas varios apis y backs (y quieres que respondan en la misma URL)
> tienes que añadir una capa por delante que se encargue de distribuir la
> carga y de mantener el estado de tu servicio. Esta capa ahora mismo se está
> resolviendo con orquestadores.
>

Creo que por el momento el api/frontend es único, pero hay más de un
backend.

>
> Si eres nuevo en docker, te paso un tuto que hice, con el que aproveché
> para aprender; es muy sencillo pero te enseña las bases:
> http://moduslaborandi.net/2016/02/docker-101-hello-world/ (y los 3
> siguientes).
>
> Lo que planteas en tu email es un sistema complejo y sofisticado; es
> improbable que exista una única herramienta que te lo resuelva, así que mi
> recomendación en todo caso es que vayas resolviendo trozos pequeños,
> asegurándote de usar buenas prácticas, de forma que después vaya a ser más
> sencillo unirlos. Por ejemplo, es muy importante no acoplar componentes de
> tu aplicación.
>

En otro documento que me pasaron el la universidad, sugería el tema de la
geolocalización a través de un CDN, pero creo que eso sería un agregado
posterior, lo voy a obviar por el momento. Esto de los microservicios se
presenta muy interesante por las ventajas y quiero empezar de a poco.

Cualquier comentario será muy bien recibido, yo leo varias veces las
respuestas.

Luciano

Re: [Python-es] Ejemplo de microservicios (Sistema distribuido)

2017-04-28 Por tema Luciano Andino
El 27 de abril de 2017, 13:28, lasizoillo  escribió:

> Buenas,
>
> Siento ser así, pero creo que te voy a plantear más dudas de las que
> te voy a resolver. Pero de todas formas te las vas a acabar
> encontrando, así que al lío.
>
> El día 26 de abril de 2017, 21:24, Luciano Andino
>  escribió:
> > Buenas, este es mi primer email a la lista. Les consulto: Tengo que
> > desarrollar una aplicación del tipo "Hotel" (clientes, habitaciones,
> > reservas, etc) pero utilizando microservicios. A detallar:
> >
> > * Un frontend del tipo API REST oauth2 (logueandose con la cuanta de
> gmail
> > por ejemplo), que interactue con el backend de hotel (utilizando
> > microservicios).
>
> Aparte de los que te comenta yamila, tienes otros frameworks como Falcon o
> Sanic
> https://falconframework.org/
> https://github.com/channelcat/sanic
>
> Estos que te comento te pueden dar un rendimiento mayor a costa de
> menor estabilidad y que muchas cosas que te las vas a tener que hacer
> tu. Como tu problema es ya bastante complejo, tira por los que te ha
> recomendado yamila y no mires un solo benchmark hasta que tengas el
> problema resuelto ;-) Django y Flask son dos buenas opciones.
>
> >
> > * El backend estará encapsulado en docker, porque a efectos de
> > geolocalización del usuario web, el frontend se comunicará con el backend
> > más cercano a través del UUID. Con esto quiero decir que habría más de un
> > backend. (Sistema distribuido)
>
> A este párrafo no le he encontrado el sentido. Docker permite
> contenedores de forma sencilla, lo cual es útil para montar un entorno
> de desarrollo o un sistema distribuido. Hay otras formas de hacer
> sistemas distribuidos. Pero bueno, aceptemos que tenemos docker en el
> sistema y que necesitas saber que instancia se va a encargar de hacer
> el trabajo.
>
> Docker tiene un demonio que se encarga de manejar los contendores y
> una serie de comandos que se comunican mediante api rests con el para
> que le digas como hacerlo. Docker compose está hecho en python, puedes
> ver su código. Y tienes librerias para comunicar con ese api:
> https://github.com/docker/docker-py
>
> Con eso puedes resolver el levantar y dar de baja instancias, descagar
> imágenes del registry, ...
>
> También hay opciones como docker registrator (si no quieres hacerlo
> tu) que atiende a los eventos de docker para ver que instancias están
> levantadas. Luego guarda la información en un etc o un consul y así
> tienes un punto con la información de qué backends hay levantados para
> tirarles las peticiones geolocalizadas esas que necesitas:
> https://github.com/gliderlabs/registrator
> https://github.com/jplana/python-etcd
> https://github.com/cablehead/python-consul
>
> Pero vamos, esto es solo una opción para hacer las llamadas. Hay otras
> aproximaciones, más a lo service bus, que en vez de centralizar quién
> puede atender peticiones, lo que centraliza son las peticiones en si a
> través de una cola de mensajes. Puedes echarle un ojo a nameko, que
> aunque creo que no cubre tus necesidades de routing geolocalizado
> puede darte una idea:
> https://github.com/nameko/nameko
> https://www.rabbitmq.com/tutorials/tutorial-four-python.html
> https://www.rabbitmq.com/tutorials/tutorial-five-python.html
>
> Otra aproximación es que cuando se levantan los backends se den de
> alta en un dns y mediante views en los servidores DNS se resuelva el
> tema de la geolocalización. Aunque hay gente que no le gusta que eso
> se haga:
> http://queue.acm.org/detail.cfm?id=1647302
>
> Por lo que cuentas una solución registrator, consul y código para ver
> a dónde atacar me suena mejor. Pero como siempre todo depende de los
> detalles.
>
> >
> > * Debo ser capaz desde un perfil de administrador, podér agregar
> instancias
> > backend, dar de baja, etc.
> >
>
> Eso como te decía yamila suena a scheduler. Puedes tirar del api de
> docker y hacerte el tuyo o tratar de usar uno de los 200 que hay (he
> dicho 200 como estimación, podrían ser más o menos). Otra opción es
> tirar por un sistema de PaaS (plataform as a service) que aparte de
> donde y como levantar las instancias suelen ayudar en su construcción,
> marchas atrás, ...
>
> Levantar instancias de código es trivial, pero ¿qué piensas hacer con los
> datos?
>
> Datos y sistemas distribuidos es un auténtico marrón:
> https://es.wikipedia.org/wiki/Teorema_CAP
>
> Si cada instancia tiene sus propios datos no distribuidos te quitas
> una gran complejidad. Bin. Se te va a complicar el hacer los
> backups. Oo. Pero cada backend va a tener los datos más cerca lo
> que implica menos latencias. Bin, Pero las tareas de
> administración (cambio de esquema, creación de índices, ...) se
> multiplican por cada particionado de datos. Oo.
>
> Elijas la solución final que elijas, piensa en que dejas un marrón a
> un pobre administrador de sistemas que tiene familia. Piensa en ellos
> y echale un ojo a 12Factor para que no tenga que acabar siguiendo los
> 12 pasos de aa.
> ht