{"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\/en\/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 &#8220;hijo&#8221; 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 &#8220;pocos&#8221; 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 &#8220;poquito&#8221; ya que no pueden ejecutar procedimientos complejos sin separar la ejecuci\u00f3n mediante Threads o procesos. Como hacen &#8220;poquito&#8221; 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 &#8220;web servers&#8221;&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 &#8220;natural&#8221; usan funcionalidades del sistema operativo para tratar las conexiones (en el fondo b\u00fafferes) de modo paralelo y cuando les llega algo &#8220;raro&#8221; 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 &#8220;puros&#8221; 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 &#8220;s\u00f3lo&#8221; 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 &#8220;load avg.&#8221; 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 &#8220;h\u00edbrido&#8221; 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 &#8220;hijo&#8221; por conexi\u00f3n, y la gesti\u00f3n de estos hijos es costosa computacionalmente hablando.As\u00ed que la<a href=\"https:\/\/www.xpnti.net\/en\/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\/en\/wp-json\/wp\/v2\/posts\/13"}],"collection":[{"href":"https:\/\/www.xpnti.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xpnti.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xpnti.net\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xpnti.net\/en\/wp-json\/wp\/v2\/comments?post=13"}],"version-history":[{"count":1,"href":"https:\/\/www.xpnti.net\/en\/wp-json\/wp\/v2\/posts\/13\/revisions"}],"predecessor-version":[{"id":202,"href":"https:\/\/www.xpnti.net\/en\/wp-json\/wp\/v2\/posts\/13\/revisions\/202"}],"wp:attachment":[{"href":"https:\/\/www.xpnti.net\/en\/wp-json\/wp\/v2\/media?parent=13"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xpnti.net\/en\/wp-json\/wp\/v2\/categories?post=13"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xpnti.net\/en\/wp-json\/wp\/v2\/tags?post=13"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}