Jorge&Bas*dame@jorgebas*da.com@jorgebas*daJaime&Irurzunjaime@irurzun.com@jaimeirurzunOpen SourceModern web development
env environmentOpen source modernweb development!⚒#dev developmentops operations
dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
Browser1
renderizaejecutahablaBrowserMás que un terminal tonto,pero no tanto másHTML + CSSJavaScriptHTTP (+DNS)
HTML + CSSJavaScriptHTTP (+DNS)BrowserMás que un terminal tonto,pero no tanto másfrontendbackend
renderiza HTML + CSS<html><head><title>Example</title><link rel="stylesheet"type="text/css"href="example.css"></head><body...
ejecuta JavaScript<html>...<body><h1>Title</h1>...<script type="text/javascript"src="example.js"></script></body></html>do...
¿qué ocurrepor detrás?habla HTTP (+DNS)
Escribes una URL en el navegador1Se hace una petición DNSpara traducir el hostname dela URL a su dirección IP2Se hace una ...
El navegador comienza a renderizar el HTML y hace máspeticiones [DNS+] HTTP para cada recurso (css, img, js, etc)que encue...
El navegador comienza a renderizar el HTML y hace máspeticiones [DNS+] HTTP para cada recurso (css, img, js, etc)que encue...
HTTP es el idioma de la weby hay que conocerlo
dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
HTTP2
físicoenlace de datosredtransportesesiónpresentaciónaplicaciónModelo OSIHardwareAcceso al medio (MAC)Enrutamiento entre re...
acceso al medioredtransporteaplicaciónTCP/IPfísicoenlace de datosredtransportesesiónpresentaciónaplicaciónModelo OSIhttp, ...
HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <d...
HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <d...
HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <d...
Un recurso se identifica mediante una URL<OPERACIÓN> <recurso> HTTP/1.1protocol://[user:pass@]host[:port][/resource]en htt...
<OPERACIÓN> <recurso> HTTP/1.1Las URLs son parte fundamentaldel diseño de una aplicación webhttp://www.wordpress.org/http:...
HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <d...
GET Obtiene un recurso. No debería producir cambios.POSTPUTCrea un recurso.Reemplaza o crea un recurso.DELETE Elimina un r...
<OPERACIÓN> <recurso> HTTP/1.1REST es un enfoque de diseño de APIs que,entre otras cosas, explota la pureza de estos conce...
+La navaja suiza de las URLscURL
La navaja suiza de las URLs$ curl example.com/recetas$ curl -XGET example.com/recetas$ curl -XPOST example.com/recetas$ cu...
La navaja suiza de las URLs$ curl example.com/recetas$ curl -XGET example.com/recetas$ curl -XPOST example.com/recetas$ cu...
$ curl -X GET google.com<HTML><HEAD><meta http-equiv="content-type"content="text/html;charset=utf-8"><TITLE>301 Moved</TIT...
HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <d...
<cabeceras>Son parejas Clave: valor que transmiten alservidor información acerca de la requestAccept: text/plainAccept-Cha...
<cabeceras>Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==Content-Type: application/x-www-form-urlencodedDate: Tue, 15 Nov 1994 08:1...
<cabeceras>Max-Forwards: 10Origin: http://www.example-social-network.comPragma: no-cacheProxy-Authorization: Basic QWxhZGR...
cURL:ver cabeceras$ curl -v -X GET google.com* About to connect() to google.com port 80 (#0)* Trying 173.194.41.8...* conn...
cURL:enviar cabeceras$ curl -v -X GET google.com -H User-Agent: Mozilla/5.0* About to connect() to google.com port 80 (#0)...
HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <d...
<cuerpo>Content-Type: application/jsonapplication/pdfapplication/x-www-form-urlencodedmultipart/form-dataimage/jpegtext/pl...
<cuerpo>POST /blog/posts HTTP/1.1Accept: application/jsonContent-Type: application/jsonContent-Length: 57Host: www.example...
<cuerpo>POST /blog/posts HTTP/1.1Accept: text/html, application/xhtml+xml, */*Content-Type: multipart/form-data; boundary=...
cURL:cuerpo de una petición$ curl -v -X POST localhost:8000/jugadores/ -d "username=pablo"* About to connect() to localhos...
HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <d...
HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <d...
HTTP/1.1 <código> <descripción>200 OK201 Created202 Accepted203 Non-Authoritative Information204 No Content205 Reset Conte...
HTTP/1.1 <código> <descripción>#4XX Client Error400 Bad Request401 Unauthorized402 Payment Required403 Forbidden404 Not Fo...
HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <d...
<cabeceras>Access-Control-Allow-Origin: *Accept-Ranges: bytesAge: 12Allow: GET, HEADCache-Control: max-age=3600Connection:...
<cabeceras>Content-Range: bytes 21010-47021/47022Content-Type: text/html; charset=utf-8Date: Tue, 15 Nov 1994 08:12:31 GMT...
<cabeceras>Retry-After: 120Server: Apache/2.4.1 (Unix)Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1Status: 200 OKStr...
HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <d...
<cuerpo>HTTP/1.1 200 OKContent-Type: text/htmlDate: Thu, 31 May 2007 20:35:00 GMT<html><head><title>Web page</title></head...
HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <d...
HTTP/1.1 200 OKContent-Type: text/htmlDate: Thu, 31 May 2007 20:35:00 GMT<html><body><h1>Hello world</h1></body></html>HTT...
HTTP/1.1 301 Moved PermanentlyLocation: http://www.example.com/new/url/HTTP/1.1 302 FoundLocation: http://www.example.com/...
HTTP/1.1 400 Bad RequestHTTP/1.1 401 UnauthorizedWWW-Authenticate: Basic realm="..."HTTP/1.1 403 ForbiddenHTTP/1.1 404 Not...
HTTP/1.1 500 Internal Server ErrorHTTP/1.1 501 Not ImplementedHTTP/1.1 502 Bad GatewayHTTP/1.1 503 Service UnavailableHTTP...
CookiesSolucionan la falta de estado del protocolo HTTP$#$#Son simples strings que se almacenan en el navegadorGET / HTTP/...
CookiesSet-Cookie: sessionid=xxx; Domain=docs.foo.com; Path=/accounts;Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpO...
CookiesSet-Cookie: sessionid=xxx; Domain=docs.foo.com; Path=/accounts;Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpO...
Método sencillo para proveer de autenticación a peticionesHTTP, sin necesidad de cookies$# GET / HTTP/1.1...Cliente Servid...
Basic HTTP authMétodo sencillo para proveer de autenticación a peticionesHTTP, sin necesidad de cookies$# GET / HTTP/1.1.....
cURL:Basic HTTP auth$ curl -v -X GET localhost:8000/ --user pablo:x6f8* About to connect() to localhost port 8000 (#0)* Tr...
Ejercicio cURL: La guarida del dragón.$ curl -v -XPOST 10.172.104.175/jugadores/ -d "username=pablo")
dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
HTTPS*
acceso al medioredtransporteaplicaciónfísicoenlace de datosredtransportesesiónpresentaciónaplicación HTTPTLS/SSLHTTPS
HTTPS$# CertificadoPublic key (P)P(K)OkK = ...Clave simétrica compartida mediante algoritmo asimétricoK(mensaje)K(mensaje)...
Otras navajas suizastcpflow$ sudo tcpflow -i eth0 port 80 -CSniffer de tráfico TCP por excelencia en UNIXChrome inspector
dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
Optimización3
ClienteServidorCanalCachear, Delegar, Indexarvarnish, redis, cron, batch...Reducir request ( número y tamaño )Minify, spri...
ClienteServidorCanalCachear, Delegar, Indexarvarnish, redis, cron, batch...Reducir request ( número y tamaño )Minify, spri...
Servidor3.1
Cachear3.1.1ContenidoRequest ResponseVarnishRequest
30m 10m no-cacheMemcached, redis etc...Contenido externo• APIs, RSS, TwitterContenido “Estático”• Últimas noticias• Nuevos...
> GET last_tweets<h1>n<ul><li>Hello from....Memcached•Ventajas• Velocidad• Sencillez•Inconvenientes• Volátil: sólo reside ...
> INCR message:143:comments 14445Redis•Ventajas• Velocidad• Tipos de datos complejos• Operaciones atómicas•Inconvenientes•...
Existen múltiples “puntos” donde cachear.•Servidor web• Intrusismo• Complejidad media•Código del proyecto “backend”• Senci...
•Requests Anónimas• Digg effect• Landing page• Google•Contenido Estático• Assets• Thumbnails•APIs•“Hot Pages”Request Respon...
Request* Versión muy simplificada del funcionamiento de VarnishVarnishVarnish3.1.1
Request vcl_recv()* Versión muy simplificada del funcionamiento de VarnishVarnishVarnish3.1.1
Request vcl_recv()lookup* Versión muy simplificada del funcionamiento de Varnishincache?VarnishVarnish3.1.1
Request vcl_recv()lookup* Versión muy simplificada del funcionamiento de Varnishincache?yesVarnishVarnish3.1.1
Request vcl_recv()lookup* Versión muy simplificada del funcionamiento de Varnishincache?Build ResponseyesVarnishVarnish3.1.1
Request vcl_recv()lookup* Versión muy simplificada del funcionamiento de Varnishincache?Build ResponseResponseyesVarnishVar...
Request vcl_recv()passlookup* Versión muy simplificada del funcionamiento de Varnishincache?noBuild ResponseResponseyesVarn...
Request vcl_recv()Backendpasslookup* Versión muy simplificada del funcionamiento de Varnishincache?noBuild Responsevcl_fetc...
Request vcl_recv()Backendpasslookup* Versión muy simplificada del funcionamiento de Varnishincache?noBuild Responsevcl_fetc...
Request vcl_recv()Backendpasslookup* Versión muy simplificada del funcionamiento de Varnishincache?noBuild Responsevcl_fetc...
sub vcl_recv {# Pass anything other than GET and HEAD directly.if (req.request != "GET" && req.request != "HEAD"){return(p...
sub vcl_fetch {# If the response status >= 400 dont cache it.if (beresp.status >= 400) {return (hit_for_pass);}# Remove co...
Demo Varnish3A
Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5sDejar que alguien haga el trabajo sucio, antes o despuéscsv#
Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5s¿Cuánto del trabajo sucio es imprescindible al instante?csv#???
Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5s¿Cuánto del trabajo sucio es imprescindible al instante?csv# ?¿caché??
Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5s¿Cuánto del trabajo sucio es imprescindible al instante?csv# ?¿caché?¿tare...
Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5s¿Cuánto del trabajo sucio es imprescindible al instante?csv#¿caché?¿tareap...
Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5s¿Cuánto del trabajo sucio es imprescindible al instante?csv#¿caché?Delegar...
Scheduler de trabajos de UNIXcron* * * * * <cmd>día de la semana (0 - 7)mes (1 - 12)día del mes (1 - 31)hora (0 - 23)minut...
Scheduler de trabajos de UNIX# crontab -l0 1 * * * /usr/sbin/ntpdate pool.ntp.org0 */2 * * * /home/root/bin/server-backup@...
Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5s¿Cuánto del trabajo sucio es imprescindible al instante?csv#¿caché?Delegar...
Celery3.2Sistema de Tareas Asíncronas distribuidas.• Features: Colas, Concurrencia, Distribuido...• Pro: Muy fácil de impl...
Celery3.2El principal componente es el Broker. Se encarga de almacenar yentregar tareas a todos los workers.EstableExperim...
Celery+RabbitMQ3.2
Celery+RabbitMQ3.2
Funcionamiento3.2Server #1celery workercelery beatServer #3celery workerServer #4web nodeServer #5web nodeañadirprocesarpr...
Funcionamiento3.2Server #1celery workercelery beatServer #3celery workerServer #4web nodeServer #5web nodeañadirprocesarpr...
Funcionamiento3.2Server #1celery workercelery beatServer #3celery workerServer #4web nodeServer #5web nodeañadirprocesarpr...
Funcionamiento3.2Conceptos clave:• Atómico: Las tareas se entregan solo a un worker.• Distribuido: Los nodos son independi...
Indexar3.3Preparar la información para acceder másrápido a ella en el momento de la consulta! DB Search-
!DB indexSELECT date(timestamp) as day, count(*)FROM stamp WHERE key=%s AND date(timestamp) > current_date - interval %sGR...
BEGIN;DROP TABLE IF EXISTS "stamp";CREATE TABLE "stamp" ("key" varchar(255) NOT NULL,"timestamp" timestamp without time zo...
BEGIN;DROP TABLE IF EXISTS "stamp";CREATE TABLE "stamp" ("key" varchar(255) NOT NULL,"timestamp" timestamp without time zo...
Search index-$#Cliente Servidorbd!q=covent gardenSELECT * FROM messages WHERE subject like %covent garden% ORbody like %co...
Search index-$#Cliente Servidorbd!q=covent gardenSELECT * FROM messages WHERE subject like %covent garden% ORbody like %co...
Search index-$#Cliente Servidorbd!q=covent garden-searchengine.
Search index-$#Cliente Servidorbd!q=covent garden-searchengine.
Redis3.3.3Redis is an open source, BSD licensed,advanced key-value store. It is oftenreferred to as a data structure serve...
Enero 2012
Enero 2012~67%~23%150ms300ms
Memcached Feb 2012~86%~14%50ms300ms
Redis Feb 2013~99%~1%3 ms300ms
Redis como Indice3.1Problema:Mostrar avatares de 25 usuarios que compartan algún áreacontigo promocionando aquellos que no...
3.1Solución: Sorted Sets1. Para cada area crear un sorted set con el id de todos los miembros.> ZADD area:1:followers 1 1a...
3.1Solución: Sorted Sets1. Para cada area crear un sorted set con el id de todos los miembros.> ZADD area:1:followers 1 1>...
3.1Solución: Sorted Sets1. Para cada area crear un sorted set con el id de todos los miembros.> ZADD area:1:followers 1 1>...
3.1Solución: Sorted Sets1. Para cada area crear un sorted set con el id de todos los miembros.> ZADD area:1:followers 1 1>...
3.1Solución: Sorted Sets1. Para cada area crear un sorted set con el id de todos los miembros.> ZADD area:1:followers 1 1>...
3.1Problema: ¿Usuarios que siguen el area #1?> GET area:1:followersarea:1:followers 1 2area:2:followers 1area:3:followers ...
3.1Problema: ¿Usuarios que siguen el area #1 o el area #2?> ZINTERSTORE areas:1-2:followers 2 area:1:followersarea:2:follo...
3.1Problema: 25 usuarios que sigan el area #1 o el area #2 promocionandoaquellos que tengan avatar.> ZREVRANGE areas:1-2:f...
3.1Problema: 25 usuarios que sigan el area #1 o el area #2 promocionandoaquellos que tengan avatar.> ZREVRANGE areas:1-2:f...
ClienteServidorCanalCachear, Delegar, Indexarvarnish, redis, cron, batch...Reducir request ( número y tamaño )Minify, spri...
Canal3.2
Minimizar JS y CSSSL.Utils.flash = {init: function () {// Handle closing of flash messages$(#flashes .close, .flashes .cl...
--line-break--type js|css--charset character-set--disable-optimizations$ java -jar yuicompressor.jar file.js -o file-min.j...
Sprites?
N 1
A.sprite-A{...}
A.sprite-A{background-image: url(sprite.png);...}
x:120pxy:50pxA.sprite-A{background-image: url(sprite.png);background-position: -120px -50px;...}
A.sprite-A{background-image: url(sprite.png);background-position: -120px -50px;width: 10px;height: 20px;...}20px10px
A<div class=”sprite-A”></div>
#1By hand
Rebuild sprites should can mustbe part of the assets-rebuild*for 99% of your sprites*“”
Glue$command-line-sprites$command-line-spritesgluecss.com
Drop source images somewhere
Drop source images somewhere$ glue source output
Drop source images somewhere$ glue source outputParty!
.sprite-icons-rainbow{background-image:url(sprite.png);background-repeat:no-repeat;background-position: 247px 147px;width:...
.glyphicons-187-more{background-image:url(glyphicons.png);background-repeat:no-repeat;background-position: 212px 42px;widt...
gzip3.2.2GET /index.htmlAccept-Encoding: gzipHTTP 1.1 200 OK<html><head> ...gzipServidorServidor sin gzip configuradoPese a...
GET /index.htmlAccept-Encoding: gzipServidor con gzip configuradoEstando gzip configurado en el servidor, si los clientesenv...
A tener en cuenta•Navegadores MUY antiguos no soportan gzip. (~12 años)• Netscape <6• Internet Explorer <5.5 (Julio 2000)•...
CDN: Content delivery network•Objetivos principales• Distribuir contenido de la manera más eficiente posible apoder ser des...
ClienteServidorCanalCachear, Delegar, Indexarvarnish, redis, cron, batch...Reducir request ( número y tamaño )Minify, spri...
Cliente3.3
Speeding up your website1. CSS y JS en ficheros externos2. CSS al comienzo3. JS al final4. Entre 2 y 4 hostnameshttp://dev...
dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
Arquitectura4
$Servidor WebAplicaciónBase de datos✓⚠SENCILLO❌✓ OK PARA EMPEZARTERMINA SIENDO POCOSPOFSSL*
$Servidor WebAplicación✓⚠SENCILLO❌✓ PUEDE LLEVARTE LEJOSTERMINA SIENDO POCOSPOF$Base de datos⚠SPOFSSL*
$Servidor WebAplicación✓⚠SENCILLO❌✓ PUEDE LLEVARTE LEJOSTERMINA SIENDO POCOSPOF$Base de datos⚠SPOFx2SSL*
$Servidor WebAplicación⚠SPOF$Base de datos⚠SPOF$Servidor WebAplicación⚠SPOFDNS ROUND ROBIN:(SSL* SSL*
$Servidor WebAplicación⚠SPOF$Base de datos⚠SPOF$Servidor WebAplicación⚠SPOFDNS ROUND ROBIN:(SSL* SSL*
$Servidor WebHAProxy⚠SPOF$Base de datos⚠SPOF⚠SPOF$Servidor WebAplicación⚠SPOF$Servidor WebAplicaciónSSL*
$Servidor WebHAProxy⚠SPOF$Base de datos⚠SPOF$Servidor WebAplicación$Servidor WebAplicaciónSSL*
$Servidor WebHAProxy⚠SPOF$Base de datos⚠SPOF$Servidor WebAplicación$Servidor WebAplicaciónSSL*????Host $host;X-Real-IP $re...
HAProxy4.2Balanceador TCP/HTTPEs uno de los balanceadores de carga más utilizados. Se caracteriza por sermuy eficiente tant...
globallog 127.0.0.1 local0 noticemaxconn 4096user haproxygroup haproxydefaultslog globalmode httpoption httplogoption dont...
Demo HAProxy4A
$Servidor WebHAProxy⚠SPOF$Base de datos⚠SPOF$Servidor WebAplicación$Servidor WebAplicaciónSSL*
High availability4.3Load BalancernginxhaproxyWeb #1nginxappWeb #2nginxappWeb #3nginxapp⏶Web #1 33%Web #2 33%Web #3 33%✓✓✓4...
High availability4.3Web #1nginxappWeb #2nginxappWeb #3nginxapp⏶Web #1 50%Web #2 50%Web #3 0%✓⚠✓4upexample.com⚠Load Balance...
High availability4.3Web #1nginxappWeb #2nginxappWeb #3nginxapp⏶Web #1 100%Web #2 0%Web #3 0%✓⚠⚠4upexample.com⚠⚠Load Balanc...
Load BalancernginxhaproxyHigh availability4.3Web #1nginxappWeb #2nginxappWeb #3nginxapp⏶Web #1 33%Web #2 33%Web #3 33%✓✓✓5...
:(
DNS$example.com$$$$$$Datacenter66666666$176.58.97.9
DNS$example.com176.58.97.9$$$$$$Datacenter66666666$176.58.97.9
$6DNS$example.com176.58.97.9176.58.97.9$$$$$$????Datacenter6666666
$6DNS$example.com176.58.97.9176.58.97.9$$$$$$????Datacenter6666666SPOF: Single Point Of Failure
High availability4.3ProblemaNecesitamos hacer que nuestro balanceador no sea un unSPOF, Single point of failure.• En caso ...
$6$$$$$$#1Datacenter6666666$176.58.97.9#2
$6$$$$$$#1Datacenter6666666$176.58.97.9#2
$6$$$$$$#1Datacenter6666666$176.58.97.9#2
Heartbeat♥ Pacemaker8+
Heartbeat♥ Capa de comunicaciónBásicamente es un “bus” que nosasegura que todos los mensajesenviados se envían a todos los...
Pacemaker8 AgenteSe encarga de arrancar y parar serviciosen función de reglas que nosotrosestablezcamos. De igual manera, ...
Configuración$ cat /etc/ha.d/ha.cfkeepalive 2deadtime 15warntime 5initdead 120udpport 694ucast eth0 123.123.123.123auto_fai...
Configuración$ cat /etc/heartbeat/authkeysauth 11 sha1 SECRET$ chmod 600 /etc/heartbeat/authkeysHeartbeat4.3Hemos de configu...
Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yy...
Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yy...
Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yy...
Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yy...
Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yy...
Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yy...
Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yy...
$Servidor WebHAProxy$Base de datos⚠SPOF$Servidor WebAplicación$Servidor WebAplicaciónSSL*$Servidor WebHAProxySSL*
$Servidor WebHAProxy$Base de datos⚠SPOF$Servidor WebAplicación$Servidor WebAplicaciónSSL*$Servidor WebHAProxySSL*$Servidor...
$Servidor WebHAProxy$Base de datosMaster$Servidor WebAplicación$Servidor WebAplicaciónSSL*$Servidor WebHAProxySSL*$Servido...
$Servidor WebHAProxy$Base de datosMaster$Servidor WebAplicación$Servidor WebAplicaciónSSL*$Servidor WebHAProxySSL*$Servido...
Y aún más lejos?Llegados a este punto deberíamos de tenera varias personas trabajando en esto atiempo completo... pero el ...
$Servidor WebHAProxySSL*$Servidor WebHAProxySSL*DNS ROUND ROBIN$Servidor WebHAProxySSL*$Servidor WebHAProxySSL*$Servidor W...
Servidores Web4.4¿Cuál elijo?Existen docenas de servidores web, cada empresa suele elegir uno enfunción de las necesidades...
Spoon feeding?
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6UsuarioADSL6Usuario3G6UsuarioEDGE6UsuarioGPRSnginxLAN;INTERNET;1G...
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6UsuarioADSL6Usuario3G6UsuarioEDGE6UsuarioGPRSnginxLAN;INTERNET;1G...
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6UsuarioADSL6Usuario3G6UsuarioEDGE6UsuarioGPRSnginxLAN;INTERNET;1G...
$Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6UsuarioADSL6Usuario3G6UsuarioEDGE6UsuarioGPRSnginxLAN;INTERNET;1G...
✉EmailsLa mayoría de los servicios onlinenecesitan enviar emails a sus usuarios.El número de emails que has de enviarcrece...
Amazon SES4.4¿Qué es Amazon SES?Servicio cloud de Amazon que nos permite enviar grandes cantidades de emailssin tener que ...
dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
Deploy5
https://github.com/blog/1241-deploying-at-githubDeploying is a big part of the lives of most GitHub employees. Wedont have...
$$$ $$$ $ $$ $ $ $server #1server #3server #11 server #12server #2server #4 server #5 server #6server #7 server #8 server ...
$$$ $$$ $ $$ $ $ $server #1Bserver #3Bserver #11B server #12Bserver #2Bserver #4B server #5B server #6Bserver #7B server #...
$$$ $$$ $ $$ $ $ $server #1Bserver #3Bserver #11B server #12Bserver #2Bserver #4B server #5B server #6Bserver #7B server #...
Streamlining SSH scriptsfabricfrom fabric.api import rundef host_type():run(uname -s)fabfile.py$ fab -H localhost,linuxbox...
Streamlining SSH scriptsfabricget(remote_path, local_path=None)put(local_path=None, remote_path=None, ...)run(command, ......
Hostsfabric@hosts(varnish.example.com)def purge_varnish():"""Purge varnish cache"""sudo(varnishadm -T 127.0.0.1:6082 ban.u...
Agrupación de hosts en rolesfabricenv.roledefs = {test: [test-web-1.example.com, test-web-2.example.com],test-db: [test-db...
Helpers de interacciónfabricconfirm(question, default=True)abort(msg)error(message, func=None, exception=None, stdout=None...
dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
Seguridad6
La seguridad es un tema extenso y delicado.Os invitamos a profundizar en cada uno de losaspectos antes de ponerlos en prác...
*iptablesNo lo son todo, pero sin lugar a dudasson un buen comienzo para evitarnosproblemas.
Funcionamiento iptablesINPUT TRAFFICFILTERNATMANGLEPREROUTINGPREROUTINGFORWARDFORWARDPOSTROUTINGPOSTROUTINGINPUTINPUTLOCAL...
Funcionamiento iptablesINPUT TRAFFICFILTERNATMANGLEPREROUTINGPREROUTINGFORWARDFORWARDPOSTROUTINGPOSTROUTINGINPUTINPUTLOCAL...
Funcionamiento iptablesINPUT TRAFFICFILTERNATMANGLEPREROUTINGPREROUTINGFORWARDFORWARDPOSTROUTINGPOSTROUTINGINPUTINPUTLOCAL...
Tablas predefinidas>;FILTER.NAT.MANGLE.Tabla responsable del filtrado de paquetes.Todos los paquetes pasan por esta tabla.T...
Tablas predefinidas>;FILTER.NAT.MANGLE.Tabla responsable del filtrado de paquetes.Todos los paquetes pasan por esta tabla.T...
>FILTER.Tabla responsable del filtrado de paquetes.☰INPUT☰OUTPUT☰FORWARDTodos los paquetes destinados a este sistema atravi...
>FILTER.Tabla responsable del filtrado de paquetes.☰INPUT☰OUTPUT☰FORWARDTodos los paquetes destinados a este sistema atravi...
>FILTER:INPUTCadena responsable del filtrado de paquetes de entrada.*filter:INPUT DROP [0:0]:OUTPUT ACCEPT [0:0]:FORWARD DR...
fail2ban6.2Fail2ban nos permite bloquear ataques de fuerza bruta contra servicioscomo ssh, mail, http etc...• Muy sencillo...
SSH root@...6.3Desactivar la cuenta de root es una de las primeras medidas a tomar alconfigurar un servidor.• Si disponemos...
dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
Monitoring7
You can’t improvewhat you don’t measure“”
top7.1
htop7.2
munin7.3Ventajas• Muy sencillo de instalar y configurar.• Fácil de crear nuevas gráficas usandocualquier lenguaje de scripti...
but... What’s next?Llegado el momento las métricas seconvierten en críticas para analizar nosolo la salud del sistema, si ...
graphite7.4!h#p://graphite.wikidot.com
graphite servergraphitetcp 80☁
graphite server!carbongraphitetcp 80☁
graphite serverdb server!carbongraphitetcp 80☁
graphite serverdb server!carbongraphitediamondtcp 80☁
graphite serverdb server!carbongraphitediamondstatsdudp 8125tcp 80☁
graphite serverdb server!carbongraphitetcp 2003diamondstatsdudp 8125tcp 80☁
graphite serverweb server db server!carbongraphitetcp 2003diamondstatsdudp 8125diamond statsdudp 8125diamondstatsdudp 8125...
graphite serverweb server db server!carbongraphitetcp 2003diamondstatsdudp 8125diamond statsdudp 8125diamondstatsdudp 8125...
graphite serverweb server db server!carbongraphitetcp 2003diamondstatsdudp 8125diamond statsdudp 8125diamondstatsdudp 8125...
graphite7.4No sólo datos... conocimiento!Descubrir que la carga de un servidor es 9.3 lo fines de semana a las 3am es útilp...
graphite7.4from pystatsd import Clientsc = Client(127.0.0.1, 8125)sc.increment(streetlife.emails.immediate.sent)Pythonecho...
sentry7.5!h#p://getsentry.comh#ps://github.com/getsentry/sentryOpen Source SAAS
pingdom7.6Yo mi me conmigo...Es muy embarazoso darse cuenta que tu web se ha caído porque te lo diga uncliente. Hay docena...
dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
Provisioning8
$server #1$ ssh user1@server1$ apt-get install paquete_x
$server #1$ ssh user1@server1$ apt-get install paquete_x$server #2$ ssh user2@server2$ apt-get install paquete_x
$server #1$ ssh user1@server1$ apt-get install paquete_x$server #2$ ssh user2@server2$ apt-get install paquete_x$server #3...
$ ssh user1@server1$ apt-get install paquete_x$server #1$server #2$server #3$server #4$ ssh user1@server1$ apt-get install...
$ ssh user1@server1$ apt-get install paquete_x$server #1$server #2$server #3$server #4$ ssh user1@server1$ apt-get install...
$ ssh user1@server1$ apt-get install paquete_x$server #1$server #2$server #3$server #4$ ssh user1@server1$ apt-get install...
$$$ $$$$$$$$$$ $server #1server #3server #11 server #12server #2server #4 server #5 server #6server #7 server #8 server #9...
$$$ $$$ $ $$ $ $ $server #1server #3server #11 server #12server #2server #4 server #5 server #6server #7 server #8 server ...
$$$ $$$ $ $$ $ $ $server #1server #3server #11 server #12server #2server #4 server #5 server #6server #7 server #8 server ...
Shit hapens happens... a lot.⚠Repetition leads to boredom,boredom to horrifying mistakes,horrifying mistakes to God-I-wish...
Provisioning8.1Automatizar la configuración y mantenimiento de tantos servidores cómo necesitemos.• Generar plantillas que ...
Puppet8.2Puppet es junto a Chef uno de los más utilizados.• Nos permite automatizar la configuración deservidores UNIX y Wi...
Puppet8.2Una de las principales características de Puppetfrente a otros sistemas de configuración es quees idempotente. Por...
packagepackage { nginx:ensure => installed,}presentlatest1.5.3absent
packagepackage { nginx:ensure => installed,}presentlatest1.5.3absent
filefile { /etc/nginx/nginx.conf:source => modules/nginx/nginx.conf,owner => root,group => root,mode => 640,require => Pac...
filefile { /etc/nginx/nginx.conf:source => modules/nginx/nginx.conf,owner => root,group => root,mode => 640,require => Pac...
serviceservice { nginx:ensure => running,enable => true,hasstatus => true,hasrestart => true,}
require, notifyPackage[nginx]File[/etc/nginx/nginx.conf]Service[nginx]InstalledCreated Updated
user, groupuser { tom:ensure => present,shell => /bin/bash,home => /home/tom,managehome => true,}group { friends:ensure =>...
nodesnode web.example.com inherits web_node {include munininclude pythonuser { tom:ensure => present,shell => /bin/bash,ho...
apply$ puppet apply puppet/manifests/site.pp
dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
Herramientas9
Características• Wrapper de virtualbox para crear y destruir máquinas desde lalinea de comandos.• Permite crear “instancia...
Añadir un boxVagrant9.1$ vagrant box add ubuntu-precise http://bit.ly/ubuntu-preciseCrear una nueva instancia$ vagrant ini...
Vagrant::Config.run do |config|config.vm.define :web do |web|web.vm.box = "ubuntu-precise-64"web.vm.box_url = "http://bit....
$ vagrant up web[web] VM already created. Booting if its not already running...[web] Clearing any previously set forwarded...
Git branch model9.2http://nvie.com/posts/a-successful-git-branching-model/1
CSS Preprocessors9.3
Chrome Plugins9.4Hay docenas de plugins que pueden hacer nuestro día a día muchomás sencillo. Estos son algunos de los que...
User-Agent switcher9.4Cambiar de User-Agent con dos clicksPodemos configurar nuestrospropios User-Agent.
Resolution test9.4Cambiar el tamaño de la ventana con dos clicks
Cache Killer9.4Mientras esté activo no se utilizará la cache del navegador.
Speed tracer9.4
dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
Buenas prácticas10
CI: Jenkins10.2CaracterísticasServicio que nos permite automatizar (entreotras cosas) la ejecución de tests,compilación de...
Hipchat/IRC10.3La comunicación entre los empleados es muyimportante (sobre todo cuando no siempre todo elmundo está trabaj...
Questions?
Recursoshttp://www.flickr.com/photos/marceldouwedekker/http://pygments.org/http://entypo.com/Fuenteshttp://net.tutsplus.com...
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Open Source Modern Web Development
Upcoming SlideShare
Loading in …5
×

Open Source Modern Web Development

778 views

Published on

0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
778
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
24
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Open Source Modern Web Development

  1. 1. Jorge&Bas*dame@jorgebas*da.com@jorgebas*daJaime&Irurzunjaime@irurzun.com@jaimeirurzunOpen SourceModern web development
  2. 2. env environmentOpen source modernweb development!⚒#dev developmentops operations
  3. 3. dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
  4. 4. dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
  5. 5. Browser1
  6. 6. renderizaejecutahablaBrowserMás que un terminal tonto,pero no tanto másHTML + CSSJavaScriptHTTP (+DNS)
  7. 7. HTML + CSSJavaScriptHTTP (+DNS)BrowserMás que un terminal tonto,pero no tanto másfrontendbackend
  8. 8. renderiza HTML + CSS<html><head><title>Example</title><link rel="stylesheet"type="text/css"href="example.css"></head><body><h1>Title</h1><p>This is <strong>important</strong>.</p></body></html>body { font-family: Arial; }strong { color: red; }+ =example.htmlexample.css
  9. 9. ejecuta JavaScript<html>...<body><h1>Title</h1>...<script type="text/javascript"src="example.js"></script></body></html>document.getElementsByTagName(h1)[0].onclick = function() {alert("Youve clicked!");};+ =example.htmlexample.js
  10. 10. ¿qué ocurrepor detrás?habla HTTP (+DNS)
  11. 11. Escribes una URL en el navegador1Se hace una petición DNSpara traducir el hostname dela URL a su dirección IP2Se hace una petición HTTP a esa IP pidiendo el recurso / y serecibe el resultado, normalmente un fichero .html3www.wikipedia.org91.198.174.22591.198.174.225GET / HTTP/1.1...HTTP/1.1 200 OK...$#
  12. 12. El navegador comienza a renderizar el HTML y hace máspeticiones [DNS+] HTTP para cada recurso (css, img, js, etc)que encuentre referenciado en el código (src=..., href=...)4<div class="central-featured-logo-inner"><img src="//upload.wikimedia.org/wikipedia/commons/Wikipedia-logo.png"></div>A partir de aquí, y hasta la próxima petición HTTP que fuerceuna recarga completa de la página, todo lo que puede ocurrirson efectos CSS y código JavaScript.5Desde JavaScript podemos hacer peticiones HTTP asíncronas(AJAX) que fuercen acciones en el servidor y como resultadorealicen cambios en el DOM de la página.Y esto es todo.
  13. 13. El navegador comienza a renderizar el HTML y hace máspeticiones [DNS+] HTTP para cada recurso (css, img, js, etc)que encuentre referenciado en el código (src=..., href=...)4<div class="central-featured-logo-inner"><img src="//upload.wikimedia.org/wikipedia/commons/Wikipedia-logo.png"></div>A partir de aquí, y hasta la próxima petición HTTP que fuerceuna recarga completa de la página, todo lo que puede ocurrirson efectos CSS y código JavaScript.5Desde JavaScript podemos hacer peticiones HTTP asíncronas(AJAX) que fuercen acciones en el servidor y como resultadorealicen cambios en el DOM de la página.Y esto es todo.
  14. 14. HTTP es el idioma de la weby hay que conocerlo
  15. 15. dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
  16. 16. HTTP2
  17. 17. físicoenlace de datosredtransportesesiónpresentaciónaplicaciónModelo OSIHardwareAcceso al medio (MAC)Enrutamiento entre redesTransmisión fiable del mensajeDiálogoCodificación, cifrado, compresión...Contenido del mensaje
  18. 18. acceso al medioredtransporteaplicaciónTCP/IPfísicoenlace de datosredtransportesesiónpresentaciónaplicaciónModelo OSIhttp, ftp,smtp, pop,imap, ssh,irc, ...TCP, UDPIPethernet,token ring,fddi, ...
  19. 19. HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <descripción><cabeceras><cuerpo>PeticiónRespuesta$#
  20. 20. HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <descripción><cabeceras><cuerpo>RespuestaPetición$#
  21. 21. HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <descripción><cabeceras><cuerpo>PeticiónRespuesta$#
  22. 22. Un recurso se identifica mediante una URL<OPERACIÓN> <recurso> HTTP/1.1protocol://[user:pass@]host[:port][/resource]en http, por defecto:user = pass =port = 80resource = /http://www.wikipedia.org:80/
  23. 23. <OPERACIÓN> <recurso> HTTP/1.1Las URLs son parte fundamentaldel diseño de una aplicación webhttp://www.wordpress.org/http://www.wordpress.org/about/http://www.wordpress.org/support/http://www.wordpress.org/extend/themes/http://www.wordpress.org/extend/themes/montezuma...
  24. 24. HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <descripción><cabeceras><cuerpo>PeticiónRespuesta$#
  25. 25. GET Obtiene un recurso. No debería producir cambios.POSTPUTCrea un recurso.Reemplaza o crea un recurso.DELETE Elimina un recurso.<OPERACIÓN> <recurso> HTTP/1.1HEAD Como GET, pero pide sólo las cabeceras.TRACE Diagnóstico.OPTIONS Pregunta por los métodos que soporta el servidor.CONNECT Diagnóstico.
  26. 26. <OPERACIÓN> <recurso> HTTP/1.1REST es un enfoque de diseño de APIs que,entre otras cosas, explota la pureza de estos conceptoshttp://example.com/recetas/http://example.com/recetas/453PUTGETPOSTDELETEPUTGETPOSTDELETELista las URIs de recetas y quizá otros detalles.Reemplaza la colección de recetas por una nueva.Inserta una nueva receta y devuelve su URI.Borra la colección de recetas.Devuelve el detalle de una receta.Reemplaza o crea (si no existe) una receta.---Borra una receta.
  27. 27. +La navaja suiza de las URLscURL
  28. 28. La navaja suiza de las URLs$ curl example.com/recetas$ curl -XGET example.com/recetas$ curl -XPOST example.com/recetas$ curl -XPUT example.com/recetas$ curl -XDELETE example.com/recetascURL
  29. 29. La navaja suiza de las URLs$ curl example.com/recetas$ curl -XGET example.com/recetas$ curl -XPOST example.com/recetas$ curl -XPUT example.com/recetas$ curl -XDELETE example.com/recetascURL
  30. 30. $ curl -X GET google.com<HTML><HEAD><meta http-equiv="content-type"content="text/html;charset=utf-8"><TITLE>301 Moved</TITLE></HEAD><BODY><H1>301 Moved</H1>The document has moved<A HREF="http://www.google.com/">here</A>.</BODY></HTML>cURLLa navaja suiza de las URLs
  31. 31. HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <descripción><cabeceras><cuerpo>PeticiónRespuesta$#
  32. 32. <cabeceras>Son parejas Clave: valor que transmiten alservidor información acerca de la requestAccept: text/plainAccept-Charset: utf-8Accept-Encoding: gzip, deflateAccept-Language: en-USAccept-Datetime: Thu, 31 May 2007 20:35:00 GMTAuthorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==Cache-Control: no-cacheConnection: keep-aliveCookie: $Version=1; Skin=new;Content-Length: 348
  33. 33. <cabeceras>Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==Content-Type: application/x-www-form-urlencodedDate: Tue, 15 Nov 1994 08:12:31 GMTExpect: 100-continueFrom: user@example.comHost: en.wikipedia.org:80If-Match: "737060cd8c284d8af7ad3082f209582d"If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMTIf-None-Match: "737060cd8c284d8af7ad3082f209582d"If-Range: "737060cd8c284d8af7ad3082f209582d"If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
  34. 34. <cabeceras>Max-Forwards: 10Origin: http://www.example-social-network.comPragma: no-cacheProxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==Range: bytes=500-999Referer: http://en.wikipedia.org/wiki/Main_PageTE: trailers, deflateUpgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, ...User-Agent: Mozilla/5.0 (X11; Linux x86_64; ...Via: 1.0 fred, 1.1 example.com (Apache/1.1)Warning: 199 Miscellaneous warningX-<YYY>: ZZZ
  35. 35. cURL:ver cabeceras$ curl -v -X GET google.com* About to connect() to google.com port 80 (#0)* Trying 173.194.41.8...* connected* Connected to google.com (173.194.41.8) port 80 (#0)> GET / HTTP/1.1> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5> Host: google.com> Accept: */*>< HTTP/1.1 301 Moved Permanently< Location: http://www.google.com/< Content-Type: text/html; charset=UTF-8< Date: Mon, 06 May 2013 08:03:50 GMT< Expires: Wed, 05 Jun 2013 08:03:50 GMT< Cache-Control: public, max-age=2592000< Server: gws< Content-Length: 219< X-XSS-Protection: 1; mode=block< X-Frame-Options: SAMEORIGIN<<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"><TITLE>301 Moved</TITLE></HEAD><BODY><H1>301 Moved</H1>The document has moved<A HREF="http://www.google.com/">here</A>.</BODY></HTML>* Connection #0 to host google.com left intact* Closing connection #0
  36. 36. cURL:enviar cabeceras$ curl -v -X GET google.com -H User-Agent: Mozilla/5.0* About to connect() to google.com port 80 (#0)* Trying 173.194.41.232...* connected* Connected to google.com (173.194.41.232) port 80 (#0)> GET / HTTP/1.1> Host: google.com> Accept: */*> User-Agent: Mozilla/5.0>< HTTP/1.1 301 Moved Permanently< Location: http://www.google.com/< Content-Type: text/html; charset=UTF-8< Date: Mon, 06 May 2013 08:16:10 GMT< Expires: Wed, 05 Jun 2013 08:16:10 GMT< Cache-Control: public, max-age=2592000< Server: gws< Content-Length: 219< X-XSS-Protection: 1; mode=block< X-Frame-Options: SAMEORIGIN<<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"><TITLE>301 Moved</TITLE></HEAD><BODY><H1>301 Moved</H1>The document has moved<A HREF="http://www.google.com/">here</A>.</BODY></HTML>* Connection #0 to host google.com left intact* Closing connection #0
  37. 37. HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <descripción><cabeceras><cuerpo>PeticiónRespuesta$#
  38. 38. <cuerpo>Content-Type: application/jsonapplication/pdfapplication/x-www-form-urlencodedmultipart/form-dataimage/jpegtext/plainvideo/mpeg...Tiene sentido en peticiones PUT y POST.Su formato lo define la cabecera Content-Type:
  39. 39. <cuerpo>POST /blog/posts HTTP/1.1Accept: application/jsonContent-Type: application/jsonContent-Length: 57Host: www.example.com:80{"title":"Hello!","body":"This is my first post!"}POST /blog/posts HTTP/1.1Accept: */*Content-Type: application/x-www-form-urlencodedContent-Length: 47Host: www.example.com:80title=Hello%21&body=This+is+my+first+post%21
  40. 40. <cuerpo>POST /blog/posts HTTP/1.1Accept: text/html, application/xhtml+xml, */*Content-Type: multipart/form-data; boundary=AaB03xContent-Length: 240Host: www.example.com:80--AaB03xContent-Disposition: form-data; name="name"Larry--AaB03xContent-Disposition: form-data; name="files"Content-Type: multipart/mixed; boundary=BbC04y--BbC04yContent-Disposition: file; filename="file1.txt"Content-Type: text/plain... contents of file1.txt ...--BbC04yContent-Disposition: file; filename="file2.gif"Content-Type: image/gifContent-Transfer-Encoding: binary...contents of file2.gif...--BbC04y----AaB03x--
  41. 41. cURL:cuerpo de una petición$ curl -v -X POST localhost:8000/jugadores/ -d "username=pablo"* About to connect() to localhost port 8000 (#0)* Trying ::1...* Connection refused* Trying 127.0.0.1...* connected* Connected to localhost (127.0.0.1) port 8000 (#0)> POST /jugadores/ HTTP/1.1> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5> Host: localhost:8000> Accept: */*> Content-Length: 14> Content-Type: application/x-www-form-urlencoded>* upload completely sent off: 14 out of 14 bytes* HTTP 1.0, assume close after body< HTTP/1.0 200 OK< Date: Mon, 06 May 2013 07:48:08 GMT< Server: WSGIServer/0.1 Python/2.7.2< Content-Type: text/html; charset=utf-8<......* Closing connection #0
  42. 42. HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <descripción><cabeceras><cuerpo>PeticiónRespuesta$#
  43. 43. HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <descripción><cabeceras><cuerpo>PeticiónRespuesta$#
  44. 44. HTTP/1.1 <código> <descripción>200 OK201 Created202 Accepted203 Non-Authoritative Information204 No Content205 Reset Content206 Partial Content✓ℹ1XX Informational2XX Success100 Continue101 Switching Protocols300 Multiple Choices301 Moved Permanently302 Found303 See Other304 Not Modified305 Use Proxy306 (Unused)307 Temporary Redirect3XX Redirection
  45. 45. HTTP/1.1 <código> <descripción>#4XX Client Error400 Bad Request401 Unauthorized402 Payment Required403 Forbidden404 Not Found405 Method Not Allowed406 Not Acceptable407 Proxy Authentication Required408 Request Timeout409 Conflict410 Gone411 Length Required412 Precondition Failed413 Request Entity Too Large414 Request-URI Too Long415 Unsupported Media Type416 Requested Range Not Satisfiable417 Expectation Failed500 Internal Server Error501 Not Implemented502 Bad Gateway503 Service Unavailable504 Gateway Timeout505 HTTP Version NotSupported5XX Server Error$
  46. 46. HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <descripción><cabeceras><cuerpo>PeticiónRespuesta$#
  47. 47. <cabeceras>Access-Control-Allow-Origin: *Accept-Ranges: bytesAge: 12Allow: GET, HEADCache-Control: max-age=3600Connection: closeContent-Encoding: gzipContent-Language: enContent-Length: 348Content-Location: /index.htmlContent-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==Content-Disposition: attachment; filename="f.txt"
  48. 48. <cabeceras>Content-Range: bytes 21010-47021/47022Content-Type: text/html; charset=utf-8Date: Tue, 15 Nov 1994 08:12:31 GMTETag: "737060cd8c284d8af7ad3082f209582d"Expires: Thu, 01 Dec 1994 16:00:00 GMTLast-Modified: Tue, 15 Nov 1994 12:45:26 GMTLink: </feed>; rel="alternate"[25]Location: http://www.w3.org/pub/WWW/People.htmlP3P: CP="This is not a P3P policy! See..."Pragma: no-cacheProxy-Authenticate: BasicRefresh: 5; url=http://...
  49. 49. <cabeceras>Retry-After: 120Server: Apache/2.4.1 (Unix)Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1Status: 200 OKStrict-Transport-Security: max-age=16070; includeSubDomainsTrailer: Max-ForwardsTransfer-Encoding: chunkedVary: *Via: 1.0 fred, 1.1 example.com (Apache/1.1)Warning: 199 Miscellaneous warningWWW-Authenticate: BasicX-<YYY>: ZZZ
  50. 50. HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <descripción><cabeceras><cuerpo>PeticiónRespuesta$#
  51. 51. <cuerpo>HTTP/1.1 200 OKContent-Type: text/htmlDate: Thu, 31 May 2007 20:35:00 GMT<html><head><title>Web page</title></head><body><h1>Hello world</h1></body></html>
  52. 52. HTTPProtocolo de manipulación de recursos, sin estado<OPERACIÓN> <recurso> HTTP/1.1<cabeceras><cuerpo>HTTP/1.1 <código> <descripción><cabeceras><cuerpo>PeticiónRespuesta$#
  53. 53. HTTP/1.1 200 OKContent-Type: text/htmlDate: Thu, 31 May 2007 20:35:00 GMT<html><body><h1>Hello world</h1></body></html>HTTP/1.1 304 Not ModifiedDate: Thu, 06 Jun 2007 19:40:00 GMTHTTP Imprescindible
  54. 54. HTTP/1.1 301 Moved PermanentlyLocation: http://www.example.com/new/url/HTTP/1.1 302 FoundLocation: http://www.example.com/other/url/HTTP/1.1 303 See OtherLocation: http://www.example.com/other/url/HTTP/1.1 307 Temporary RedirectLocation: http://www.example.com/other/url/http 1.0http 1.1GETXXXGETXXXHTTP Imprescindible
  55. 55. HTTP/1.1 400 Bad RequestHTTP/1.1 401 UnauthorizedWWW-Authenticate: Basic realm="..."HTTP/1.1 403 ForbiddenHTTP/1.1 404 Not FoundHTTP/1.1 405 Method Not AllowedHTTP/1.1 410 GoneHTTP Imprescindible
  56. 56. HTTP/1.1 500 Internal Server ErrorHTTP/1.1 501 Not ImplementedHTTP/1.1 502 Bad GatewayHTTP/1.1 503 Service UnavailableHTTP Imprescindible
  57. 57. CookiesSolucionan la falta de estado del protocolo HTTP$#$#Son simples strings que se almacenan en el navegadorGET / HTTP/1.1...GET / HTTP/1.1Cookie: sessionid=xxxHTTP/1.1 200 OKSet-Cookie: sessionid=xxxHTTP/1.1 200 OK...Cliente Servidor
  58. 58. CookiesSet-Cookie: sessionid=xxx; Domain=docs.foo.com; Path=/accounts;Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnlyEn qué requests debería enviarse como Cookie:Domain + PathExpires Cuándo el User-Agent debería borrar la cookieSecure Sólo debe enviarse si el tráfico es httpsHttpOnly Sólo accessible desde HTTP, no desde JavaScriptXSS!⚠document.cookie = ...
  59. 59. CookiesSet-Cookie: sessionid=xxx; Domain=docs.foo.com; Path=/accounts;Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnlyEn qué requests debería enviarse como Cookie:Domain + PathExpires Cuándo el User-Agent debería borrar la cookieSecure Sólo debe enviarse si el tráfico es httpsHttpOnly Sólo accessible desde HTTP, no desde JavaScriptXSS!⚠document.cookie = ...
  60. 60. Método sencillo para proveer de autenticación a peticionesHTTP, sin necesidad de cookies$# GET / HTTP/1.1...Cliente ServidorHTTP/1.1 401 UnauthorizedWWW-Authenticate: Basic realm="Login"Basic HTTP auth
  61. 61. Basic HTTP authMétodo sencillo para proveer de autenticación a peticionesHTTP, sin necesidad de cookies$# GET / HTTP/1.1...Cliente ServidorHTTP/1.1 401 UnauthorizedWWW-Authenticate: Basic realm="Login"$# GET / HTTP/1.1Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==HTTP/1.1 200 OK...base64(username:password) HTTPS!⚠
  62. 62. cURL:Basic HTTP auth$ curl -v -X GET localhost:8000/ --user pablo:x6f8* About to connect() to localhost port 8000 (#0)* Trying ::1...* Connection refused* Trying 127.0.0.1...* connected* Connected to localhost (127.0.0.1) port 8000 (#0)* Server auth using Basic with user pablo> GET / HTTP/1.1> Authorization: Basic cGFibG86eDZmOA==> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5> Host: localhost:8000> Accept: */*>* HTTP 1.0, assume close after body< HTTP/1.0 200 OK< Date: Mon, 06 May 2013 08:36:25 GMT< Server: WSGIServer/0.1 Python/2.7.2< Content-Type: text/html; charset=utf-8<Bienvenido a la mazmorra, espera instrucciones!* Closing connection #0
  63. 63. Ejercicio cURL: La guarida del dragón.$ curl -v -XPOST 10.172.104.175/jugadores/ -d "username=pablo")
  64. 64. dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
  65. 65. HTTPS*
  66. 66. acceso al medioredtransporteaplicaciónfísicoenlace de datosredtransportesesiónpresentaciónaplicación HTTPTLS/SSLHTTPS
  67. 67. HTTPS$# CertificadoPublic key (P)P(K)OkK = ...Clave simétrica compartida mediante algoritmo asimétricoK(mensaje)K(mensaje)Cliente Servidor+
  68. 68. Otras navajas suizastcpflow$ sudo tcpflow -i eth0 port 80 -CSniffer de tráfico TCP por excelencia en UNIXChrome inspector
  69. 69. dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
  70. 70. Optimización3
  71. 71. ClienteServidorCanalCachear, Delegar, Indexarvarnish, redis, cron, batch...Reducir request ( número y tamaño )Minify, sprites, gzip, cdn...Cachear + OptimizarCache, dns lookups, redirects, etags...Optimización3
  72. 72. ClienteServidorCanalCachear, Delegar, Indexarvarnish, redis, cron, batch...Reducir request ( número y tamaño )Minify, sprites, gzip, cdn...Cachear + OptimizarCache, dns lookups, redirects, etags...Optimización3
  73. 73. Servidor3.1
  74. 74. Cachear3.1.1ContenidoRequest ResponseVarnishRequest
  75. 75. 30m 10m no-cacheMemcached, redis etc...Contenido externo• APIs, RSS, TwitterContenido “Estático”• Últimas noticias• Nuevos usuarios• Últimos tweets• ...Cachear Contenido3.1.1
  76. 76. > GET last_tweets<h1>n<ul><li>Hello from....Memcached•Ventajas• Velocidad• Sencillez•Inconvenientes• Volátil: sólo reside en memoria.• Sólo entiende cadenas de texto.Cachear Contenido3.1.1
  77. 77. > INCR message:143:comments 14445Redis•Ventajas• Velocidad• Tipos de datos complejos• Operaciones atómicas•Inconvenientes• Muy pocas• Abuso = Problemas (como todo)Welcome to my site.4445 CommentsCachear Contenido3.1.1
  78. 78. Existen múltiples “puntos” donde cachear.•Servidor web• Intrusismo• Complejidad media•Código del proyecto “backend”• Sencillo de implementar• Poco eficiente•Proxy• Sencillo• Muy eficienteCachear Requests3.1.1
  79. 79. •Requests Anónimas• Digg effect• Landing page• Google•Contenido Estático• Assets• Thumbnails•APIs•“Hot Pages”Request ResponseVarnishServerMissHitCachear Requests3.1.1
  80. 80. Request* Versión muy simplificada del funcionamiento de VarnishVarnishVarnish3.1.1
  81. 81. Request vcl_recv()* Versión muy simplificada del funcionamiento de VarnishVarnishVarnish3.1.1
  82. 82. Request vcl_recv()lookup* Versión muy simplificada del funcionamiento de Varnishincache?VarnishVarnish3.1.1
  83. 83. Request vcl_recv()lookup* Versión muy simplificada del funcionamiento de Varnishincache?yesVarnishVarnish3.1.1
  84. 84. Request vcl_recv()lookup* Versión muy simplificada del funcionamiento de Varnishincache?Build ResponseyesVarnishVarnish3.1.1
  85. 85. Request vcl_recv()lookup* Versión muy simplificada del funcionamiento de Varnishincache?Build ResponseResponseyesVarnishVarnish3.1.1
  86. 86. Request vcl_recv()passlookup* Versión muy simplificada del funcionamiento de Varnishincache?noBuild ResponseResponseyesVarnishVarnish3.1.1
  87. 87. Request vcl_recv()Backendpasslookup* Versión muy simplificada del funcionamiento de Varnishincache?noBuild Responsevcl_fetch()Responseyes cache?VarnishVarnish3.1.1
  88. 88. Request vcl_recv()Backendpasslookup* Versión muy simplificada del funcionamiento de Varnishincache?noBuild Responsevcl_fetch()Responseyes cache?noVarnishVarnish3.1.1
  89. 89. Request vcl_recv()Backendpasslookup* Versión muy simplificada del funcionamiento de Varnishincache?noBuild Responsevcl_fetch()ResponseyesCachecache?yesnoVarnishVarnish3.1.1
  90. 90. sub vcl_recv {# Pass anything other than GET and HEAD directly.if (req.request != "GET" && req.request != "HEAD"){return(pass);}# Always lookup static files from the cache.# We dont need request cookies neither Authorization.if (req.request == "GET" && req.url ~ "^/static/") {unset req.http.cookie;unset req.http.Authorization;return(lookup);}# Remove any cookie we dont know about except `sessionid`.if (req.http.Cookie) {set req.http.Cookie = ";" + req.http.Cookie;set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");set req.http.Cookie = regsuball(req.http.Cookie, ";(sessionid)=", "; 1=");set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");if (req.http.Cookie == "") {# If there are no cookies, remove the header and lookup the cache.unset req.http.Cookie;return(lookup);}else {# If `sessionid` cookie is pressent pass the request to the backend.return (pass);}}}vcl_recv
  91. 91. sub vcl_fetch {# If the response status >= 400 dont cache it.if (beresp.status >= 400) {return (hit_for_pass);}# Remove cookies if this is a static request and set 1 week of ttl.if (req.url ~ "^/static/") {unset beresp.http.set-cookie;set beresp.ttl = 1w;return (deliver);}else{# If the response is setting any cookie, dont cache it.if (beresp.http.Set-Cookie) {return (hit_for_pass);}# Cache this response for 10 minutes.set beresp.ttl = 10m;return (deliver);}}vcl_fetch
  92. 92. Demo Varnish3A
  93. 93. Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5sDejar que alguien haga el trabajo sucio, antes o despuéscsv#
  94. 94. Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5s¿Cuánto del trabajo sucio es imprescindible al instante?csv#???
  95. 95. Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5s¿Cuánto del trabajo sucio es imprescindible al instante?csv# ?¿caché??
  96. 96. Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5s¿Cuánto del trabajo sucio es imprescindible al instante?csv# ?¿caché?¿tareaperiódica?
  97. 97. Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5s¿Cuánto del trabajo sucio es imprescindible al instante?csv#¿caché?¿tareaperiódica?¿cola demensajes?
  98. 98. Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5s¿Cuánto del trabajo sucio es imprescindible al instante?csv#¿caché?DelegarantesDelegardespués
  99. 99. Scheduler de trabajos de UNIXcron* * * * * <cmd>día de la semana (0 - 7)mes (1 - 12)día del mes (1 - 31)hora (0 - 23)minuto (0 - 59)# crontab -e$ crontab -e
  100. 100. Scheduler de trabajos de UNIX# crontab -l0 1 * * * /usr/sbin/ntpdate pool.ntp.org0 */2 * * * /home/root/bin/server-backup@reboot /home/root/bin/email-admins.shcron$ crontab -l*/5 * * * * /home/ops/bin/billing.sh@hourly /home/ops/bin/caches.py@daily /home/ops/bin/users-csv.py@weekly /home/ops/bin/spending-reports.sh
  101. 101. Delegar3.2$#Cliente Servidor500msbd!,smtp200ms5s¿Cuánto del trabajo sucio es imprescindible al instante?csv#¿caché?DelegarantesDelegardespués
  102. 102. Celery3.2Sistema de Tareas Asíncronas distribuidas.• Features: Colas, Concurrencia, Distribuido...• Pro: Muy fácil de implementar y escalable.• Casos prácticos:• Enviar un email (Notificationes, ...)• Calcular el karma de de los usuarios del sistema.• Tareas programadas (Limpieza, Post-procesado, etc...)• Regenerar caches etc..!h#p://celeryproject.org
  103. 103. Celery3.2El principal componente es el Broker. Se encarga de almacenar yentregar tareas a todos los workers.EstableExperimental
  104. 104. Celery+RabbitMQ3.2
  105. 105. Celery+RabbitMQ3.2
  106. 106. Funcionamiento3.2Server #1celery workercelery beatServer #3celery workerServer #4web nodeServer #5web nodeañadirprocesarprocesarañadirañadirServer #2celery workerprocesar
  107. 107. Funcionamiento3.2Server #1celery workercelery beatServer #3celery workerServer #4web nodeServer #5web nodeañadirprocesarprocesarañadirañadirServer #2celery workerprocesar
  108. 108. Funcionamiento3.2Server #1celery workercelery beatServer #3celery workerServer #4web nodeServer #5web nodeañadirprocesarprocesarañadirañadirServer #2celery workerprocesar
  109. 109. Funcionamiento3.2Conceptos clave:• Atómico: Las tareas se entregan solo a un worker.• Distribuido: Los nodos son independientes unos de otros y elnúmero puede aumentar y disminuir dinámicamente.• Fiable: Si no se informa a RabbitMQ sobre la finalización deuna tarea, esta vuelve a formar parte de la cola. En caso decatástrofe no perdemos tareas.• Rates: Celery nos permite definir rates para nos sobrecargar elsistema o APIs externas.• Tareas Periodicas: Celery beat registrará por nosotros tareas enla cola de la misma manera que lo haría cron.
  110. 110. Indexar3.3Preparar la información para acceder másrápido a ella en el momento de la consulta! DB Search-
  111. 111. !DB indexSELECT date(timestamp) as day, count(*)FROM stamp WHERE key=%s AND date(timestamp) > current_date - interval %sGROUP BY day ORDER BY day;BEGIN;DROP TABLE IF EXISTS "stamp";CREATE TABLE "stamp" ("key" varchar(255) NOT NULL,"timestamp" timestamp without time zone NOT NULL);COMMIT;con 4.221.883 registros, 11.488 segundos
  112. 112. BEGIN;DROP TABLE IF EXISTS "stamp";CREATE TABLE "stamp" ("key" varchar(255) NOT NULL,"timestamp" timestamp without time zone NOT NULL);CREATE INDEX "stamp_key_idx" ON stamp(key);COMMIT;SELECT date(timestamp) as day, count(*)FROM stamp WHERE key=%s AND date(timestamp) > current_date - interval %sGROUP BY day ORDER BY day;con 4.221.883 registros,!DB index11.488 segundos
  113. 113. BEGIN;DROP TABLE IF EXISTS "stamp";CREATE TABLE "stamp" ("key" varchar(255) NOT NULL,"timestamp" timestamp without time zone NOT NULL);CREATE INDEX "stamp_key_idx" ON stamp(key);COMMIT;SELECT date(timestamp) as day, count(*)FROM stamp WHERE key=%s AND date(timestamp) > current_date - interval %sGROUP BY day ORDER BY day;con 4.221.883 registros,!DB index11.4880.107segundos
  114. 114. Search index-$#Cliente Servidorbd!q=covent gardenSELECT * FROM messages WHERE subject like %covent garden% ORbody like %covent garden% ORauthor like %covent garden%;SELECT * FROM locations WHERE name like %covent garden% ORdescription like %covent garden%;SELECT * FROM pages WHERE name like %covent garden% ORdescription like %covent garden%;SELECT * FROM shareables WHERE name like %covent garden% ORdescription like %covent garden%;
  115. 115. Search index-$#Cliente Servidorbd!q=covent gardenSELECT * FROM messages WHERE subject like %covent garden% ORbody like %covent garden% ORauthor like %covent garden%;SELECT * FROM locations WHERE name like %covent garden% ORdescription like %covent garden%;SELECT * FROM pages WHERE name like %covent garden% ORdescription like %covent garden%;SELECT * FROM shareables WHERE name like %covent garden% ORdescription like %covent garden%;mmm... NO
  116. 116. Search index-$#Cliente Servidorbd!q=covent garden-searchengine.
  117. 117. Search index-$#Cliente Servidorbd!q=covent garden-searchengine.
  118. 118. Redis3.3.3Redis is an open source, BSD licensed,advanced key-value store. It is oftenreferred to as a data structure serversince keys can contain strings, hashes, lists,sets and sorted sets.“”hasheslists sets sorted setsstringspub/sub scripts
  119. 119. Enero 2012
  120. 120. Enero 2012~67%~23%150ms300ms
  121. 121. Memcached Feb 2012~86%~14%50ms300ms
  122. 122. Redis Feb 2013~99%~1%3 ms300ms
  123. 123. Redis como Indice3.1Problema:Mostrar avatares de 25 usuarios que compartan algún áreacontigo promocionando aquellos que no tengan uno de losavatares por defecto.CustomDefault
  124. 124. 3.1Solución: Sorted Sets1. Para cada area crear un sorted set con el id de todos los miembros.> ZADD area:1:followers 1 1area:1:followers 1Redis como Indice
  125. 125. 3.1Solución: Sorted Sets1. Para cada area crear un sorted set con el id de todos los miembros.> ZADD area:1:followers 1 1> ZADD area:1:followers 0 2area:1:followers 1 2Redis como Indice
  126. 126. 3.1Solución: Sorted Sets1. Para cada area crear un sorted set con el id de todos los miembros.> ZADD area:1:followers 1 1> ZADD area:1:followers 0 2> ZADD area:2:followers 1 1area:1:followers 1 2area:2:followers 1Redis como Indice
  127. 127. 3.1Solución: Sorted Sets1. Para cada area crear un sorted set con el id de todos los miembros.> ZADD area:1:followers 1 1> ZADD area:1:followers 0 2> ZADD area:2:followers 1 1> ZADD area:3:followers 0 4area:1:followers 1 2area:2:followers 1area:3:followers 4Redis como Indice
  128. 128. 3.1Solución: Sorted Sets1. Para cada area crear un sorted set con el id de todos los miembros.> ZADD area:1:followers 1 1> ZADD area:1:followers 0 2> ZADD area:2:followers 1 1> ZADD area:3:followers 0 4> ZADD area:3:followers 1 5area:1:followers 1 2area:2:followers 1area:3:followers 5 4Redis como Indice
  129. 129. 3.1Problema: ¿Usuarios que siguen el area #1?> GET area:1:followersarea:1:followers 1 2area:2:followers 1area:3:followers 5 4Redis como Indice
  130. 130. 3.1Problema: ¿Usuarios que siguen el area #1 o el area #2?> ZINTERSTORE areas:1-2:followers 2 area:1:followersarea:2:followers AGGREGATE MAX> GET areas:1-2:followersarea:2:followers 1area:3:followers 5 4areas:1-2:followersarea:1:followers 1 21 2Redis como Indice
  131. 131. 3.1Problema: 25 usuarios que sigan el area #1 o el area #2 promocionandoaquellos que tengan avatar.> ZREVRANGE areas:1-2:followers 0 25area:2:followers 1area:3:followers 5 4area:1:followers 1 2Redis como Indice
  132. 132. 3.1Problema: 25 usuarios que sigan el area #1 o el area #2 promocionandoaquellos que tengan avatar.> ZREVRANGE areas:1-2:followers 0 25area:2:followers 1area:3:followers 5 4areas:1-2:followersarea:1:followers 1 21 2Redis como Indice
  133. 133. ClienteServidorCanalCachear, Delegar, Indexarvarnish, redis, cron, batch...Reducir request ( número y tamaño )Minify, sprites, gzip, cdn...Cachear + OptimizarCache, dns lookups, redirects, etags...Optimización3
  134. 134. Canal3.2
  135. 135. Minimizar JS y CSSSL.Utils.flash = {init: function () {// Handle closing of flash messages$(#flashes .close, .flashes .close).live(click, function (e) {$(e.target).closest(li).slideUp(120, function () {// Cleanup after the last onevar container = $(this).closest(#flashes, .flashes),all_messages = container.find(li:visible);if (all_messages.length < 1) {container.remove();}});e.preventDefault();});}};SL.Utils.flash={init:function(){$("#flashes .close, .flashes .close").live("click",function(a){$(a.target).closest("li").slideUp(120,function(){var a=$(this).closest("#flashes, .flashes");1>a.find("li:visible").length&&a.remove()});a.preventDefault()})}};585 bytes255 bytes (~56%)Un paso más del proceso de build + deploy
  136. 136. --line-break--type js|css--charset character-set--disable-optimizations$ java -jar yuicompressor.jar file.js -o file-min.jshttps://github.com/yui/yuicompressor/Yahoo YUI compressorhttp://refresh-sf.com/yui/01
  137. 137. Sprites?
  138. 138. N 1
  139. 139. A.sprite-A{...}
  140. 140. A.sprite-A{background-image: url(sprite.png);...}
  141. 141. x:120pxy:50pxA.sprite-A{background-image: url(sprite.png);background-position: -120px -50px;...}
  142. 142. A.sprite-A{background-image: url(sprite.png);background-position: -120px -50px;width: 10px;height: 20px;...}20px10px
  143. 143. A<div class=”sprite-A”></div>
  144. 144. #1By hand
  145. 145. Rebuild sprites should can mustbe part of the assets-rebuild*for 99% of your sprites*“”
  146. 146. Glue$command-line-sprites$command-line-spritesgluecss.com
  147. 147. Drop source images somewhere
  148. 148. Drop source images somewhere$ glue source output
  149. 149. Drop source images somewhere$ glue source outputParty!
  150. 150. .sprite-icons-rainbow{background-image:url(sprite.png);background-repeat:no-repeat;background-position: 247px 147px;width: 25px;height: 25px;}...fam fam fam
  151. 151. .glyphicons-187-more{background-image:url(glyphicons.png);background-repeat:no-repeat;background-position: 212px 42px;width: 23px;height: 22px;}...glyphish
  152. 152. gzip3.2.2GET /index.htmlAccept-Encoding: gzipHTTP 1.1 200 OK<html><head> ...gzipServidorServidor sin gzip configuradoPese a que el navegador soporte gzip y envíe el headeradecuado en la petición, el servidor lo ignora y envía elcontenido sin comprimir.100Kb
  153. 153. GET /index.htmlAccept-Encoding: gzipServidor con gzip configuradoEstando gzip configurado en el servidor, si los clientesenvían los header adecuados, el servidor comprimirá larespuesta utilizando gzip.HTTP 1.1 200 OKContent-Encoding: gzipkk3s(e?3.sn2isn19fkjnasd...50Kbgzip3.2.2gzipServidor
  154. 154. A tener en cuenta•Navegadores MUY antiguos no soportan gzip. (~12 años)• Netscape <6• Internet Explorer <5.5 (Julio 2000)• Opera <5 (Enero 2000)• Firefox <0.9.5 (Octubre 2001)•Solo comprimir texto (html, xml, css, js...)• Imágenes, audio y video suelen estar comprimidosutilizando codecs más eficientes y resulta una perdida detiempo y cpu intentar recomprimirlos.•El 90% del tráfico de internet se genera utilizando navegadores quesoportan gzip (Yahoo!)gzip3.2.2
  155. 155. CDN: Content delivery network•Objetivos principales• Distribuir contenido de la manera más eficiente posible apoder ser desde localizaciones geográficamente cercanasal cliente para reducir la latencia.• Reducir tráfico de nuestros servidores web distribuyendo eltrafico a otros servidores.• Disminuir el coste.•Amazon S3• $0.095 por GB Almacenado.• $0.004 por cada 10.000 requests.• $0.120 por GB transferido•Distribuir un video de 50Mb a 100K personas (~5Tb)• $0 (Hosting) + $0.04 (requests) + $585 (transferencia)CDN3.2.3
  156. 156. ClienteServidorCanalCachear, Delegar, Indexarvarnish, redis, cron, batch...Reducir request ( número y tamaño )Minify, sprites, gzip, cdn...Cachear + OptimizarCache, dns lookups, redirects, etags...Optimización3
  157. 157. Cliente3.3
  158. 158. Speeding up your website1. CSS y JS en ficheros externos2. CSS al comienzo3. JS al final4. Entre 2 y 4 hostnameshttp://developer.yahoo.com/performance/rules.html1A single-user client SHOULD NOT maintain morethan 2 connections with any server or proxy.“
  159. 159. dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
  160. 160. Arquitectura4
  161. 161. $Servidor WebAplicaciónBase de datos✓⚠SENCILLO❌✓ OK PARA EMPEZARTERMINA SIENDO POCOSPOFSSL*
  162. 162. $Servidor WebAplicación✓⚠SENCILLO❌✓ PUEDE LLEVARTE LEJOSTERMINA SIENDO POCOSPOF$Base de datos⚠SPOFSSL*
  163. 163. $Servidor WebAplicación✓⚠SENCILLO❌✓ PUEDE LLEVARTE LEJOSTERMINA SIENDO POCOSPOF$Base de datos⚠SPOFx2SSL*
  164. 164. $Servidor WebAplicación⚠SPOF$Base de datos⚠SPOF$Servidor WebAplicación⚠SPOFDNS ROUND ROBIN:(SSL* SSL*
  165. 165. $Servidor WebAplicación⚠SPOF$Base de datos⚠SPOF$Servidor WebAplicación⚠SPOFDNS ROUND ROBIN:(SSL* SSL*
  166. 166. $Servidor WebHAProxy⚠SPOF$Base de datos⚠SPOF⚠SPOF$Servidor WebAplicación⚠SPOF$Servidor WebAplicaciónSSL*
  167. 167. $Servidor WebHAProxy⚠SPOF$Base de datos⚠SPOF$Servidor WebAplicación$Servidor WebAplicaciónSSL*
  168. 168. $Servidor WebHAProxy⚠SPOF$Base de datos⚠SPOF$Servidor WebAplicación$Servidor WebAplicaciónSSL*????Host $host;X-Real-IP $remote_addr;X-Forwarded-Proto $scheme;
  169. 169. HAProxy4.2Balanceador TCP/HTTPEs uno de los balanceadores de carga más utilizados. Se caracteriza por sermuy eficiente tanto en CPU como en RAM y es famoso por su estabilidad.• Permite balancear tanto tráfico TCP como a un más alto nivel tráfico HTTP.• Nos permite realizar health-check de los servidores backend.• Podemos activar y desactivar servidores manualmente.• Dispone de varios criterios para asignar servidores: Random, Round-robin,Least connection, source, uri, url-parameter etc...
  170. 170. globallog 127.0.0.1 local0 noticemaxconn 4096user haproxygroup haproxydefaultslog globalmode httpoption httplogoption dontlognulloption redispatchretries 3contimeout 5000clitimeout 50000srvtimeout 50000stats enablestats auth USER:PASSWORDbackend allserversmode httpserver web1 192.168.0.11:80 checkserver web2 192.168.0.12:80 checkserver web3 192.168.0.13:80 check...balance roundrobinoption httpchk HEAD /test/option forwardfor...haproxy.cfg
  171. 171. Demo HAProxy4A
  172. 172. $Servidor WebHAProxy⚠SPOF$Base de datos⚠SPOF$Servidor WebAplicación$Servidor WebAplicaciónSSL*
  173. 173. High availability4.3Load BalancernginxhaproxyWeb #1nginxappWeb #2nginxappWeb #3nginxapp⏶Web #1 33%Web #2 33%Web #3 33%✓✓✓4upexample.com
  174. 174. High availability4.3Web #1nginxappWeb #2nginxappWeb #3nginxapp⏶Web #1 50%Web #2 50%Web #3 0%✓⚠✓4upexample.com⚠Load Balancernginxhaproxy
  175. 175. High availability4.3Web #1nginxappWeb #2nginxappWeb #3nginxapp⏶Web #1 100%Web #2 0%Web #3 0%✓⚠⚠4upexample.com⚠⚠Load Balancernginxhaproxy
  176. 176. Load BalancernginxhaproxyHigh availability4.3Web #1nginxappWeb #2nginxappWeb #3nginxapp⏶Web #1 33%Web #2 33%Web #3 33%✓✓✓5downexample.com⚠
  177. 177. :(
  178. 178. DNS$example.com$$$$$$Datacenter66666666$176.58.97.9
  179. 179. DNS$example.com176.58.97.9$$$$$$Datacenter66666666$176.58.97.9
  180. 180. $6DNS$example.com176.58.97.9176.58.97.9$$$$$$????Datacenter6666666
  181. 181. $6DNS$example.com176.58.97.9176.58.97.9$$$$$$????Datacenter6666666SPOF: Single Point Of Failure
  182. 182. High availability4.3ProblemaNecesitamos hacer que nuestro balanceador no sea un unSPOF, Single point of failure.• En caso de fallo no podemos cambiar la configuracióndel DNS ya que conllevaría tiempo propagar el cambio.• No podemos poner otra capa de balanceadores porencima del balanceador ya que tendríamos el mismoproblema.• Hagamos lo que hagamos ha de ser rápido para evitardowntime en la medida de lo posible.
  183. 183. $6$$$$$$#1Datacenter6666666$176.58.97.9#2
  184. 184. $6$$$$$$#1Datacenter6666666$176.58.97.9#2
  185. 185. $6$$$$$$#1Datacenter6666666$176.58.97.9#2
  186. 186. Heartbeat♥ Pacemaker8+
  187. 187. Heartbeat♥ Capa de comunicaciónBásicamente es un “bus” que nosasegura que todos los mensajesenviados se envían a todos losmiembros del bus y se asegura de quetodo el mundo esté de acuerdo sobre quienestá o no está conectado.
  188. 188. Pacemaker8 AgenteSe encarga de arrancar y parar serviciosen función de reglas que nosotrosestablezcamos. De igual manera, secerciora de que estos servicios solo seejecuten en uno de los servidores.
  189. 189. Configuración$ cat /etc/ha.d/ha.cfkeepalive 2deadtime 15warntime 5initdead 120udpport 694ucast eth0 123.123.123.123auto_failback onnode ha-1.example.comnode ha-2.example.comuse_logd yescrm respawnHeartbeat4.3Instalación$ apt-get install heartbeatComprobar nodos cada dos segundos.Dar un nodo por muerto a los 15s.Alertar pasados 5 segundos.Máximo tiempo de espera en arranque.Puerto.IP.Failback automático al nodo primario.Nodo #1.Nodo #2.Enable log.Arrancar Pacemaker al arranque del cluster.Hemos de configurar hearbeat en ambos nodos9
  190. 190. Configuración$ cat /etc/heartbeat/authkeysauth 11 sha1 SECRET$ chmod 600 /etc/heartbeat/authkeysHeartbeat4.3Hemos de configurar hearbeat en ambos nodos9Arranque$ service heartbeat startEstado$ service heartbeat statusheartbeat OK [pid 2332 et al] is running onha-1.example.com [ha-1.example.com]...
  191. 191. Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" ha-2.example.comprimitive ip1 ocf:heartbeat:IPaddr2 params ip="123.123.123.123" nic="eth2" op monitor interval="5s"primitive ip1arp ocf:heartbeat:SendArp params ip="123.123.123.123" nic="eth2"group HAServices ip1 ip1arp meta target-role="Started"order ip-before-arp inf: ip1:start ip1arp:startproperty $id="cib-bootstrap-options" dc-version="xxxxxxxxxxxxxxxx" cluster-infrastructure="Heartbeat" expected-quorum-votes="1" stonith-enabled="false" no-quorum-policy="ignore"rsc_defaults $id="rsc-options" resource-stickiness="100"Pacemaker4.3Instalación$ apt-get install pacemaker
  192. 192. Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" ha-2.example.comprimitive ip1 ocf:heartbeat:IPaddr2 params ip="123.123.123.123" nic="eth2" op monitor interval="5s"primitive ip1arp ocf:heartbeat:SendArp params ip="123.123.123.123" nic="eth2"group HAServices ip1 ip1arp meta target-role="Started"order ip-before-arp inf: ip1:start ip1arp:startproperty $id="cib-bootstrap-options" dc-version="xxxxxxxxxxxxxxxx" cluster-infrastructure="Heartbeat" expected-quorum-votes="1" stonith-enabled="false" no-quorum-policy="ignore"rsc_defaults $id="rsc-options" resource-stickiness="100"Pacemaker4.3Instalación$ apt-get install pacemaker
  193. 193. Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" ha-2.example.comprimitive ip1 ocf:heartbeat:IPaddr2 params ip="123.123.123.123" nic="eth2" op monitor interval="5s"primitive ip1arp ocf:heartbeat:SendArp params ip="123.123.123.123" nic="eth2"group HAServices ip1 ip1arp meta target-role="Started"order ip-before-arp inf: ip1:start ip1arp:startproperty $id="cib-bootstrap-options" dc-version="xxxxxxxxxxxxxxxx" cluster-infrastructure="Heartbeat" expected-quorum-votes="1" stonith-enabled="false" no-quorum-policy="ignore"rsc_defaults $id="rsc-options" resource-stickiness="100"Pacemaker4.3Instalación$ apt-get install pacemaker
  194. 194. Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" ha-2.example.comprimitive ip1 ocf:heartbeat:IPaddr2 params ip="123.123.123.123" nic="eth2" op monitor interval="5s"primitive ip1arp ocf:heartbeat:SendArp params ip="123.123.123.123" nic="eth2"group HAServices ip1 ip1arp meta target-role="Started"order ip-before-arp inf: ip1:start ip1arp:startproperty $id="cib-bootstrap-options" dc-version="xxxxxxxxxxxxxxxx" cluster-infrastructure="Heartbeat" expected-quorum-votes="1" stonith-enabled="false" no-quorum-policy="ignore"rsc_defaults $id="rsc-options" resource-stickiness="100"Pacemaker4.3Instalación$ apt-get install pacemaker
  195. 195. Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" ha-2.example.comprimitive ip1 ocf:heartbeat:IPaddr2 params ip="123.123.123.123" nic="eth2" op monitor interval="5s"primitive ip1arp ocf:heartbeat:SendArp params ip="123.123.123.123" nic="eth2"group HAServices ip1 ip1arp meta target-role="Started"order ip-before-arp inf: ip1:start ip1arp:startproperty $id="cib-bootstrap-options" dc-version="xxxxxxxxxxxxxxxx" cluster-infrastructure="Heartbeat" expected-quorum-votes="1" stonith-enabled="false" no-quorum-policy="ignore"rsc_defaults $id="rsc-options" resource-stickiness="100"Pacemaker4.3Instalación$ apt-get install pacemaker
  196. 196. Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" ha-2.example.comprimitive ip1 ocf:heartbeat:IPaddr2 params ip="123.123.123.123" nic="eth2" op monitor interval="5s"primitive ip1arp ocf:heartbeat:SendArp params ip="123.123.123.123" nic="eth2"group HAServices ip1 ip1arp meta target-role="Started"order ip-before-arp inf: ip1:start ip1arp:startproperty $id="cib-bootstrap-options" dc-version="xxxxxxxxxxxxxxxx" cluster-infrastructure="Heartbeat" expected-quorum-votes="1" stonith-enabled="false" no-quorum-policy="ignore"rsc_defaults $id="rsc-options" resource-stickiness="100"Pacemaker4.3Instalación$ apt-get install pacemaker
  197. 197. Configuración$ crm configure editnode $id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ha-1.example.comnode $id="yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" ha-2.example.comprimitive ip1 ocf:heartbeat:IPaddr2 params ip="123.123.123.123" nic="eth2" op monitor interval="5s"primitive ip1arp ocf:heartbeat:SendArp params ip="123.123.123.123" nic="eth2"group HAServices ip1 ip1arp meta target-role="Started"order ip-before-arp inf: ip1:start ip1arp:startproperty $id="cib-bootstrap-options" dc-version="xxxxxxxxxxxxxxxx" cluster-infrastructure="Heartbeat" expected-quorum-votes="1" stonith-enabled="false" no-quorum-policy="ignore"rsc_defaults $id="rsc-options" resource-stickiness="100"Pacemaker4.3Instalación$ apt-get install pacemaker
  198. 198. $Servidor WebHAProxy$Base de datos⚠SPOF$Servidor WebAplicación$Servidor WebAplicaciónSSL*$Servidor WebHAProxySSL*
  199. 199. $Servidor WebHAProxy$Base de datos⚠SPOF$Servidor WebAplicación$Servidor WebAplicaciónSSL*$Servidor WebHAProxySSL*$Servidor WebAplicación$Servidor WebAplicación$Servidor WebAplicación????
  200. 200. $Servidor WebHAProxy$Base de datosMaster$Servidor WebAplicación$Servidor WebAplicaciónSSL*$Servidor WebHAProxySSL*$Servidor WebAplicación$Servidor WebAplicación$Servidor WebAplicaciónWWW W W$Base de datosRead Only
  201. 201. $Servidor WebHAProxy$Base de datosMaster$Servidor WebAplicación$Servidor WebAplicaciónSSL*$Servidor WebHAProxySSL*$Servidor WebAplicación$Servidor WebAplicación$Servidor WebAplicaciónRR R RR$Base de datosRead Only
  202. 202. Y aún más lejos?Llegados a este punto deberíamos de tenera varias personas trabajando en esto atiempo completo... pero el resultado podríaparecerse algo como....:
  203. 203. $Servidor WebHAProxySSL*$Servidor WebHAProxySSL*DNS ROUND ROBIN$Servidor WebHAProxySSL*$Servidor WebHAProxySSL*$Servidor WebHAProxySSL*$Servidor WebHAProxySSL*$Servidor WebAplicación$Servidor WebAplicación$Servidor WebAplicación$Servidor WebAplicación$Servidor WebAplicación$Servidor WebAplicación$Servidor WebAplicación$Servidor WebAplicación$Servidor WebAplicaciónMulti Master DB$Slaven n nn$Master$Master$Slave$Slave$Slave$Slave$Slave$Slave$Slave++
  204. 204. Servidores Web4.4¿Cuál elijo?Existen docenas de servidores web, cada empresa suele elegir uno enfunción de las necesidades y features de cada uno.Nosotros utilizamos nginx dada la sencillez de configuración, la estabilidad, losgrandísimos resultados que siempre alcanza en los tests de carga y enparticular porque ya hemos trabajado con él y lo conocemos.En realidad nginx lo utilizamos como reverse proxy tanto en los balanceadoresde carga como en los servidores web, así como para hacer “spoon-feeding”.
  205. 205. Spoon feeding?
  206. 206. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL???????9
  207. 207. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL???????9
  208. 208. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL???????9
  209. 209. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G???????9
  210. 210. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G???????9
  211. 211. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G???????9
  212. 212. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G???????9
  213. 213. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G???????9
  214. 214. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE???????9
  215. 215. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
  216. 216. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
  217. 217. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
  218. 218. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
  219. 219. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
  220. 220. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
  221. 221. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6Usuario3G6Usuario3G6UsuarioEDGE6UsuarioGPRS???????9
  222. 222. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6UsuarioADSL6Usuario3G6UsuarioEDGE6UsuarioGPRSnginxLAN;INTERNET;1Gb/s
  223. 223. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6UsuarioADSL6Usuario3G6UsuarioEDGE6UsuarioGPRSnginxLAN;INTERNET;1Gb/s2.5Mb/s
  224. 224. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6UsuarioADSL6Usuario3G6UsuarioEDGE6UsuarioGPRSnginxLAN;INTERNET;1Gb/s236Kb/s
  225. 225. $Proceso #1$Proceso #2$Proceso #3$Proceso #46UsuarioADSL6UsuarioADSL6Usuario3G6UsuarioEDGE6UsuarioGPRSnginxLAN;INTERNET;1Gb/s60Kb/s
  226. 226. ✉EmailsLa mayoría de los servicios onlinenecesitan enviar emails a sus usuarios.El número de emails que has de enviarcrece mucho más rápido de lo queesperas...
  227. 227. Amazon SES4.4¿Qué es Amazon SES?Servicio cloud de Amazon que nos permite enviar grandes cantidades de emailssin tener que disponer de una infraestructura para tales efectos.¿Y porqué no un smtp inhouse?El tiempo es oro y el día sólo tiene 24 horas.• Pequeñas empresas que no disponen de personal de sistemas puedenahorrarse muchos dolores de cabeza (y ganar otros) externalizando servicioscomo este .• Grandes empresas que necesitan enviar millones de emails en épocasconcretas y no desean sobre escalar sus sistemas para estas situacionespuntuales.• El coste es muy competitivo: 0.10 $ por cada 1000 emails.Actualmente enviamos alrededor de 1M de emails al mes, lo cual nos cuesta ~£64.
  228. 228. dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
  229. 229. Deploy5
  230. 230. https://github.com/blog/1241-deploying-at-githubDeploying is a big part of the lives of most GitHub employees. Wedont have a release manager and there are no set weeklydeploys. Developers and designers are responsible for shipping newstuff themselves as soon as its ready. This means that deployingneeds to be as smooth and safe a process as possible.“
  231. 231. $$$ $$$ $ $$ $ $ $server #1server #3server #11 server #12server #2server #4 server #5 server #6server #7 server #8 server #9 server #10$ $server #11 server #12$$$ $$$ $ $$ $ $ $server #1Bserver #3Bserver #11B server #12Bserver #2Bserver #4B server #5B server #6Bserver #7B server #8B server #9B server #10B$ $server #11B server #12Bstaging live
  232. 232. $$$ $$$ $ $$ $ $ $server #1Bserver #3Bserver #11B server #12Bserver #2Bserver #4B server #5B server #6Bserver #7B server #8B server #9B server #10B$ $server #11B server #12Blive
  233. 233. $$$ $$$ $ $$ $ $ $server #1Bserver #3Bserver #11B server #12Bserver #2Bserver #4B server #5B server #6Bserver #7B server #8B server #9B server #10B$ $server #11B server #12Bliveactivar modo mantenimiento (503)desplegar nuevo códigopurgar cachésreiniciar serviciosminimizar javascriptminimizar cssgenerar sprites...desactivar modo mantenimiento
  234. 234. Streamlining SSH scriptsfabricfrom fabric.api import rundef host_type():run(uname -s)fabfile.py$ fab -H localhost,linuxbox host_type[localhost] run: uname -s[localhost] out: Darwin[linuxbox] run: uname -s[linuxbox] out: LinuxDone.Disconnecting from localhost... done.Disconnecting from linuxbox... done.
  235. 235. Streamlining SSH scriptsfabricget(remote_path, local_path=None)put(local_path=None, remote_path=None, ...)run(command, ...)sudo(command, ...)reboot(wait=120)local(command, ...)
  236. 236. Hostsfabric@hosts(varnish.example.com)def purge_varnish():"""Purge varnish cache"""sudo(varnishadm -T 127.0.0.1:6082 ban.url . -S /etc/varnish/secret)$ fab purge_varnish
  237. 237. Agrupación de hosts en rolesfabricenv.roledefs = {test: [test-web-1.example.com, test-web-2.example.com],test-db: [test-db-1.example.com, test-db-2.example.com],test-ha: [test-ha-1.example.com, test-ha-2.example.com],www: [www-web-1.example.com, www-web-2.example.com],www-db: [www-db-1.example.com, www-db-2.example.com],www-ha: [www-ha-1.example.com, www-ha-2.example.com],}$ fab deploy -R test$ fab deploy -R www
  238. 238. Helpers de interacciónfabricconfirm(question, default=True)abort(msg)error(message, func=None, exception=None, stdout=None, stderr=None)green(text, bold=False)red(text, bold=False)indent(text, spaces=4, strip=False)
  239. 239. dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
  240. 240. Seguridad6
  241. 241. La seguridad es un tema extenso y delicado.Os invitamos a profundizar en cada uno de losaspectos antes de ponerlos en práctica.Los siguientes son sólo ejemplos y puedencontener errores.⚠
  242. 242. *iptablesNo lo son todo, pero sin lugar a dudasson un buen comienzo para evitarnosproblemas.
  243. 243. Funcionamiento iptablesINPUT TRAFFICFILTERNATMANGLEPREROUTINGPREROUTINGFORWARDFORWARDPOSTROUTINGPOSTROUTINGINPUTINPUTLOCALOUTPUTOUTPUTOUTPUTForwarding processLocal processROUTINGOUTPUT TRAFFIC
  244. 244. Funcionamiento iptablesINPUT TRAFFICFILTERNATMANGLEPREROUTINGPREROUTINGFORWARDFORWARDPOSTROUTINGPOSTROUTINGINPUTINPUTLOCALOUTPUTOUTPUTOUTPUTForwarding processLocal processROUTINGOUTPUT TRAFFICTablasCadenas
  245. 245. Funcionamiento iptablesINPUT TRAFFICFILTERNATMANGLEPREROUTINGPREROUTINGFORWARDFORWARDPOSTROUTINGPOSTROUTINGINPUTINPUTLOCALOUTPUTOUTPUTOUTPUTForwarding processLocal processROUTINGOUTPUT TRAFFIC
  246. 246. Tablas predefinidas>;FILTER.NAT.MANGLE.Tabla responsable del filtrado de paquetes.Todos los paquetes pasan por esta tabla.Tabla responsable de la reescritura de direcciones y/o puertos.El primer paquete de cada conexión pasa por esta tabla.Tabla responsable de ajustar opciones de paquetes (e.j) QOS.Todos los paquetes pasan por esta tabla.
  247. 247. Tablas predefinidas>;FILTER.NAT.MANGLE.Tabla responsable del filtrado de paquetes.Todos los paquetes pasan por esta tabla.Tabla responsable de la reescritura de direcciones y/o puertos.El primer paquete de cada conexión pasa por esta tabla.Tabla responsable de ajustar opciones de paquetes (e.j) QOS.Todos los paquetes pasan por esta tabla.
  248. 248. >FILTER.Tabla responsable del filtrado de paquetes.☰INPUT☰OUTPUT☰FORWARDTodos los paquetes destinados a este sistema atraviesan esta cadena.Todos los paquetes creados por este sistema atraviesan esta cadena.Todos los paquetes que pasan por este sistema atraviesan esta cadena.El destino de cada una de las reglas dentro de las cadenas puede ser:ACCEPT, DROP, QUEUE, o RETURN (entre otros)
  249. 249. >FILTER.Tabla responsable del filtrado de paquetes.☰INPUT☰OUTPUT☰FORWARDTodos los paquetes destinados a este sistema atraviesan esta cadena.Todos los paquetes creados por este sistema atraviesan esta cadena.Todos los paquetes que pasan por este sistema atraviesan esta cadena.El destino de cada una de las reglas dentro de las cadenas puede ser:ACCEPT, DROP, QUEUE, o RETURN (entre otros)
  250. 250. >FILTER:INPUTCadena responsable del filtrado de paquetes de entrada.*filter:INPUT DROP [0:0]:OUTPUT ACCEPT [0:0]:FORWARD DROP [0:0]-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT-A INPUT -m state --state INVALID -j DROP-A INPUT -i lo -j ACCEPT-A INPUT -p icmp -j ACCEPT-A INPUT -s $IP/32 -d $IP/32 -p tcp --dport 80 -j ACCEPT
  251. 251. fail2ban6.2Fail2ban nos permite bloquear ataques de fuerza bruta contra servicioscomo ssh, mail, http etc...• Muy sencillo de instalar y configurar.• Una buena contramedida activa.• Su funcionamiento se basa en leer los logs generados por estosservicios utilizando expresiones regulares.• Además de bloquear el trafico entrante desde estas fuentes sepueden desplegar otras medidas o enviar notificaciones.!h#p://fail2ban.org
  252. 252. SSH root@...6.3Desactivar la cuenta de root es una de las primeras medidas a tomar alconfigurar un servidor.• Si disponemos de un servicio como fail2ban estaremos impidiendoen cierta medida que nadie tenga éxito al realizar un ataque defuerza bruta.• Si por alguna razón el servicio está caído tendríamos nuestra cuentade root expuesta.• Es muy recomendable no permitir conexiones ssh utilizando root.• Una vez en el sistema podemos identificarnos como root o utilizarsudo.PermitRootLogin no/etc/ssh/sshd_config
  253. 253. dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
  254. 254. Monitoring7
  255. 255. You can’t improvewhat you don’t measure“”
  256. 256. top7.1
  257. 257. htop7.2
  258. 258. munin7.3Ventajas• Muy sencillo de instalar y configurar.• Fácil de crear nuevas gráficas usandocualquier lenguaje de scripting.• Uso mínimo de recursos.• Un muy buen punto de partida.Desventajas• Sólo tres vistas por cada gráfica(diaria, semanal, anual)• Gráficas generadas cada ~5m.!h#p://munin9monitoring.org
  259. 259. but... What’s next?Llegado el momento las métricas seconvierten en críticas para analizar nosolo la salud del sistema, si no la delnegocio.;
  260. 260. graphite7.4!h#p://graphite.wikidot.com
  261. 261. graphite servergraphitetcp 80☁
  262. 262. graphite server!carbongraphitetcp 80☁
  263. 263. graphite serverdb server!carbongraphitetcp 80☁
  264. 264. graphite serverdb server!carbongraphitediamondtcp 80☁
  265. 265. graphite serverdb server!carbongraphitediamondstatsdudp 8125tcp 80☁
  266. 266. graphite serverdb server!carbongraphitetcp 2003diamondstatsdudp 8125tcp 80☁
  267. 267. graphite serverweb server db server!carbongraphitetcp 2003diamondstatsdudp 8125diamond statsdudp 8125diamondstatsdudp 8125tcp 80☁
  268. 268. graphite serverweb server db server!carbongraphitetcp 2003diamondstatsdudp 8125diamond statsdudp 8125diamondstatsdudp 8125tcp 80logslogs☁
  269. 269. graphite serverweb server db server!carbongraphitetcp 2003diamondstatsdudp 8125diamond statsdudp 8125diamondstatsdudp 8125tcp 80applogslogs☁
  270. 270. graphite7.4No sólo datos... conocimiento!Descubrir que la carga de un servidor es 9.3 lo fines de semana a las 3am es útilpero... ¿cual es la causa? ¿Que otros síntomas hay? ¿Algún otro servidor se veafectado? ¿Qué estaba haciendo el servidor? ¿Cuantos procesos teníamos enmarcha? ¿Qué tamaño tenía la cola de emails? ¿Hace cuando que hicimos elúltimo deploy?...
  271. 271. graphite7.4from pystatsd import Clientsc = Client(127.0.0.1, 8125)sc.increment(streetlife.emails.immediate.sent)Pythonecho "streetlife.emails.immediate.sent:1|c" | nc -w 1 -u 127.0.0.1 8125BashSon sólo paquetes UDP.Dado que añadir estadísticas consiste en enviar un simple paquete UDP anuestro servidor de statsd, podemos hacerlo desde cualquier sitio!Nuestra aplicación, un script en bash ... Fire-and-forget!
  272. 272. sentry7.5!h#p://getsentry.comh#ps://github.com/getsentry/sentryOpen Source SAAS
  273. 273. pingdom7.6Yo mi me conmigo...Es muy embarazoso darse cuenta que tu web se ha caído porque te lo diga uncliente. Hay docenas de servicios como pingdom que se dedican a testear tuweb desde múltiples localizaciones.Features interesantes:• Monitorizar estado y tiempo de respuesta de páginas clave.• Comprobar tiempos de respuesta desde la otra parte del mundo.• Notificaciones SMS.• Uptime reports.
  274. 274. dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
  275. 275. Provisioning8
  276. 276. $server #1$ ssh user1@server1$ apt-get install paquete_x
  277. 277. $server #1$ ssh user1@server1$ apt-get install paquete_x$server #2$ ssh user2@server2$ apt-get install paquete_x
  278. 278. $server #1$ ssh user1@server1$ apt-get install paquete_x$server #2$ ssh user2@server2$ apt-get install paquete_x$server #3$ ssh user3@server3$ apt-get install paquete_x
  279. 279. $ ssh user1@server1$ apt-get install paquete_x$server #1$server #2$server #3$server #4$ ssh user1@server1$ apt-get install paquete_x$ ssh user3@server3$ apt-get install paquete_z$ ssh user4@server4$ apt-get install paquete_z
  280. 280. $ ssh user1@server1$ apt-get install paquete_x$server #1$server #2$server #3$server #4$ ssh user1@server1$ apt-get install paquete_x$ ssh user3@server3$ apt-get install paquete_z$ ssh user4@server4$ apt-get install paquete_z
  281. 281. $ ssh user1@server1$ apt-get install paquete_x$server #1$server #2$server #3$server #4$ ssh user1@server1$ apt-get install paquete_x$ ssh user3@server3$ apt-get install paquete_z$ ssh user4@server4$ apt-get install paquete_z
  282. 282. $$$ $$$$$$$$$$ $server #1server #3server #11 server #12server #2server #4 server #5 server #6server #7 server #8 server #9 server #10server #13 server #14
  283. 283. $$$ $$$ $ $$ $ $ $server #1server #3server #11 server #12server #2server #4 server #5 server #6server #7 server #8 server #9 server #10$ $server #11 server #12$$$ $$$ $ $$ $ $ $server #1Bserver #3Bserver #11B server #12Bserver #2Bserver #4B server #5B server #6Bserver #7B server #8B server #9B server #10B$ $server #11B server #12Blive staging
  284. 284. $$$ $$$ $ $$ $ $ $server #1server #3server #11 server #12server #2server #4 server #5 server #6server #7 server #8 server #9 server #10$ $server #11 server #12$$$ $$$ $ $$ $ $ $server #1Bserver #3Bserver #11B server #12Bserver #2Bserver #4B server #5B server #6Bserver #7B server #8B server #9B server #10B$ $server #11B server #12Blive staging$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x$ ssh user1@server1$ apt-get install paquete_x
  285. 285. Shit hapens happens... a lot.⚠Repetition leads to boredom,boredom to horrifying mistakes,horrifying mistakes to God-I-wish-I-was-still-bored.
  286. 286. Provisioning8.1Automatizar la configuración y mantenimiento de tantos servidores cómo necesitemos.• Generar plantillas que nos permitan generar nuevas máquinas sin muchoesfuerzo y de manera automatizada.• Solucionar casos de catástrofe total ya que podemos regenerar nuestraarquitectura en otro datacenter sin problemas.• Todo del código que automatice este proceso se convierte en últimotermino en una excelente documentación.• “Code as Infrastructure”
  287. 287. Puppet8.2Puppet es junto a Chef uno de los más utilizados.• Nos permite automatizar la configuración deservidores UNIX y Windows.• El lenguaje que se utiliza puede ser tanto Rubycomo un lenguaje declarativo propio de Puppet enel que se definen tanto recursos del sistema como elestado de los mismos.• Servicios, usuarios, paquetes, ficheros...• Puppet extrae del sistema información como CPUs,memoria, discos direcciones IP etc... y compilanuestras plantillas junto a esta información.• Puede ejecutarse en modo arquitectura con unservicio central encargado de compilar las plantillaso en modo “solo-mode” en el cual se compilan lasplantillas en cada servidor.
  288. 288. Puppet8.2Una de las principales características de Puppetfrente a otros sistemas de configuración es quees idempotente. Por ejemplo, podemos ejecutarlocada 30 minutos y cerciorarnos de que todo estátal y como lo hemos definido.Esta es una gran ventaja dado que además deservirnos como bootstrap para nuevas máquinas,puppet nos permite administrar nuestrasmáquinas a lo largo de todo su ciclo de vida desdela creación mantenimiento y migración.
  289. 289. packagepackage { nginx:ensure => installed,}presentlatest1.5.3absent
  290. 290. packagepackage { nginx:ensure => installed,}presentlatest1.5.3absent
  291. 291. filefile { /etc/nginx/nginx.conf:source => modules/nginx/nginx.conf,owner => root,group => root,mode => 640,require => Package[nginx],notify => Service[nginx]}????
  292. 292. filefile { /etc/nginx/nginx.conf:source => modules/nginx/nginx.conf,owner => root,group => root,mode => 640,require => Package[nginx],notify => Service[nginx]}????
  293. 293. serviceservice { nginx:ensure => running,enable => true,hasstatus => true,hasrestart => true,}
  294. 294. require, notifyPackage[nginx]File[/etc/nginx/nginx.conf]Service[nginx]InstalledCreated Updated
  295. 295. user, groupuser { tom:ensure => present,shell => /bin/bash,home => /home/tom,managehome => true,}group { friends:ensure => present}
  296. 296. nodesnode web.example.com inherits web_node {include munininclude pythonuser { tom:ensure => present,shell => /bin/bash,home => /home/tom,managehome => true,}...}
  297. 297. apply$ puppet apply puppet/manifests/site.pp
  298. 298. dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
  299. 299. Herramientas9
  300. 300. Características• Wrapper de virtualbox para crear y destruir máquinas desde lalinea de comandos.• Permite crear “instancias” base para crear máquinas desde unestado concreto en cuestión de segundos.• Integración con Puppet y Chef entre otros.• Gracias a vagrant y puppet podemos lograr que todos losmiembros del equipo dispongan del mismo setup en local sinmucho quebradero de cabeza.• La puesta en marcha de nuevos empleados se reduce a minutosen vez de días.• Gracias a la sencillez de uso podemos crear distintos setup encuestión de minutos y comprobar su funcionamiento.• Funciona en todas las plataformas: Linux, OSX y Windows.Vagrant9.1
  301. 301. Añadir un boxVagrant9.1$ vagrant box add ubuntu-precise http://bit.ly/ubuntu-preciseCrear una nueva instancia$ vagrant init ubuntu-preciseArrancar nuestra nueva máquina virtual$ vagrant up!h#p://vagrantbox.es$ vagrant ssh
  302. 302. Vagrant::Config.run do |config|config.vm.define :web do |web|web.vm.box = "ubuntu-precise-64"web.vm.box_url = "http://bit.ly/ubuntu-precise"web.vm.host_name = "dev.example.com"web.vm.network :hostonly, "33.33.33.20"web.vm.forward_port(22, 2023)web.vm.forward_port(80, 8081)web.vm.share_folder("code", "/home/vagrant/code", "./code", :nfs => true)endconfig.vm.define :db do |db|db.vm.box = "ubuntu-precise-64"db.vm.box_url = "http://bit.ly/ubuntu-precise"db.vm.host_name = "dev-db.example.com"db.vm.network :hostonly, "33.33.33.21"db.vm.forward_port(22, 2024)db.vm.forward_port(5432, 5432)endendMúltiples boxes
  303. 303. $ vagrant up web[web] VM already created. Booting if its not already running...[web] Clearing any previously set forwarded ports...[web] Fixed port collision for 22 => 2222. Now on port 2202.[web] Forwarding ports...[web] -- 22 => 2023 (adapter 1)[web] -- 80 => 8081 (adapter 1)[web] Exporting NFS shared folders...[vagrant] Preparing to edit /etc/exports. Administrator privileges will be required...[web] Creating shared folders metadata...[web] Clearing any previously set network interfaces...[web] Preparing network interfaces based on configuration...[web] Booting VM...[web] Waiting for VM to boot. This can take a few minutes.[web] VM booted and ready for use![web] Configuring and enabling network interfaces...[web] Setting host name...[web] Mounting shared folders...[web] -- v-root: /vagrant[web] -- manifests: /tmp/vagrant-puppet/manifests[web] -- v-pp-m0: /tmp/vagrant-puppet/modules-0[web] Mounting NFS shared folders...[web] Running provisioner: Vagrant::Provisioners::Puppet...[web] Running Puppet with /tmp/vagrant-puppet/manifests/site.pp...stdin: is not a ttynotice: Finished catalog run in 1.70 secondsvagrant up
  304. 304. Git branch model9.2http://nvie.com/posts/a-successful-git-branching-model/1
  305. 305. CSS Preprocessors9.3
  306. 306. Chrome Plugins9.4Hay docenas de plugins que pueden hacer nuestro día a día muchomás sencillo. Estos son algunos de los que encontramos másinteresantes, además del inspector que Chrome tiene integrado.
  307. 307. User-Agent switcher9.4Cambiar de User-Agent con dos clicksPodemos configurar nuestrospropios User-Agent.
  308. 308. Resolution test9.4Cambiar el tamaño de la ventana con dos clicks
  309. 309. Cache Killer9.4Mientras esté activo no se utilizará la cache del navegador.
  310. 310. Speed tracer9.4
  311. 311. dev1ops2env3browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamientoherramientasbuenas prácticas
  312. 312. Buenas prácticas10
  313. 313. CI: Jenkins10.2CaracterísticasServicio que nos permite automatizar (entreotras cosas) la ejecución de tests,compilación de documentación, generarreports de test coverage...Ejecuciones• Periódicamente• Por cada commit al repositorio.Configuración• Requiere de un poco de práctica perouna vez configurado no necesita muchomantenimiento.
  314. 314. Hipchat/IRC10.3La comunicación entre los empleados es muyimportante (sobre todo cuando no siempre todo elmundo está trabajando desde la misma oficina).Ventajas• Histórico de todas las conversaciones.• Facilidad para compartir rápidamente ficheros,capturas de pantalla etc...• 0 Configuración y entrada amable para no techies.• Salas por departamentos, equipos etc...• Gaticos.• Notificaciones de deploy, mantenimiento etc...
  315. 315. Questions?
  316. 316. Recursoshttp://www.flickr.com/photos/marceldouwedekker/http://pygments.org/http://entypo.com/Fuenteshttp://net.tutsplus.com/tutorials/other/http-headers-for-dummies/http://igoro.com/archive/what-really-happens-when-you-navigate-to-a-url/http://pyvideo.org/video/1677/how-the-internet-workshttp://es.wikipedia.org/wiki/Hypertext_Transfer_Protocolhttp://en.wikipedia.org/wiki/List_of_HTTP_header_fieldshttp://en.wikipedia.org/wiki/MIME_typehttp://silex.sensiolabs.org/doc/cookbook/json_request_body.htmlhttp://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-1http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.htmlhttp://www.w3.org/TR/html401/interact/forms.html#h-17.13.4http://en.wikipedia.org/wiki/HTTP_cookiehttp://developer.yahoo.com/performance/rules.htmlhttp://www.tldp.org/HOWTO/SSL-Certificates-HOWTO/x64.htmlhttp://www.varnish-cache.org/docs/3.0/http://haproxy.1wt.eu/download/1.5/doc/configuration.txthttp://ontwik.com/python/django-deployment-workshop-by-jacob-kaplan-moss/http://glue.readthedocs.org/en/latest/http://library.linode.com/http://code.flickr.net/2008/10/27/counting-timing/http://codeascraft.etsy.com/2011/02/15/measure-anything-measure-everything/http://codeascraft.etsy.com/2010/12/08/track-every-release/http://plusbryan.com/my-first-5-minutes-on-a-server-or-essential-security-for-linux-servershttp://docs.vagrantup.com/v2/

×