{"id":31124,"date":"2019-10-31T21:39:36","date_gmt":"2019-10-31T18:39:36","guid":{"rendered":"https:\/\/prohoster.info\/blog\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie\/"},"modified":"2019-10-31T21:39:36","modified_gmt":"2019-10-31T18:39:36","slug":"stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","status":"publish","type":"post","link":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","title":{"rendered":"Bloques de construcci\u00f3n de aplicaciones distribuidas. Segunda aproximaci\u00f3n","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Anuncio<\/strong><\/p>\n<p><\/p>\n<p><em>Colegas, a mediados del verano planeo lanzar otro ciclo de art\u00edculos sobre el dise\u00f1o de sistemas de servicio masivo: \u201cExperimento VTrade\u201d \u2014 un intento de escribir un marco para sistemas comerciales. En el ciclo se abordar\u00e1 la teor\u00eda y la pr\u00e1ctica de la construcci\u00f3n de bolsas, subastas y tiendas. Al final del art\u00edculo, propongo votar por los temas que les parezcan m\u00e1s interesantes.<br \/>\n<\/em><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Bloques de construcci\u00f3n de aplicaciones distribuidas. Segunda aproximaci\u00f3n\" src=\"\/wp-content\/uploads\/2019\/04\/358996733e805327b587176f4f992aea.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Este es el art\u00edculo final del ciclo sobre aplicaciones reactivas distribuidas en Erlang\/Elixir. En <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446028\/\">primer art\u00edculo<\/a><\/noindex> se pueden encontrar los fundamentos te\u00f3ricos de la arquitectura reactiva. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446108\/\">El segundo art\u00edculo<\/a><\/noindex> ilustra los principales patrones y mecanismos para construir tales sistemas.<\/p>\n<p><\/p>\n<p>Hoy abordaremos cuestiones sobre el desarrollo de la base de c\u00f3digo y los proyectos en general. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"organizaciya-servisov\">Organizaci\u00f3n de servicios<\/h2>\n<p><\/p>\n<p>En la vida real, al desarrollar un servicio, a menudo es necesario combinar varios patrones de interacci\u00f3n en un solo controlador. Por ejemplo, el servicio de usuarios, que se encarga de gestionar los perfiles de los usuarios del proyecto, debe responder a solicitudes req-resp y comunicar actualizaciones de los perfiles a trav\u00e9s de pub-sub. Este caso es bastante simple: un controlador gestiona la l\u00f3gica del servicio y publica las actualizaciones.<\/p>\n<p><\/p>\n<p>La situaci\u00f3n se complica cuando necesitamos implementar un servicio distribuido tolerante a fallos. Supongamos que los requisitos para los usuarios han cambiado: <\/p>\n<p><\/p>\n<ol>\n<li>ahora el servicio debe manejar solicitudes en 5 nodos del cl\u00faster, <\/li>\n<li>tener la capacidad de ejecutar tareas en segundo plano, <\/li>\n<li>y tambi\u00e9n ser capaz de gestionar din\u00e1micamente las listas de suscripci\u00f3n a las actualizaciones de los perfiles.<\/li>\n<\/ol>\n<p><\/p>\n<p><em>Nota:<\/em> No abordamos la cuesti\u00f3n del almacenamiento consistente y la replicaci\u00f3n de datos. Supongamos que estas cuestiones ya se han resuelto y que en el sistema ya existe una capa de almacenamiento confiable y escalable, y que los controladores tienen mecanismos para interactuar con ella.<\/p>\n<p><\/p>\n<p>La descripci\u00f3n formal del servicio de usuarios se ha complicado. Desde el punto de vista del programador, gracias al uso de mensajer\u00eda, los cambios son m\u00ednimos. Para satisfacer el primer requisito, necesitamos configurar la balanceo en el punto de intercambio req-resp. <\/p>\n<p><\/p>\n<p>La necesidad de procesar tareas en segundo plano es com\u00fan. En los usuarios, esto puede incluir verificaciones de documentos de los usuarios, procesamiento de multimedia cargada o sincronizaci\u00f3n de datos con redes sociales. Estas tareas deben ser distribuidas de alguna manera dentro del cl\u00faster y controlarse su progreso. Por ello, tenemos dos opciones: usar la plantilla de distribuci\u00f3n de tareas del art\u00edculo anterior, o, si no es adecuada, escribir un programador de tareas personalizado que gestione el grupo de manejadores de la manera que necesitamos. <\/p>\n<p><\/p>\n<p>El punto 3 requiere ampliar la plantilla pub-sub. Y para implementarlo, tras la creaci\u00f3n del punto de intercambio pub-sub, necesitamos iniciar adicionalmente el controlador de este punto dentro de nuestro servicio. As\u00ed, parece que estamos separando la l\u00f3gica de procesamiento de las suscripciones y desuscripciones de la capa de mensajer\u00eda a la implementaci\u00f3n de usuarios.<\/p>\n<p><\/p>\n<p>Como resultado, la descomposici\u00f3n de la tarea mostr\u00f3 que para satisfacer los requisitos necesitamos lanzar 5 instancias del servicio en diferentes nodos y crear una entidad adicional: un controlador pub-sub, responsable de las suscripciones.<br \/>\nPara lanzar 5 manejadores no se requiere cambiar el c\u00f3digo del servicio. La \u00fanica acci\u00f3n adicional es la configuraci\u00f3n de las reglas de balanceo en el punto de intercambio, de lo que hablaremos m\u00e1s adelante.<br \/>\nAdem\u00e1s, surgi\u00f3 una complejidad adicional: el controlador pub-sub y el planificador de tareas personalizado deben funcionar en una \u00fanica instancia. Nuevamente, el servicio de mensajer\u00eda, como fundamental, debe proporcionar un mecanismo para elegir un l\u00edder.<\/p>\n<p><\/p>\n<h3 id=\"vybor-lidera\">Elecci\u00f3n del l\u00edder<\/h3>\n<p><\/p>\n<p>En sistemas distribuidos, la elecci\u00f3n del l\u00edder es el procedimiento de designaci\u00f3n de un \u00fanico proceso encargado de planificar el procesamiento distribuido de alguna carga. <\/p>\n<p><\/p>\n<p>En sistemas que no tienden a la centralizaci\u00f3n, se utilizan algoritmos universales y algoritmos basados en consenso, como paxos o raft.<br \/>\nDado que la mensajer\u00eda es un corredor y un elemento central, conoce a todos los controladores del servicio que son candidatos a l\u00edderes. La mensajer\u00eda puede designar un l\u00edder sin la necesidad de una votaci\u00f3n.<\/p>\n<p><\/p>\n<p>Todos los servicios, tras su inicio y conexi\u00f3n al punto de intercambio, reciben un mensaje del sistema <code>#'$leader'{exchange = ?EXCHANGE, pid = LeaderPid, servers = Servers}<\/code>. En caso de que <code>LeaderPid<\/code> coincida con <code>pid<\/code> del proceso actual, se le designa como l\u00edder, y la lista <code>Servers<\/code> incluye todos los nodos y sus par\u00e1metros.<br \/>\nEn el momento de la aparici\u00f3n de un nuevo nodo y la desconexi\u00f3n de un nodo en funcionamiento del cl\u00faster, todos los controladores del servicio reciben <code>#'$slave_up'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts}<\/code> y <code>#'$slave_down'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts}<\/code> correspondientemente.<\/p>\n<p><\/p>\n<p>De este modo, todos los componentes son conscientes de todos los cambios, y en el cl\u00faster hay garantizado un l\u00edder en cada momento.<\/p>\n<p><\/p>\n<h2 id=\"posredniki\">Intermediarios<\/h2>\n<p><\/p>\n<p>Para implementar procesos complejos de procesamiento distribuido, as\u00ed como en tareas de optimizaci\u00f3n de arquitecturas existentes, es conveniente utilizar intermediarios.<br \/>\nPara no modificar el c\u00f3digo de los servicios y resolver, por ejemplo, tareas de procesamiento adicional, enrutamiento o registro de mensajes, se puede incluir un manejador proxy delante del servicio, que realizar\u00e1 todo el trabajo adicional.<\/p>\n<p><\/p>\n<p>Un ejemplo cl\u00e1sico de optimizaci\u00f3n pub-sub es una aplicaci\u00f3n distribuida con un n\u00facleo comercial que genera eventos de actualizaci\u00f3n, como cambios en los precios del mercado, y una capa de acceso: N servidores que proporcionan API websocket para clientes web.<br \/>\nSi se aborda de manera directa, el servicio al cliente se ve de la siguiente manera:<\/p>\n<p><\/p>\n<ul>\n<li>el cliente establece conexiones con la plataforma. En el lado del servidor, que termina el tr\u00e1fico, se inicia el proceso que atiende esta conexi\u00f3n.<\/li>\n<li>en el contexto del proceso de atenci\u00f3n se realiza la autorizaci\u00f3n y suscripci\u00f3n a actualizaciones. El proceso llama al m\u00e9todo subscribe para los temas.<\/li>\n<li>despu\u00e9s de que se genera un evento en el n\u00facleo, se entrega a los procesos que atienden las conexiones.<\/li>\n<\/ul>\n<p><\/p>\n<p>Imaginemos que tenemos 50000 suscriptores para el tema \"noticias\". Los suscriptores est\u00e1n distribuidos uniformemente en 5 servidores. Como resultado, cada actualizaci\u00f3n, al llegar al punto de intercambio, ser\u00e1 replicada 50000 veces: 10000 veces en cada servidor, seg\u00fan la cantidad de suscriptores en \u00e9l. \u00bfNo es una esquema algo ineficiente?<br \/>\nPara mejorar la situaci\u00f3n, introduciremos un proxy que tenga el mismo nombre que el punto de intercambio. El registrador de nombres globales debe poder devolver el proceso m\u00e1s cercano por nombre, esto es importante.<\/p>\n<p><\/p>\n<p>Ejecutaremos este proxy en los servidores de la capa de acceso, y todos nuestros procesos que atienden la API websocket se suscribir\u00e1n a \u00e9l, y no al punto de intercambio pub-sub original en el n\u00facleo. El proxy se suscribe al n\u00facleo solo en caso de una suscripci\u00f3n \u00fanica y replica el mensaje recibido a todos sus suscriptores.<br \/>\nComo resultado, entre el n\u00facleo y los servidores de acceso se enviar\u00e1n 5 mensajes, en lugar de 50000.<\/p>\n<p><\/p>\n<h2 id=\"marshrutizaciya-i-balansirovka\">Enrutamiento y balanceo<\/h2>\n<p><\/p>\n<h3 id=\"req-resp\">Req-Resp<\/h3>\n<p><\/p>\n<p>En la implementaci\u00f3n actual de mensajer\u00eda existen 7 estrategias de distribuci\u00f3n de solicitudes:<\/p>\n<p><\/p>\n<ul>\n<li><code>default<\/code>. La solicitud se env\u00eda a todos los controladores.<\/li>\n<li><code>round-robin<\/code>. Se realiza un recorrido y distribuci\u00f3n c\u00edclica de las solicitudes entre los controladores.<\/li>\n<li><code>consenso<\/code>. Los controladores que manejan el servicio se dividen en l\u00edder y seguidores. Las solicitudes se env\u00edan solo al l\u00edder.<\/li>\n<li><code>consenso &amp; round-robin<\/code>. En el grupo hay un l\u00edder, pero las solicitudes se distribuyen entre todos los miembros.<\/li>\n<li><code>sticky<\/code>. Se calcula una funci\u00f3n hash y se asocia a un manejador espec\u00edfico. Las solicitudes posteriores con esta firma se env\u00edan a este mismo manejador.<\/li>\n<li><code>sticky-fun<\/code>. Al iniciar el punto de intercambio, se pasa adicionalmente una funci\u00f3n para calcular el hash para <code>sticky<\/code> balanceo.<\/li>\n<li><code>fun<\/code>. Es similar a sticky-fun, pero se pueden redirigir, rechazar o preprocesar adicionalmente. <\/li>\n<\/ul>\n<p><\/p>\n<p>La estrategia de distribuci\u00f3n se establece al inicializar el punto de intercambio.<\/p>\n<p><\/p>\n<p>Adem\u00e1s del balanceo, el messaging permite etiquetar entidades. Analicemos los tipos de etiquetas en el sistema:<\/p>\n<p><\/p>\n<ul>\n<li>Etiqueta de conexi\u00f3n. Permite entender a trav\u00e9s de qu\u00e9 conexi\u00f3n llegaron los eventos. Se utiliza cuando el proceso del controlador se conecta a un punto de intercambio, pero con diferentes claves de enrutamiento. <\/li>\n<li>Etiqueta de servicio. Permite agrupar manejadores para un \u00fanico servicio y ampliar las capacidades de enrutamiento y balanceo. Para el patr\u00f3n req-resp, el enrutamiento es lineal. Enviamos una solicitud al punto de intercambio, luego lo transmite al servicio. Pero si necesitamos dividir los manejadores en grupos l\u00f3gicos, la divisi\u00f3n se realiza mediante etiquetas. Al especificar una etiqueta, la solicitud se dirigir\u00e1 a un grupo espec\u00edfico de controladores.<\/li>\n<li>Etiqueta de solicitud. Permite distinguir las respuestas. Dado que nuestro sistema es asincr\u00f3nico, para procesar las respuestas del servicio necesitamos la capacidad de especificar el RequestTag al enviar la solicitud. Por ello, podremos identificar a qu\u00e9 solicitud corresponde la respuesta que hemos recibido.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"pub-sub\">Pub-sub<\/h3>\n<p><\/p>\n<p>Para pub-sub es un poco m\u00e1s simple. Tenemos un punto de intercambio al que se publican mensajes. El punto de intercambio distribuye mensajes entre los suscriptores que se han suscrito a las claves de enrutamiento que les interesan (se puede decir que es an\u00e1logo a los temas).<\/p>\n<p><\/p>\n<h2 id=\"masshtabiruemost-i-otkazoustoychivost\">Escalabilidad y tolerancia a fallos<\/h2>\n<p><\/p>\n<p>La escalabilidad del sistema en su conjunto depende del grado de escalabilidad de las capas y componentes del sistema:<\/p>\n<p><\/p>\n<ul>\n<li>Los servicios se escalan a\u00f1adiendo nodos adicionales con manejadores de este servicio al cl\u00faster. Durante la operaci\u00f3n pr\u00e1ctica, se puede elegir la pol\u00edtica de balanceo \u00f3ptima.<\/li>\n<li>El propio servicio de mensajer\u00eda, en el contexto de un cl\u00faster separado, generalmente se escala ya sea trasladando puntos de intercambio con alta carga a nodos separados del cl\u00faster, o a\u00f1adiendo procesos proxy en zonas especialmente sobrecargadas del cl\u00faster.<\/li>\n<li>La escalabilidad de todo el sistema como caracter\u00edstica depende de la flexibilidad de la arquitectura y de la capacidad de integrar cl\u00fasteres individuales en una entidad l\u00f3gica com\u00fan.<\/li>\n<\/ul>\n<p><\/p>\n<p>La simplicidad y rapidez de escalado a menudo determina el \u00e9xito del proyecto. La mensajer\u00eda en la implementaci\u00f3n actual crece junto con la aplicaci\u00f3n. Incluso si no contamos con un cl\u00faster de 50-60 m\u00e1quinas, se puede recurrir a la federaci\u00f3n. Desafortunadamente, el tema de la federaci\u00f3n est\u00e1 m\u00e1s all\u00e1 del alcance de este art\u00edculo.<\/p>\n<p><\/p>\n<h2 id=\"rezervirovanie\">Redundancia<\/h2>\n<p><\/p>\n<p>Al analizar el balanceo de carga, ya discutimos la redundancia de los controladores de servicios. Sin embargo, la mensajer\u00eda tambi\u00e9n debe estar reservada. En caso de ca\u00edda de un nodo o m\u00e1quina, la mensajer\u00eda debe recuperarse autom\u00e1ticamente en el menor tiempo posible.<\/p>\n<p><\/p>\n<p>En mis proyectos, utilizo nodos adicionales que asumen la carga en caso de ca\u00edda. En Erlang, existe una implementaci\u00f3n est\u00e1ndar de modo distribuido para aplicaciones OTP. El modo distribuido se encarga de la recuperaci\u00f3n en caso de falla iniciando la aplicaci\u00f3n ca\u00edda en otro nodo previamente en funcionamiento. El proceso es transparente; tras el fallo, la aplicaci\u00f3n se traslada autom\u00e1ticamente al nodo de failover. Puedes leer m\u00e1s sobre esta funcionalidad. <noindex><a rel=\"nofollow\" href=\"http:\/\/erlang.org\/doc\/design_principles\/distributed_applications.html\">aqu\u00ed<\/a><\/noindex>.<\/p>\n<p><\/p>\n<h2 id=\"proizvoditelnost\">Rendimiento<\/h2>\n<p><\/p>\n<p>Intentemos comparar al menos de manera aproximada el rendimiento de rabbitmq y nuestro sistema de mensajer\u00eda personalizado.<br \/>\nHe encontrado <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.openstack.org\/developer\/performance-docs\/test_results\/mq\/rabbitmq\/cmsm\/index.html\">resultados oficiales<\/a><\/noindex> de pruebas de rabbitmq del equipo de openstack.<\/p>\n<p><\/p>\n<p>En el apartado 6.14.1.2.1.2.2. del documento original se presenta el resultado de RPC CAST:<br \/>\n<img decoding=\"async\" alt=\"Bloques de construcci\u00f3n de aplicaciones distribuidas. Segunda aproximaci\u00f3n\" src=\"\/wp-content\/uploads\/2019\/04\/95f615d241d70a4523fe3c400179b8e6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Previamente, no realizaremos ninguna configuraci\u00f3n adicional en el n\u00facleo del sistema operativo o en la m\u00e1quina virtual de Erlang. Las condiciones para las pruebas son:<\/p>\n<p><\/p>\n<ul>\n<li>erl opts: +A1 +sbtu.<\/li>\n<li>La prueba en el \u00e1mbito de un solo nodo de Erlang se ejecuta en un port\u00e1til con un viejo i7 en una configuraci\u00f3n m\u00f3vil.<\/li>\n<li>Las pruebas de cl\u00faster se realizan en servidores con red de 10G.<\/li>\n<li>El c\u00f3digo funciona en contenedores Docker. La red est\u00e1 en modo NAT.<\/li>\n<\/ul>\n<p><\/p>\n<p>C\u00f3digo de la prueba:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">req_resp_bench(_) -&gt;\n  W = perftest:comprehensive(10000,\n    fun() -&gt;\n      messaging:request(?EXCHANGE, default, ping, self()),\n      receive\n        #'$msg'{message = pong} -&gt; ok\n      after 5000 -&gt;\n        throw(timeout)\n      end\n    end\n  ),\n  true = lists:any(fun(E) -&gt; E &gt;= 30000 end, W),\n  ok.<\/code><\/pre>\n<p><\/p>\n<p><em>Escenario 1:<\/em> La prueba se ejecuta en un port\u00e1til con un viejo i7 de m\u00f3vil. La prueba, el mensajer\u00eda y el servicio se ejecutan en un solo nodo dentro de un contenedor Docker:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Ciclos secuenciales de 10000 en ~0 segundos (26987 ciclos\/s)\nCiclos secuenciales de 20000 en ~1 segundos (26915 ciclos\/s)\nCiclos secuenciales de 100000 en ~4 segundos (26957 ciclos\/s)\nParalelo 2 ciclos de 100000 en ~2 segundos (44240 ciclos\/s)\nParalelo 4 ciclos de 100000 en ~2 segundos (53459 ciclos\/s)\nParalelo 10 ciclos de 100000 en ~2 segundos (52283 ciclos\/s)\nParalelo 100 ciclos de 100000 en ~3 segundos (49317 ciclos\/s)<\/code><\/pre>\n<p><\/p>\n<p><em>Escenario 2<\/em>: 3 nodos ejecut\u00e1ndose en diferentes m\u00e1quinas bajo Docker (NAT).<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Ciclos secuenciales de 10000 en ~1 segundos (8684 ciclos\/s)\nCiclos secuenciales de 20000 en ~2 segundos (8424 ciclos\/s)\nCiclos secuenciales de 100000 en ~12 segundos (8655 ciclos\/s)\nParalelo 2 ciclos de 100000 en ~7 segundos (15160 ciclos\/s)\nParalelo 4 ciclos de 100000 en ~5 segundos (19133 ciclos\/s)\nParalelo 10 ciclos de 100000 en ~4 segundos (24399 ciclos\/s)\nParalelo 100 ciclos de 100000 en ~3 segundos (34517 ciclos\/s)<\/code><\/pre>\n<p><\/p>\n<p>En todos los casos, la utilizaci\u00f3n de CPU no super\u00f3 el 250%<\/p>\n<p><\/p>\n<h2 id=\"itogi\">Resultados<\/h2>\n<p><\/p>\n<p>Espero que este ciclo no parezca un volcado de conciencia y que mi experiencia aporte un beneficio real tanto a los investigadores de sistemas distribuidos como a los profesionales que est\u00e1n comenzando a construir arquitecturas distribuidas para sus sistemas empresariales y que miran con inter\u00e9s a Erlang\/Elixir, pero dudan si vale la pena...<\/p>\n<p><\/p>\n<p>Foto <noindex><a rel=\"nofollow\" href=\"https:\/\/unsplash.com\/photos\/Q4bmoSPJM18\">@chuttersnap<\/a><\/noindex><\/p>\n<p class=\"for_users_only_msg\">Solo los usuarios registrados pueden participar en la encuesta. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Inicie sesi\u00f3n<\/a><\/noindex>, por favor.<\/p>\n<h2 class=\"default-block__polling-title\">\u00bfQu\u00e9 temas deber\u00eda abordar con m\u00e1s detalle en el ciclo \"Experimento VTrade\"?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Teor\u00eda: Mercados, \u00f3rdenes y su vigencia: DAY, GTD, GTC, IOC, FOK, MOO, MOC, LOO, LOC<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Libro de \u00f3rdenes. Teor\u00eda y pr\u00e1ctica de la implementaci\u00f3n del libro con agrupaciones<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Visualizaci\u00f3n de operaciones: Ticks, barras, resoluciones. C\u00f3mo almacenar y c\u00f3mo unir<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Backoffice. Planificaci\u00f3n y desarrollo. Control de empleados e investigaci\u00f3n de incidentes<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    API. Analizamos qu\u00e9 interfaces son necesarias y c\u00f3mo implementarlas<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Almacenamiento de informaci\u00f3n: PostgreSQL, Timescale, Tarantool en sistemas de comercio<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Reactividad en sistemas de comercio<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Otro. Escribir\u00e9 en los comentarios<\/p>\n<\/li>\n<\/ul>\n<p>    Votaron 6 usuarios. 4 usuarios se abstuvieron.<br \/>\n<br \/>Fuente: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446344\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0410\u043d\u043e\u043d\u0441 \u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043b\u0435\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f: \u201c\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 VTrade\u201d \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c. \u0412 \u0446\u0438\u043a\u043b\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u0430 \u0442\u0435\u043e\u0440\u0438\u044f \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0431\u0438\u0440\u0436\u0438, \u0430\u0443\u043a\u0446\u0438\u043e\u043d\u0430 \u0438 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430. \u0412 \u043a\u043e\u043d\u0446\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043f\u0440\u043e\u0433\u043e\u043b\u043e\u0441\u043e\u0432\u0430\u0442\u044c \u0437\u0430 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0432\u0430\u043c \u0442\u0435\u043c\u044b. \u042d\u0442\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0446\u0438\u043a\u043b\u0430 \u043f\u043e \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":23092,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-31124","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0410\u043d\u043e\u043d\u0441 \u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043b\u0435\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f: \u201c\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 VTrade\u201d \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0421\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0412\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0410\u043d\u043e\u043d\u0441 \u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043b\u0435\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f: \u201c\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 VTrade\u201d \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:39:36+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:39:36+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Bloques de construcci\u00f3n para aplicaciones distribuidas. Segunda aproximaci\u00f3n | ProHoster","description":"Anuncio Colegas, a mediados del verano planeo lanzar otra serie de art\u00edculos sobre el dise\u00f1o de sistemas de atenci\u00f3n masiva: \"Experimento VTrade\" \u2014 un intento de escribir un marco para el comercio.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0421\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0412\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 | ProHoster","og:description":"\u0410\u043d\u043e\u043d\u0441 \u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043b\u0435\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f: \u201c\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 VTrade\u201d \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445.","og:url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:39:36+00:00","article:modified_time":"2019-10-31T18:39:36+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"31124","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 04:39:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:22:34","updated":"2026-01-21 04:39:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/31124","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=31124"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/31124\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/23092"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=31124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=31124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=31124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}