{"id":13,"date":"2010-03-14T20:27:00","date_gmt":"2010-03-14T19:27:00","guid":{"rendered":"http:\/\/beta.expertosenti.com\/2010\/03\/%c2%bfcomo-evitar-que-los-problemas-de-los-usuarios-sean-conviertan-en-nuestros\/"},"modified":"2017-04-24T16:48:48","modified_gmt":"2017-04-24T14:48:48","slug":"como-evitar-que-los-problemas-de-los-usuarios-sean-conviertan-en-nuestros","status":"publish","type":"post","link":"https:\/\/www.xpnti.net\/es\/como-evitar-que-los-problemas-de-los-usuarios-sean-conviertan-en-nuestros\/","title":{"rendered":"\u00bfC\u00f3mo evitar que los problemas de los usuarios sean conviertan en nuestros?"},"content":{"rendered":"<p>Como comentamos en el <a href=\"http:\/\/blog.expertosenti.com\/2010\/03\/puede-afectar-el-emule-de-los-usuarios.html\">post anterior<\/a>, un usuario lento puede impactarnos en el numero de usuarios que podemos soportar en un momento dado. El usuario lento o malintencionado est\u00e1 explotando el hecho que la mayor\u00eda de servidores Web usan un \u00abhijo\u00bb por conexi\u00f3n, y la gesti\u00f3n de estos hijos es costosa computacionalmente hablando.<br \/>As\u00ed que la mejor forma que tenemos para soportar&nbsp;much\u00edsimos&nbsp;usuarios, lentos o no, es separar la gesti\u00f3n de la conexi\u00f3n de la generaci\u00f3n del objeto a entregar.<br \/>Y como no podr\u00eda ser de otra forma, tenemos de todo, desde opciones radicales en cada extremo hasta soluciones h\u00edbridas que intentan ofrecer lo mejor de los dos mundos.<\/p>\n<div class=\"separator\" style=\"clear: both; text-align: center;\"><a href=\"https:\/\/2.bp.blogspot.com\/_iJayHHFD94E\/S2j76pt1u1I\/AAAAAAAACiY\/0BVO-vjSV8w\/s1600\/Vi%C3%B1a-del-se%C3%B1or.jpg\" imageanchor=\"1\" style=\"margin-left: 1em; margin-right: 1em;\"><img loading=\"lazy\" border=\"0\" height=\"322\" src=\"https:\/\/2.bp.blogspot.com\/_iJayHHFD94E\/S2j76pt1u1I\/AAAAAAAACiY\/0BVO-vjSV8w\/s400\/Vi%C3%B1a-del-se%C3%B1or.jpg\" width=\"400\" \/><\/a><\/div>\n<div class=\"separator\" style=\"clear: both; text-align: center;\"><a href=\"http:\/\/www.dosisdiarias.com\/\">www.dosisdiarias.com<\/a><\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\"><\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\">En un extremo tenemos los puramente basados en una relaci\u00f3n 1:1 entre conexi\u00f3n e hijo, donde tratan igual las peticiones r\u00e1pidas de c\u00e1lculo (ficheros est\u00e1ticos) que las lentas (peticiones a base de datos, generaci\u00f3n de html personalizados, etc). Aqu\u00ed tendr\u00edamos a nuestros amigos Apache HTTP Server, Apache Tomcat y&nbsp;much\u00edsimos&nbsp;otros basados en ellos. En estos una saturaci\u00f3n de los \u00abpocos\u00bb hijos disponibles nos tira el servicio tanto para ficheros est\u00e1ticos como para los din\u00e1micos.<\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\"><\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\">En el otro extremos tenemos los que los hijos no son funci\u00f3n de las conexiones existentes&nbsp;sino&nbsp;de por ejemplo los procesadores de la m\u00e1quina u otros datos de valor fijo. Estos utilizan herramientas como epoll, &nbsp;kqueue y la&nbsp;mayor\u00eda&nbsp;est\u00e1n&nbsp;inspirados por el <a href=\"http:\/\/www.kegel.com\/c10k.html\">problema de las 10.000 conexiones concurrentes<\/a>. Casi todos estos en el fondo hacen \u00abpoquito\u00bb ya que no pueden ejecutar procedimientos complejos sin separar la ejecuci\u00f3n mediante Threads o procesos. Como hacen \u00abpoquito\u00bb la&nbsp;mayor\u00eda&nbsp;de veces se acaban montando como frontends de los que si que hacen algo aunque en algunos casos estan dise\u00f1ado para entregar ficheros. En los puramente frontend por ejemplo&nbsp;tendr\u00edamos&nbsp;al <a href=\"http:\/\/www.zeus.com\/products\/traffic-manager\/index.html\">Zeus ZXTM<\/a>,un gran acelerador de aplicaciones al que recomiendo dar un vistazo y luego los \u00abweb servers\u00bb&nbsp;como los <a href=\"http:\/\/nginx.org\/\">nginx<\/a>,<a href=\"http:\/\/www.lighttpd.net\/\">lighttpd<\/a>, que aparte de mover conexiones y modificar lo entregado al usuario de varias formas (gzip, cache, rewrites, bandwidth shaping, etc) tambi\u00e9n saben entregar ficheros y hablan FastCGI o CGI donde aqu\u00ed si que&nbsp;ir\u00e1n&nbsp;lanzando procesos m\u00e1s o menos eficientemente.<\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\"><\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\">Y los \u00faltimos, los h\u00edbridos, que he puesto en este saco todos los que tratan por un lado las conexiones simples mediante herramientas no bloqueantes (poll, events, etc&#8230;), y que si se encuentran una petici\u00f3n din\u00e1mica la pasan a un worker thread (dentro o fuera de su proceso) de forma que las peticiones a ficheros est\u00e1ticos no te molestan en los workers y mirando Webs aleatorias,&nbsp;tendr\u00edamos&nbsp;una relaci\u00f3n de 50:1 entre ficheros est\u00e1ticos (js, css,&nbsp;im\u00e1genes,&nbsp;v\u00eddeos, etc) y din\u00e1micos (la mayor\u00eda de veces el html y punto). En este saco tenemos los <a href=\"http:\/\/blogs.msdn.com\/tmarq\/archive\/2007\/07\/21\/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx\">IIS 6, 7 y 7.5<\/a>, <a href=\"https:\/\/grizzly.dev.java.net\/\">Glassfish con Grizzly<\/a>&nbsp;o <a href=\"http:\/\/caucho.com\/resin\/doc\/overview.xtp#resin10k\">Resin Pro<\/a>, que de forma \u00abnatural\u00bb usan funcionalidades del sistema operativo para tratar las conexiones (en el fondo b\u00fafferes) de modo paralelo y cuando les llega algo \u00abraro\u00bb lo suben a un Thread de worker, IIS con el ASP.net, Glassfish en Java y Resin en Java y PHP.<\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\">En el fondo se comportan como uno de los \u00abpuros\u00bb escalables m\u00e1s un daemon funcionando en<a href=\"http:\/\/www.k4ml.com\/node\/161\"> FastCGI como podr\u00eda ser PHP<\/a>, que por defecto lanza \u00abs\u00f3lo\u00bb 8 procesos que depende de la aplicaci\u00f3n&nbsp;ser\u00e1n&nbsp;suficientes o no (si estos PHP lanzan consultas a Facebook que tardan un segundo, como mucho tendr\u00e1s 8 peticiones\/segundo y la CPU al 100% de <b>idle!<\/b>). Pero si que te ahorras todo el tiempo de espera en la descarga del documento si les has asignado suficiente profundidad de b\u00fafer, claro \ud83d\ude1b<\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\"><\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\">En el fondo, en muchos casos no es tan importante como funciona el servidor de aplicaciones ya que en aplicaciones con bastantes usuarios requeriremos de un balanceador y ya que estamos mejor meter un ZXTM o un nginx, activarle cache y dotarle de parte de inteligencia como gzip, rewrites, validaci\u00f3n de par\u00e1metros, etc y dejar a los servidores de aplicaci\u00f3n trabajar s\u00f3lo para la aplicaci\u00f3n y optimizarlos para ella (memoria, threads, etc)<\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\"><\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\">Teniendo en cuenta todo esto podemos llegar a aprovechar mucho m\u00e1s el servidor, cosa que implica, m\u00e1s usuarios por menos euros :D.&nbsp;<\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\">Es una&nbsp;tonter\u00eda&nbsp;pero monitorizar servidores en base a \u00abload avg.\u00bb aunque es una&nbsp;m\u00e9trica&nbsp;importante, nos indica que el servidor est\u00e1 esperando algo y no sirviendo a usuarios y si adem\u00e1s el % de idle es alto, indica que tenemos mucho a mejorar a nivel de arquitectura, tanto de HW como SW<\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\"><\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\">Bueno,&nbsp;dir\u00eda&nbsp;que para hoy ya estamos, que sino me voy alargando y salen posts&nbsp;kilom\u00e9tricos<\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\"><\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\">Saludos!<\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\"><\/div>\n<div class=\"separator\" style=\"clear: both; text-align: left;\"><b>&lt;update&gt;:<\/b>&nbsp;Ayer, antes de empezar la segunda sesi\u00f3n, un Senior Researcher del <a href=\"http:\/\/www.bsc.es\/\">BSC\/CNS<\/a> que hab\u00eda realizado la tesis sobre escalabilidad en Web Servers me coment\u00f3 que Tomcat lo podr\u00edamos considerar \u00abh\u00edbrido\u00bb ya que tenemos un conector HTTP que utiliza NIO en lugar de multiples Threads, as\u00ed que de los grandes s\u00f3lo nos queda Apache que no soporta NIO&#8230;<b>&lt;\/update&gt;<\/b><\/div>\n<p>PS: Para aquellos que se&nbsp;est\u00e1n&nbsp;diciendo, es que yo quiero controlar los accesos a mis&nbsp;im\u00e1genes,&nbsp;v\u00eddeos, etc y claro los hago pasar por el PHP,&nbsp;plantearos&nbsp;un sistema de tickets o tokens que sea f\u00e1cil de validar (nada de base de datos) y se lo&nbsp;dej\u00e1is&nbsp;al balanceador o frontend, os ahorrareis un&nbsp;mont\u00f3n&nbsp;de accesos al servidor de aplicaciones.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Como comentamos en el post anterior, un usuario lento puede impactarnos en el numero de usuarios que podemos soportar en un momento dado. El usuario lento o malintencionado est\u00e1 explotando el hecho que la mayor\u00eda de servidores Web usan un \u00abhijo\u00bb por conexi\u00f3n, y la gesti\u00f3n de estos hijos es costosa computacionalmente hablando.As\u00ed que la<a href=\"https:\/\/www.xpnti.net\/es\/como-evitar-que-los-problemas-de-los-usuarios-sean-conviertan-en-nuestros\/\">[&#8230;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.xpnti.net\/es\/wp-json\/wp\/v2\/posts\/13"}],"collection":[{"href":"https:\/\/www.xpnti.net\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xpnti.net\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xpnti.net\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xpnti.net\/es\/wp-json\/wp\/v2\/comments?post=13"}],"version-history":[{"count":1,"href":"https:\/\/www.xpnti.net\/es\/wp-json\/wp\/v2\/posts\/13\/revisions"}],"predecessor-version":[{"id":202,"href":"https:\/\/www.xpnti.net\/es\/wp-json\/wp\/v2\/posts\/13\/revisions\/202"}],"wp:attachment":[{"href":"https:\/\/www.xpnti.net\/es\/wp-json\/wp\/v2\/media?parent=13"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xpnti.net\/es\/wp-json\/wp\/v2\/categories?post=13"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xpnti.net\/es\/wp-json\/wp\/v2\/tags?post=13"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}