Top Banner
Jorge Bas*da me@jorgebas*da.com @jorgebas*da Jaime Irurzun [email protected] @jaimeirurzun Open Source Modern web development
336
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 2: Open Source Modern Web Development
Page 3: Open Source Modern Web Development

env environment

Open source modern web development

!

#

dev development

ops operations

Page 4: Open Source Modern Web Development

dev1

ops2

env3

browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamiento

herramientasbuenas prácticas

Page 5: Open Source Modern Web Development

dev1

ops2

env3

browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamiento

herramientasbuenas prácticas

Page 6: Open Source Modern Web Development

Browser1

Page 7: Open Source Modern Web Development

renderiza ejecuta habla

Browser

Más que un terminal tonto,pero no tanto más

HTML + CSSJavaScriptHTTP (+DNS)

Page 8: Open Source Modern Web Development

HTML + CSSJavaScriptHTTP (+DNS)

Browser

Más que un terminal tonto,pero no tanto más

frontend

backend

Page 9: Open Source Modern Web Development

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.html

example.css

Page 10: Open Source Modern Web Development

ejecuta JavaScript

<html> ... <body> <h1>Title</h1> ... <script type="text/javascript" src="example.js"></script> </body></html>

document.getElementsByTagName('h1')[0].onclick = function() { alert("You've clicked!");};

+ =

example.html

example.js

Page 11: Open Source Modern Web Development

¿qué ocurre por detrás?

habla HTTP (+DNS)

Page 12: Open Source Modern Web Development

Escribes una URL en el navegador1

Se hace una petición DNS para traducir el hostname de la URL a su dirección IP

2

Se hace una petición HTTP a esa IP pidiendo el recurso / y se recibe el resultado, normalmente un fichero .html

3

www.wikipedia.org

91.198.174.225

91.198.174.225

GET / HTTP/1.1...

HTTP/1.1 200 OK...

$#

Page 13: Open Source Modern Web Development

El navegador comienza a renderizar el HTML y hace más peticiones [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 fuerce una recarga completa de la página, todo lo que puede ocurrir son efectos CSS y código JavaScript.

5

Desde JavaScript podemos hacer peticiones HTTP asíncronas (AJAX) que fuercen acciones en el servidor y como resultado realicen cambios en el DOM de la página. Y esto es todo.

Page 14: Open Source Modern Web Development

El navegador comienza a renderizar el HTML y hace más peticiones [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 fuerce una recarga completa de la página, todo lo que puede ocurrir son efectos CSS y código JavaScript.

5

Desde JavaScript podemos hacer peticiones HTTP asíncronas (AJAX) que fuercen acciones en el servidor y como resultado realicen cambios en el DOM de la página. Y esto es todo.

Page 15: Open Source Modern Web Development

HTTP es el idioma de la weby hay que conocerlo

Page 16: Open Source Modern Web Development

dev1

ops2

env3

browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamiento

herramientasbuenas prácticas

Page 17: Open Source Modern Web Development

HTTP2

Page 18: Open Source Modern Web Development

físico

enlace de datos

red

transporte

sesión

presentación

aplicación

Modelo OSI

Hardware

Acceso al medio (MAC)

Enrutamiento entre redes

Transmisión fiable del mensaje

Diálogo

Codificación, cifrado, compresión...

Contenido del mensaje

Page 19: Open Source Modern Web Development

acceso al medio

red

transporte

aplicación

TCP/IP

físico

enlace de datos

red

transporte

sesión

presentación

aplicación

Modelo OSI

http, ftp, smtp, pop, imap, ssh, irc, ...

TCP, UDP

IP

ethernet, token ring, fddi, ...

Page 20: Open Source Modern Web Development

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ón

Respuesta $

#

Page 21: Open Source Modern Web Development

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>

Respuesta

Petición

$

#

Page 22: Open Source Modern Web Development

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ón

Respuesta $

#

Page 23: Open Source Modern Web Development

Un recurso se identifica mediante una URL

<OPERACIÓN> <recurso> HTTP/1.1

protocol://[user:pass@]host[:port][/resource]

en http, por defecto:user = pass =port = 80resource = /

http://www.wikipedia.org:80/

Page 24: Open Source Modern Web Development

<OPERACIÓN> <recurso> HTTP/1.1

Las URLs son parte fundamentaldel diseño de una aplicación web

http://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...

Page 25: Open Source Modern Web Development

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ón

Respuesta $

#

Page 26: Open Source Modern Web Development

GET Obtiene un recurso. No debería producir cambios.

POSTPUT

Crea un recurso.

Reemplaza o crea un recurso.

DELETE Elimina un recurso.

<OPERACIÓN> <recurso> HTTP/1.1

HEAD Como GET, pero pide sólo las cabeceras.

TRACE Diagnóstico.

OPTIONS Pregunta por los métodos que soporta el servidor.

CONNECT Diagnóstico.

Page 27: Open Source Modern Web Development

<OPERACIÓN> <recurso> HTTP/1.1

REST es un enfoque de diseño de APIs que,entre otras cosas, explota la pureza de estos conceptos

http://example.com/recetas/

http://example.com/recetas/453

PUTGET

POSTDELETE

PUTGET

POSTDELETE

Lista 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.

Page 28: Open Source Modern Web Development

+La navaja suiza de las URLscURL

Page 29: Open Source Modern Web Development

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/recetas

cURL

Page 30: Open Source Modern Web Development

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/recetas

cURL

Page 31: Open Source Modern Web Development

$ 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

Page 32: Open Source Modern Web Development

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ón

Respuesta $

#

Page 33: Open Source Modern Web Development

<cabeceras>

Son parejas Clave: valor que transmiten alservidor información acerca de la request

Accept: text/plain

Accept-Charset: utf-8

Accept-Encoding: gzip, deflate

Accept-Language: en-US

Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Cache-Control: no-cache

Connection: keep-alive

Cookie: $Version=1; Skin=new;

Content-Length: 348

Page 34: Open Source Modern Web Development

<cabeceras>

Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==

Content-Type: application/x-www-form-urlencoded

Date: Tue, 15 Nov 1994 08:12:31 GMT

Expect: 100-continue

From: [email protected]

Host: en.wikipedia.org:80

If-Match: "737060cd8c284d8af7ad3082f209582d"

If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT

If-None-Match: "737060cd8c284d8af7ad3082f209582d"

If-Range: "737060cd8c284d8af7ad3082f209582d"

If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT

Page 35: Open Source Modern Web Development

<cabeceras>

Max-Forwards: 10

Origin: http://www.example-social-network.com

Pragma: no-cache

Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Range: bytes=500-999

Referer: http://en.wikipedia.org/wiki/Main_Page

TE: trailers, deflate

Upgrade: 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 warning

X-<YYY>: ZZZ

Page 36: Open Source Modern Web Development

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

Page 37: Open Source Modern Web Development

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

Page 38: Open Source Modern Web Development

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ón

Respuesta $

#

Page 39: Open Source Modern Web Development

<cuerpo>

Content-Type: application/json

application/pdf

application/x-www-form-urlencoded

multipart/form-data

image/jpeg

text/plain

video/mpeg

...

Tiene sentido en peticiones PUT y POST.Su formato lo define la cabecera Content-Type:

Page 40: Open Source Modern Web Development

<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:80

title=Hello%21&body=This+is+my+first+post%21

Page 41: Open Source Modern Web Development

<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--

Page 42: Open Source Modern Web Development

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

Page 43: Open Source Modern Web Development

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ón

Respuesta $

#

Page 44: Open Source Modern Web Development

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ón

Respuesta $

#

Page 45: Open Source Modern Web Development

HTTP/1.1 <código> <descripción>

200 OK201 Created202 Accepted203 Non-Authoritative Information204 No Content205 Reset Content206 Partial Content

1XX Informational

2XX Success

100 Continue101 Switching Protocols

300 Multiple Choices301 Moved Permanently302 Found303 See Other304 Not Modified305 Use Proxy306 (Unused)307 Temporary Redirect

3XX Redirection

Page 46: Open Source Modern Web Development

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 Failed

500 Internal Server Error501 Not Implemented502 Bad Gateway503 Service Unavailable504 Gateway Timeout505 HTTP Version Not Supported

5XX Server Error

$

Page 47: Open Source Modern Web Development

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ón

Respuesta $

#

Page 48: Open Source Modern Web Development

<cabeceras>

Access-Control-Allow-Origin: *

Accept-Ranges: bytes

Age: 12

Allow: GET, HEAD

Cache-Control: max-age=3600

Connection: close

Content-Encoding: gzip

Content-Language: en

Content-Length: 348

Content-Location: /index.html

Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==

Content-Disposition: attachment; filename="f.txt"

Page 49: Open Source Modern Web Development

<cabeceras>

Content-Range: bytes 21010-47021/47022

Content-Type: text/html; charset=utf-8

Date: Tue, 15 Nov 1994 08:12:31 GMT

ETag: "737060cd8c284d8af7ad3082f209582d"

Expires: Thu, 01 Dec 1994 16:00:00 GMT

Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT

Link: </feed>; rel="alternate"[25]

Location: http://www.w3.org/pub/WWW/People.html

P3P: CP="This is not a P3P policy! See..."

Pragma: no-cache

Proxy-Authenticate: Basic

Refresh: 5; url=http://...

Page 50: Open Source Modern Web Development

<cabeceras>

Retry-After: 120

Server: Apache/2.4.1 (Unix)

Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1

Status: 200 OK

Strict-Transport-Security: max-age=16070; includeSubDomains

Trailer: Max-Forwards

Transfer-Encoding: chunked

Vary: *

Via: 1.0 fred, 1.1 example.com (Apache/1.1)

Warning: 199 Miscellaneous warning

WWW-Authenticate: Basic

X-<YYY>: ZZZ

Page 51: Open Source Modern Web Development

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ón

Respuesta $

#

Page 52: Open Source Modern Web Development

<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>

Page 53: Open Source Modern Web Development

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ón

Respuesta $

#

Page 54: Open Source Modern Web Development

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 GMT

HTTP Imprescindible

Page 55: Open Source Modern Web Development

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.0

http 1.1GET

XXXGET

XXX

HTTP Imprescindible

Page 56: Open Source Modern Web Development

HTTP/1.1 400 Bad Request

HTTP/1.1 401 UnauthorizedWWW-Authenticate: Basic realm="..."

HTTP/1.1 403 Forbidden

HTTP/1.1 404 Not Found

HTTP/1.1 405 Method Not Allowed

HTTP/1.1 410 Gone

HTTP Imprescindible

Page 57: Open Source Modern Web Development

HTTP/1.1 500 Internal Server Error

HTTP/1.1 501 Not Implemented

HTTP/1.1 502 Bad Gateway

HTTP/1.1 503 Service Unavailable

HTTP Imprescindible

Page 58: Open Source Modern Web Development

CookiesSolucionan la falta de estado del protocolo HTTP

$#

$#

Son simples strings que se almacenan en el navegador

GET / HTTP/1.1...

GET / HTTP/1.1Cookie: sessionid=xxx

HTTP/1.1 200 OKSet-Cookie: sessionid=xxx

HTTP/1.1 200 OK...

Cliente Servidor

Page 59: Open Source Modern Web Development

CookiesSet-Cookie: sessionid=xxx; Domain=docs.foo.com; Path=/accounts; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly

En qué requests debería enviarse como Cookie:Domain + Path

Expires Cuándo el User-Agent debería borrar la cookie

Secure Sólo debe enviarse si el tráfico es https

HttpOnly Sólo accessible desde HTTP, no desde JavaScript

XSS!⚠document.cookie = ...

Page 60: Open Source Modern Web Development

CookiesSet-Cookie: sessionid=xxx; Domain=docs.foo.com; Path=/accounts; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly

En qué requests debería enviarse como Cookie:Domain + Path

Expires Cuándo el User-Agent debería borrar la cookie

Secure Sólo debe enviarse si el tráfico es https

HttpOnly Sólo accessible desde HTTP, no desde JavaScript

XSS!⚠document.cookie = ...

Page 61: Open Source Modern Web Development

Método sencillo para proveer de autenticación a peticiones HTTP, sin necesidad de cookies

$#GET / HTTP/1.1...

Cliente Servidor

HTTP/1.1 401 UnauthorizedWWW-Authenticate: Basic realm="Login"

Basic HTTP auth

Page 62: Open Source Modern Web Development

Basic HTTP authMétodo sencillo para proveer de autenticación a peticiones

HTTP, sin necesidad de cookies

$#GET / HTTP/1.1...

Cliente Servidor

HTTP/1.1 401 UnauthorizedWWW-Authenticate: Basic realm="Login"

$#GET / HTTP/1.1Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

HTTP/1.1 200 OK...

base64(username:password) HTTPS!⚠

Page 63: Open Source Modern Web Development

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

Page 64: Open Source Modern Web Development

cURL

* About to connect() to google.com port 80 (#0)* Trying 173.194.41.233... connected> GET / HTTP/1.1> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0> Host: google.com> Accept: */*>< HTTP/1.1 301 Moved Permanently< Location: http://www.google.com/< Content-Type: text/html; charset=UTF-8< Date: Sun, 05 May 2013 22:16:31 GMT< Expires: Tue, 04 Jun 2013 22:16:31 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

Ejercicio cURL: La guarida del dragón.$ curl -v -XPOST 10.172.104.175/jugadores/ -d "username=pablo"

)

Page 65: Open Source Modern Web Development

dev1

ops2

env3

browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamiento

herramientasbuenas prácticas

Page 66: Open Source Modern Web Development

HTTPS*

Page 67: Open Source Modern Web Development

acceso al medio

red

transporte

aplicación

físico

enlace de datos

red

transporte

sesión

presentación

aplicación HTTP

TLS/SSL

HTTPS

Page 68: Open Source Modern Web Development

HTTPS

$#Certificado

Public key (P)

P(K)

Ok

K = ...

Clave simétrica compartida mediante algoritmo asimétrico

K(mensaje)

K(mensaje)

Cliente Servidor

+

Page 69: Open Source Modern Web Development

Otras navajas suizastcpflow

$ sudo tcpflow -i eth0 port 80 -C

Sniffer de tráfico TCP por excelencia en UNIX

Chrome inspector

Page 70: Open Source Modern Web Development

dev1

ops2

env3

browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamiento

herramientasbuenas prácticas

Page 71: Open Source Modern Web Development

Optimización3

Page 72: Open Source Modern Web Development

Cliente

Servidor

Canal

Cachear, Delegar, Indexarvarnish, redis, cron, batch...

Reducir request ( número y tamaño )Minify, sprites, gzip, cdn...

Cachear + OptimizarCache, dns lookups, redirects, etags...

Optimización3

Page 73: Open Source Modern Web Development

Cliente

Servidor

Canal

Cachear, Delegar, Indexarvarnish, redis, cron, batch...

Reducir request ( número y tamaño )Minify, sprites, gzip, cdn...

Cachear + OptimizarCache, dns lookups, redirects, etags...

Optimización3

Page 74: Open Source Modern Web Development

Servidor3.1

Page 75: Open Source Modern Web Development

Cachear3.1.1Contenido

Request Response

Varnish

Request

Page 76: Open Source Modern Web Development

30m 10m no-cache

Memcached, redis etc...

Contenido externo• APIs, RSS, Twitter

Contenido “Estático”• Últimas noticias• Nuevos usuarios• Últimos tweets• ...

Cachear Contenido3.1.1

Page 77: Open Source Modern Web Development

> 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

Page 78: Open Source Modern Web Development

> INCR message:143:comments 14445

Redis

• Ventajas• Velocidad• Tipos de datos complejos• Operaciones atómicas

• Inconvenientes• Muy pocas• Abuso = Problemas (como todo)

Welcome to my site.

4445 Comments

Cachear Contenido3.1.1

Page 79: Open Source Modern Web Development

Existen múltiples “puntos” donde cachear.•Servidor web• Intrusismo• Complejidad media

•Código del proyecto “backend”• Sencillo de implementar• Poco eficiente

•Proxy• Sencillo• Muy eficiente

Cachear Requests3.1.1

Page 80: Open Source Modern Web Development

• Requests Anónimas• Digg effect• Landing page• Google

• Contenido Estático• Assets• Thumbnails

• APIs• “Hot Pages”

Request Response

Varnish

Server

Miss

Hit

Cachear Requests3.1.1

Page 81: Open Source Modern Web Development

Request

* Versión muy simplificada del funcionamiento de Varnish

Varnish

Varnish3.1.1

Page 82: Open Source Modern Web Development

Request vcl_recv()

* Versión muy simplificada del funcionamiento de Varnish

Varnish

Varnish3.1.1

Page 83: Open Source Modern Web Development

Request vcl_recv()

lookup

* Versión muy simplificada del funcionamiento de Varnish

in cache?

Varnish

Varnish3.1.1

Page 84: Open Source Modern Web Development

Request vcl_recv()

lookup

* Versión muy simplificada del funcionamiento de Varnish

in cache?

yes

Varnish

Varnish3.1.1

Page 85: Open Source Modern Web Development

Request vcl_recv()

lookup

* Versión muy simplificada del funcionamiento de Varnish

in cache?

Build Response

yes

Varnish

Varnish3.1.1

Page 86: Open Source Modern Web Development

Request vcl_recv()

lookup

* Versión muy simplificada del funcionamiento de Varnish

in cache?

Build ResponseResponse

yes

Varnish

Varnish3.1.1

Page 87: Open Source Modern Web Development

Request vcl_recv() pass

lookup

* Versión muy simplificada del funcionamiento de Varnish

in cache?

no

Build ResponseResponse

yes

Varnish

Varnish3.1.1

Page 88: Open Source Modern Web Development

Request vcl_recv() Backendpass

lookup

* Versión muy simplificada del funcionamiento de Varnish

in cache?

no

Build Response

vcl_fetch()

Response

yes cache?

Varnish

Varnish3.1.1

Page 89: Open Source Modern Web Development

Request vcl_recv() Backendpass

lookup

* Versión muy simplificada del funcionamiento de Varnish

in cache?

no

Build Response

vcl_fetch()

Response

yes cache?no

Varnish

Varnish3.1.1

Page 90: Open Source Modern Web Development

Request vcl_recv() Backendpass

lookup

* Versión muy simplificada del funcionamiento de Varnish

in cache?

no

Build Response

vcl_fetch()

Response

yes

Cache

cache? yesno

Varnish

Varnish3.1.1

Page 91: Open Source Modern Web Development

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 don't 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 don't 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

Page 92: Open Source Modern Web Development

sub vcl_fetch {

# If the response status >= 400 don't 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, don't 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

Page 93: Open Source Modern Web Development

Demo Varnish3A

Page 94: Open Source Modern Web Development

Delegar3.2

$#

Cliente Servidor

500ms bd!

,smtp200ms

5s

Dejar que alguien haga el trabajo sucio, antes o después

csv

#

Page 95: Open Source Modern Web Development

Delegar3.2

$#

Cliente Servidor

500ms bd!

,smtp200ms

5s

¿Cuánto del trabajo sucio es imprescindible al instante?

csv

#

?

?

?

Page 96: Open Source Modern Web Development

Delegar3.2

$#

Cliente Servidor

500ms bd!

,smtp200ms

5s

¿Cuánto del trabajo sucio es imprescindible al instante?

csv

#?

¿caché?

?

Page 97: Open Source Modern Web Development

Delegar3.2

$#

Cliente Servidor

500ms bd!

,smtp200ms

5s

¿Cuánto del trabajo sucio es imprescindible al instante?

csv

#?

¿caché?

¿tarea periódica?

Page 98: Open Source Modern Web Development

Delegar3.2

$#

Cliente Servidor

500ms bd!

,smtp200ms

5s

¿Cuánto del trabajo sucio es imprescindible al instante?

csv

#

¿caché?

¿tarea periódica?

¿cola de mensajes?

Page 99: Open Source Modern Web Development

Delegar3.2

$#

Cliente Servidor

500ms bd!

,smtp200ms

5s

¿Cuánto del trabajo sucio es imprescindible al instante?

csv

#

¿caché?

Delegar antes

Delegar después

Page 100: Open Source Modern Web Development

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

Page 101: Open Source Modern Web Development

Scheduler de trabajos de UNIX

# crontab -l

0 1 * * * /usr/sbin/ntpdate pool.ntp.org

0 */2 * * * /home/root/bin/server-backup

@reboot /home/root/bin/email-admins.sh

cron

$ 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

Page 102: Open Source Modern Web Development

Delegar3.2

$#

Cliente Servidor

500ms bd!

,smtp200ms

5s

¿Cuánto del trabajo sucio es imprescindible al instante?

csv

#

¿caché?

Delegar antes

Delegar después

Page 103: Open Source Modern Web Development

Celery3.2

Sistema 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

Page 104: Open Source Modern Web Development

Celery3.2El principal componente es el Broker. Se encarga de almacenar y entregar tareas a todos los workers.

Estable

Experimental

Page 105: Open Source Modern Web Development

Celery+RabbitMQ3.2

Page 106: Open Source Modern Web Development

Celery+RabbitMQ3.2

Page 107: Open Source Modern Web Development

Funcionamiento3.2Server #1

celery worker

celery beat

Server #3

celery worker

Server #4

web node

Server #5

web node

añadir

procesarprocesar

añadir

añadir

Server #2

celery worker

procesar

Page 108: Open Source Modern Web Development

Funcionamiento3.2Server #1

celery worker

celery beat

Server #3

celery worker

Server #4

web node

Server #5

web node

añadir

procesarprocesar

añadir

añadir

Server #2

celery worker

procesar

Page 109: Open Source Modern Web Development

Funcionamiento3.2Server #1

celery worker

celery beat

Server #3

celery worker

Server #4

web node

Server #5

web node

añadir

procesarprocesar

añadir

añadir

Server #2

celery worker

procesar

Page 110: Open Source Modern Web Development

Funcionamiento3.2Conceptos clave:

• Atómico: Las tareas se entregan solo a un worker.

• Distribuido: Los nodos son independientes unos de otros y el número puede aumentar y disminuir dinámicamente.

• Fiable: Si no se informa a RabbitMQ sobre la finalización de una tarea, esta vuelve a formar parte de la cola. En caso de catástrofe no perdemos tareas.

• Rates: Celery nos permite definir rates para nos sobrecargar el sistema o APIs externas.

• Tareas Periodicas: Celery beat registrará por nosotros tareas en la cola de la misma manera que lo haría cron.

Page 111: Open Source Modern Web Development

Indexar3.3Preparar la información para acceder más rápido a ella en el momento de la consulta

! DB Search-

Page 112: Open Source Modern Web Development

! DB index

SELECT date(timestamp) as day, count(*)

FROM stamp WHERE key=%s AND date(timestamp) > current_date - interval %s

GROUP 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

Page 113: Open Source Modern Web Development

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 %s

GROUP BY day ORDER BY day;

con 4.221.883 registros,

! DB index

11.488 segundos

Page 114: Open Source Modern Web Development

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 %s

GROUP BY day ORDER BY day;

con 4.221.883 registros,

! DB index

11.488 0.107

segundos

Page 115: Open Source Modern Web Development

Search index-

$#

Cliente Servidor

bd!

q='covent garden'

SELECT * FROM messages WHERE subject like '%covent garden%' OR

body like '%covent garden%' OR

author like '%covent garden%';

SELECT * FROM locations WHERE name like '%covent garden%' OR

description like '%covent garden%';

SELECT * FROM pages WHERE name like '%covent garden%' OR

description like '%covent garden%';

SELECT * FROM shareables WHERE name like '%covent garden%' OR

description like '%covent garden%';

Page 116: Open Source Modern Web Development

Search index-

$#

Cliente Servidor

bd!

q='covent garden'

SELECT * FROM messages WHERE subject like '%covent garden%' OR

body like '%covent garden%' OR

author like '%covent garden%';

SELECT * FROM locations WHERE name like '%covent garden%' OR

description like '%covent garden%';

SELECT * FROM pages WHERE name like '%covent garden%' OR

description like '%covent garden%';

SELECT * FROM shareables WHERE name like '%covent garden%' OR

description like '%covent garden%';

mmm... NO

Page 117: Open Source Modern Web Development

Search index-

$#

Cliente Servidor

bd!

q='covent garden'

-searchengine

.

Page 118: Open Source Modern Web Development

Search index-

$#

Cliente Servidor

bd!

q='covent garden'

-searchengine

.

Page 119: Open Source Modern Web Development
Page 120: Open Source Modern Web Development

Redis3.3.3

Redis is an open source, BSD licensed,

advanced key-value store. It is often

referred to as a data structure server since keys can contain strings, hashes, lists,

sets and sorted sets.

hashes

lists sets sorted setsstrings

pub/sub scripts

Page 121: Open Source Modern Web Development
Page 122: Open Source Modern Web Development
Page 123: Open Source Modern Web Development

Enero 2012

Page 124: Open Source Modern Web Development

Enero 2012

~67% ~23%150ms

300ms

Page 125: Open Source Modern Web Development

Memcached Feb 2012

~86% ~14%50ms

300ms

Page 126: Open Source Modern Web Development

Redis Feb 2013

~99% ~1%3 ms

300ms

Page 127: Open Source Modern Web Development

Redis como Indice3.1

Problema:Mostrar avatares de 25 usuarios que compartan algún área contigo promocionando aquellos que no tengan uno de los avatares por defecto.

Custom

Default

Page 128: Open Source Modern Web Development

3.1Solución: Sorted Sets

1. Para cada area crear un sorted set con el id de todos los miembros.

> ZADD area:1:followers 1 1

area:1:followers 1

Redis como Indice

Page 129: Open Source Modern Web Development

3.1Solución: Sorted Sets

1. 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

area:1:followers 1 2

Redis como Indice

Page 130: Open Source Modern Web Development

3.1Solución: Sorted Sets

1. 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

area:1:followers 1 2

area:2:followers 1

Redis como Indice

Page 131: Open Source Modern Web Development

3.1Solución: Sorted Sets

1. 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

area:1:followers 1 2

area:2:followers 1

area:3:followers 4

Redis como Indice

Page 132: Open Source Modern Web Development

3.1Solución: Sorted Sets

1. 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 5

area:1:followers 1 2

area:2:followers 1

area:3:followers 5 4

Redis como Indice

Page 133: Open Source Modern Web Development

3.1

Problema: ¿Usuarios que siguen el area #1?

> GET area:1:followers

area:1:followers 1 2

area:2:followers 1

area:3:followers 5 4

Redis como Indice

Page 134: Open Source Modern Web Development

3.1

Problema: ¿Usuarios que siguen el area #1 o el area #2?

> ZINTERSTORE areas:1-2:followers 2 area:1:followers

area:2:followers AGGREGATE MAX

> GET areas:1-2:followers

area:2:followers 1

area:3:followers 5 4

areas:1-2:followers

area:1:followers 1 2

1 2

Redis como Indice

Page 135: Open Source Modern Web Development

3.1Problema: 25 usuarios que sigan el area #1 o el area #2 promocionando aquellos que tengan avatar.

> ZREVRANGE areas:1-2:followers 0 25

area:2:followers 1

area:3:followers 5 4

area:1:followers 1 2

Redis como Indice

Page 136: Open Source Modern Web Development

3.1Problema: 25 usuarios que sigan el area #1 o el area #2 promocionando aquellos que tengan avatar.

> ZREVRANGE areas:1-2:followers 0 25

area:2:followers 1

area:3:followers 5 4

areas:1-2:followers

area:1:followers 1 2

1 2

Redis como Indice

Page 137: Open Source Modern Web Development

Cliente

Servidor

Canal

Cachear, Delegar, Indexarvarnish, redis, cron, batch...

Reducir request ( número y tamaño )Minify, sprites, gzip, cdn...

Cachear + OptimizarCache, dns lookups, redirects, etags...

Optimización3

Page 138: Open Source Modern Web Development

Canal3.2

Page 139: Open Source Modern Web Development

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 one var 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 bytes

255 bytes (~56%)

Un paso más del proceso de build + deploy

Page 140: Open Source Modern Web Development

--line-break

--type js|css

--charset character-set

--disable-optimizations

$ java -jar yuicompressor.jar file.js -o file-min.js

https://github.com/yui/yuicompressor/

Yahoo YUI compressor

http://refresh-sf.com/yui/

0

1

Page 141: Open Source Modern Web Development

Sprites?

Page 142: Open Source Modern Web Development

N 1

Page 143: Open Source Modern Web Development

A

.sprite-A{

...}

Page 144: Open Source Modern Web Development

A

.sprite-A{ background-image: url(sprite.png);

...}

Page 145: Open Source Modern Web Development

x:120px

y:50px

A

.sprite-A{ background-image: url(sprite.png); background-position: -120px -50px;

...}

Page 146: Open Source Modern Web Development

A

.sprite-A{ background-image: url(sprite.png); background-position: -120px -50px; width: 10px; height: 20px; ...}

20px

10px

Page 147: Open Source Modern Web Development

A<div class=”sprite-A”></div>

Page 148: Open Source Modern Web Development

#1

By hand

Page 149: Open Source Modern Web Development

Rebuild sprites should can must be part of the assets-rebuild *

for 99% of your sprites*

“”

Page 150: Open Source Modern Web Development

Glue$command-line-sprites$command-line-sprites

gluecss.com

Page 151: Open Source Modern Web Development

Drop source images somewhere

Page 152: Open Source Modern Web Development

Drop source images somewhere

$ glue source output

Page 153: Open Source Modern Web Development

Drop source images somewhere

$ glue source output

Party!

Page 154: Open Source Modern Web Development

.sprite-icons-rainbow{ background-image:url(sprite.png); background-repeat:no-repeat; background-position: 247px 147px; width: 25px; height: 25px; } ...

fam fam fam

Page 155: Open Source Modern Web Development

.glyphicons-187-more{ background-image:url(glyphicons.png); background-repeat:no-repeat; background-position: 212px 42px; width: 23px; height: 22px; } ...

glyphish

Page 156: Open Source Modern Web Development

gzip3.2.2

GET /index.htmlAccept-Encoding: gzip

HTTP 1.1 200 OK<html><head> ...

gzip

Servidor

Servidor sin gzip configuradoPese a que el navegador soporte gzip y envíe el header adecuado en la petición, el servidor lo ignora y envía el contenido sin comprimir.

100Kb

Page 157: Open Source Modern Web Development

GET /index.htmlAccept-Encoding: gzip

Servidor con gzip configuradoEstando gzip configurado en el servidor, si los clientes envían los header adecuados, el servidor comprimirá la respuesta utilizando gzip.

HTTP 1.1 200 OKContent-Encoding: gzipkk3s(e?3.sn2isn19fkjnasd...

50Kb

gzip3.2.2

gzip

Servidor

Page 158: Open Source Modern Web Development

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 comprimidos

utilizando codecs más eficientes y resulta una perdida de tiempo y cpu intentar recomprimirlos.

•El 90% del tráfico de internet se genera utilizando navegadores que soportan gzip (Yahoo!)

gzip3.2.2

Page 159: Open Source Modern Web Development

CDN: Content delivery network•Objetivos principales• Distribuir contenido de la manera más eficiente posible a

poder ser desde localizaciones geográficamente cercanas al cliente para reducir la latencia.

• Reducir tráfico de nuestros servidores web distribuyendo el trafico 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

Page 160: Open Source Modern Web Development

Cliente

Servidor

Canal

Cachear, Delegar, Indexarvarnish, redis, cron, batch...

Reducir request ( número y tamaño )Minify, sprites, gzip, cdn...

Cachear + OptimizarCache, dns lookups, redirects, etags...

Optimización3

Page 161: Open Source Modern Web Development

Cliente3.3

Page 162: Open Source Modern Web Development

Speeding up your website

1. CSS y JS en ficheros externos

2. CSS al comienzo

3. JS al final

4. Entre 2 y 4 hostnames

http://developer.yahoo.com/performance/rules.html1

A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy.“

Page 163: Open Source Modern Web Development

dev1

ops2

env3

browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamiento

herramientasbuenas prácticas

Page 164: Open Source Modern Web Development

Arquitectura4

Page 165: Open Source Modern Web Development

$Servidor WebAplicación

Base de datos

✓⚠

SENCILLO

❌✓ OK PARA EMPEZAR

TERMINA SIENDO POCOSPOF

SSL*

Page 166: Open Source Modern Web Development

$Servidor WebAplicación

SENCILLO

❌✓ PUEDE LLEVARTE LEJOS

TERMINA SIENDO POCO

SPOF

$Base de datos

⚠ SPOF

SSL*

Page 167: Open Source Modern Web Development

$Servidor WebAplicación

SENCILLO

❌✓ PUEDE LLEVARTE LEJOS

TERMINA SIENDO POCO

SPOF

$Base de datos

⚠ SPOF

x2

SSL*

Page 168: Open Source Modern Web Development

$Servidor WebAplicación

⚠ SPOF

$Base de datos

⚠ SPOF

$Servidor WebAplicación

⚠ SPOF

DNS ROUND ROBIN

:(SSL* SSL*

Page 169: Open Source Modern Web Development

$Servidor WebAplicación

⚠ SPOF

$Base de datos

⚠ SPOF

$Servidor WebAplicación

⚠ SPOF

DNS ROUND ROBIN

:(SSL* SSL*

Page 170: Open Source Modern Web Development

$Servidor Web

HAProxy

⚠ SPOF

$Base de datos

⚠ SPOF

⚠ SPOF$Servidor Web

Aplicación

⚠ SPOF$Servidor Web

Aplicación

SSL*

Page 171: Open Source Modern Web Development

$Servidor Web

HAProxy

⚠ SPOF

$Base de datos

⚠ SPOF

$Servidor Web

Aplicación

$Servidor Web

Aplicación

SSL*

Page 172: Open Source Modern Web Development

$Servidor Web

HAProxy

⚠ SPOF

$Base de datos

⚠ SPOF

$Servidor Web

Aplicación

$Servidor Web

Aplicación

SSL*

????Host $host; X-Real-IP $remote_addr;X-Forwarded-Proto $scheme;

Page 173: Open Source Modern Web Development

HAProxy4.2Balanceador TCP/HTTPEs uno de los balanceadores de carga más utilizados. Se caracteriza por ser muy 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...

Page 174: Open Source Modern Web Development

global log 127.0.0.1 local0 notice maxconn 4096 user haproxy group haproxy

defaults log global mode http option httplog option dontlognull option redispatch retries 3 contimeout 5000 clitimeout 50000 srvtimeout 50000 stats enable stats auth USER:PASSWORD

backend allservers mode http server web1 192.168.0.11:80 check server web2 192.168.0.12:80 check server web3 192.168.0.13:80 check ...

balance roundrobin option httpchk HEAD /test/ option forwardfor ...

haproxy.cfg

Page 175: Open Source Modern Web Development

Demo HAProxy4A

Page 176: Open Source Modern Web Development

$Servidor Web

HAProxy

⚠ SPOF

$Base de datos

⚠ SPOF

$Servidor Web

Aplicación

$Servidor Web

Aplicación

SSL*

Page 177: Open Source Modern Web Development

High availability4.3Load Balancer

nginx

haproxy

Web #1

nginx

app

Web #2

nginx

app

Web #3

nginx

app⏶

Web #1 33%

Web #2 33%

Web #3 33%

4upexample.com

Page 178: Open Source Modern Web Development

High availability4.3

Web #1

nginx

app

Web #2

nginx

app

Web #3

nginx

app⏶

Web #1 50%

Web #2 50%

Web #3 0%

✓4upexample.com

Load Balancer

nginx

haproxy

Page 179: Open Source Modern Web Development

High availability4.3

Web #1

nginx

app

Web #2

nginx

app

Web #3

nginx

app⏶

Web #1 100%

Web #2 0%

Web #3 0%

⚠4upexample.com

⚠⚠

Load Balancer

nginx

haproxy

Page 180: Open Source Modern Web Development

Load Balancer

nginx

haproxy

High availability4.3

Web #1

nginx

app

Web #2

nginx

app

Web #3

nginx

app⏶

Web #1 33%

Web #2 33%

Web #3 33%

5downexample.com

Page 181: Open Source Modern Web Development

:(

Page 182: Open Source Modern Web Development

DNS

$example.com

$$$$$$

Datacenter

66666666

$176.58.97.9

Page 183: Open Source Modern Web Development

DNS

$example.com

176.58.97.9

$$$$$$

Datacenter

66666666

$176.58.97.9

Page 184: Open Source Modern Web Development

$

6

DNS

$example.com

176.58.97.9

176.58.97.9

$$$$$$

????Datacenter

6666666

Page 185: Open Source Modern Web Development

$

6

DNS

$example.com

176.58.97.9

176.58.97.9

$$$$$$

????Datacenter

6666666

SPOF: Single Point Of Failure

Page 186: Open Source Modern Web Development

High availability4.3ProblemaNecesitamos hacer que nuestro balanceador no sea un un SPOF, Single point of failure.

• En caso de fallo no podemos cambiar la configuración del DNS ya que conllevaría tiempo propagar el cambio.

• No podemos poner otra capa de balanceadores por encima del balanceador ya que tendríamos el mismo problema.

• Hagamos lo que hagamos ha de ser rápido para evitar downtime en la medida de lo posible.

Page 187: Open Source Modern Web Development

$

6

$$$$$$

#1Datacenter

6666666

$176.58.97.9

#2

Page 188: Open Source Modern Web Development

$

6

$$$$$$

#1Datacenter

6666666

$176.58.97.9

#2

Page 189: Open Source Modern Web Development

$

6

$$$$$$

#1Datacenter

6666666

$176.58.97.9

#2

Page 190: Open Source Modern Web Development

Heartbeat♥

Pacemaker8

+

Page 191: Open Source Modern Web Development

Heartbeat♥

Capa de comunicaciónBásicamente es un “bus” que nos asegura que todos los mensajes enviados se envían a todos los miembros del bus y se asegura de que todo el mundo esté de acuerdo sobre quien está o no está conectado.

Page 192: Open Source Modern Web Development

Pacemaker8

AgenteSe encarga de arrancar y parar servicios en función de reglas que nosotros establezcamos. De igual manera, se cerciora de que estos servicios solo se ejecuten en uno de los servidores.

Page 193: Open Source Modern Web Development

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 respawn

Heartbeat4.3Instalación$ apt-get install heartbeat

Comprobar 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

Page 194: Open Source Modern Web Development

Configuración$ cat /etc/heartbeat/authkeysauth 11 sha1 SECRET$ chmod 600 /etc/heartbeat/authkeys

Heartbeat4.3

Hemos de configurar hearbeat en ambos nodos9

Arranque$ service heartbeat start

Estado$ service heartbeat statusheartbeat OK [pid 2332 et al] is running on ha-1.example.com [ha-1.example.com]...

Page 195: Open Source Modern Web Development

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

Page 196: Open Source Modern Web Development

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

Page 197: Open Source Modern Web Development

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

Page 198: Open Source Modern Web Development

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

Page 199: Open Source Modern Web Development

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

Page 200: Open Source Modern Web Development

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

Page 201: Open Source Modern Web Development

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

Page 202: Open Source Modern Web Development

$Servidor Web

HAProxy

$Base de datos

⚠ SPOF

$Servidor Web

Aplicación

$Servidor Web

Aplicación

SSL*

$Servidor Web

HAProxy

SSL*

Page 203: Open Source Modern Web Development

$Servidor Web

HAProxy

$Base de datos

⚠ SPOF

$Servidor Web

Aplicación

$Servidor Web

Aplicación

SSL*

$Servidor Web

HAProxy

SSL*

$Servidor Web

Aplicación

$Servidor Web

Aplicación

$Servidor Web

Aplicación

????

Page 204: Open Source Modern Web Development

$Servidor Web

HAProxy

$Base de datos

Master

$Servidor Web

Aplicación

$Servidor Web

Aplicación

SSL*

$Servidor Web

HAProxy

SSL*

$Servidor Web

Aplicación

$Servidor Web

Aplicación

$Servidor Web

Aplicación

W

WW W W

$Base de datosRead Only

Page 205: Open Source Modern Web Development

$Servidor Web

HAProxy

$Base de datos

Master

$Servidor Web

Aplicación

$Servidor Web

Aplicación

SSL*

$Servidor Web

HAProxy

SSL*

$Servidor Web

Aplicación

$Servidor Web

Aplicación

$Servidor Web

Aplicación

RR R R

R

$Base de datosRead Only

Page 206: Open Source Modern Web Development

Y aún más lejos?Llegados a este punto deberíamos de tener a varias personas trabajando en esto a tiempo completo... pero el resultado podría parecerse algo como....

:

Page 207: Open Source Modern Web Development

$Servidor Web

HAProxy

SSL*

$Servidor Web

HAProxy

SSL*

DNS ROUND ROBIN

$Servidor Web

HAProxy

SSL*

$Servidor Web

HAProxy

SSL*

$Servidor Web

HAProxy

SSL*

$Servidor Web

HAProxy

SSL*

$Servidor Web

Aplicación

$Servidor Web

Aplicación

$Servidor Web

Aplicación

$Servidor Web

Aplicación

$Servidor Web

Aplicación

$Servidor Web

Aplicación

$Servidor Web

Aplicación

$Servidor Web

Aplicación

$Servidor Web

Aplicación

Multi Master DB

$Slave

n n n

n

$Master

$Master

$Slave$

Slave $Slave$

Slave$

Slave$

Slave $Slave

++

Page 208: Open Source Modern Web Development

Servidores Web4.4¿Cuál elijo?Existen docenas de servidores web, cada empresa suele elegir uno en función de las necesidades y features de cada uno.

Nosotros utilizamos nginx dada la sencillez de configuración, la estabilidad, los grandísimos resultados que siempre alcanza en los tests de carga y en particular porque ya hemos trabajado con él y lo conocemos.

En realidad nginx lo utilizamos como reverse proxy tanto en los balanceadores de carga como en los servidores web, así como para hacer “spoon-feeding”.

Page 209: Open Source Modern Web Development

Spoon feeding?

Page 210: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

???????9

Page 211: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

???????9

Page 212: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

???????9

Page 213: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

???????9

Page 214: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

???????9

Page 215: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

???????9

Page 216: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

???????9

Page 217: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

6Usuario

3G

???????9

Page 218: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

6Usuario

3G

6Usuario

EDGE

???????9

Page 219: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

6Usuario

3G

6Usuario

EDGE

6Usuario

GPRS

???????9

Page 220: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

6Usuario

3G

6Usuario

EDGE

6Usuario

GPRS

???????9

Page 221: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

6Usuario

3G

6Usuario

EDGE

6Usuario

GPRS

???????9

Page 222: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

6Usuario

3G

6Usuario

EDGE

6Usuario

GPRS

???????9

Page 223: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

6Usuario

3G

6Usuario

EDGE

6Usuario

GPRS

???????9

Page 224: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

6Usuario

3G

6Usuario

EDGE

6Usuario

GPRS

???????9

Page 225: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

3G

6Usuario

3G

6Usuario

EDGE

6Usuario

GPRS

???????9

Page 226: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

ADSL

6Usuario

3G

6Usuario

EDGE

6Usuario

GPRS

nginx

LAN;

INTERNET;

1Gb/s

Page 227: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

ADSL

6Usuario

3G

6Usuario

EDGE

6Usuario

GPRS

nginx

LAN;

INTERNET;

1Gb/s

2.5Mb/s

Page 228: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

ADSL

6Usuario

3G

6Usuario

EDGE

6Usuario

GPRS

nginx

LAN;

INTERNET;

1Gb/s

236Kb/s

Page 229: Open Source Modern Web Development

$Proceso #1$Proceso #2$Proceso #3$Proceso #4

6Usuario

ADSL

6Usuario

ADSL

6Usuario

3G

6Usuario

EDGE

6Usuario

GPRS

nginx

LAN;

INTERNET;

1Gb/s

60Kb/s

Page 230: Open Source Modern Web Development

✉Emails

La mayoría de los servicios online necesitan enviar emails a sus usuarios. El número de emails que has de enviar crece mucho más rápido de lo que esperas...

Page 231: Open Source Modern Web Development

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 pueden

ahorrarse muchos dolores de cabeza (y ganar otros) externalizando servicios como este .

• Grandes empresas que necesitan enviar millones de emails en épocas concretas y no desean sobre escalar sus sistemas para estas situaciones puntuales.

• 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.

Page 232: Open Source Modern Web Development

dev1

ops2

env3

browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamiento

herramientasbuenas prácticas

Page 233: Open Source Modern Web Development

Deploy5

Page 234: Open Source Modern Web Development

https://github.com/blog/1241-deploying-at-github

Deploying is a big part of the lives of most GitHub employees. We don't have a release manager and there are no set weekly deploys. Developers and designers are responsible for shipping new stuff themselves as soon as it's ready. This means that deploying needs to be as smooth and safe a process as possible.

Page 235: Open Source Modern Web Development

$

$

$ $

$

$ $ $

$ $ $ $

server #1

server #3

server #11 server #12

server #2

server #4 server #5 server #6

server #7 server #8 server #9 server #10

$ $server #11 server #12

$

$

$ $

$

$ $ $

$ $ $ $

server #1B

server #3B

server #11B server #12B

server #2B

server #4B server #5B server #6B

server #7B server #8B server #9B server #10B

$ $server #11B server #12B

staging live

Page 236: Open Source Modern Web Development

$

$

$ $

$

$ $ $

$ $ $ $

server #1B

server #3B

server #11B server #12B

server #2B

server #4B server #5B server #6B

server #7B server #8B server #9B server #10B

$ $server #11B server #12B

live

Page 237: Open Source Modern Web Development

$

$

$ $

$

$ $ $

$ $ $ $

server #1B

server #3B

server #11B server #12B

server #2B

server #4B server #5B server #6B

server #7B server #8B server #9B server #10B

$ $server #11B server #12B

liveactivar modo mantenimiento (503)

desplegar nuevo código

purgar cachés

reiniciar servicios

minimizar javascript

minimizar css

generar sprites

...

desactivar modo mantenimiento

Page 238: Open Source Modern Web Development

Streamlining SSH scriptsfabric

from fabric.api import run

def 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: Linux

Done.Disconnecting from localhost... done.Disconnecting from linuxbox... done.

Page 239: Open Source Modern Web Development

Streamlining SSH scriptsfabric

get(remote_path, local_path=None)

put(local_path=None, remote_path=None, ...)

run(command, ...)

sudo(command, ...)

reboot(wait=120)

local(command, ...)

Page 240: Open Source Modern Web Development

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

Page 241: Open Source Modern Web Development

Agrupación de hosts en rolesfabric

env.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

Page 242: Open Source Modern Web Development

Helpers de interacciónfabric

confirm(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)

Page 243: Open Source Modern Web Development

dev1

ops2

env3

browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamiento

herramientasbuenas prácticas

Page 244: Open Source Modern Web Development

Seguridad6

Page 245: Open Source Modern Web Development

La seguridad es un tema extenso y delicado.Os invitamos a profundizar en cada uno de los aspectos antes de ponerlos en práctica.Los siguientes son sólo ejemplos y pueden contener errores.

Page 246: Open Source Modern Web Development

*iptablesNo lo son todo, pero sin lugar a dudas son un buen comienzo para evitarnos problemas.

Page 247: Open Source Modern Web Development

Funcionamiento iptablesINPUT TRAFFIC

FILTER

NAT

MANGLE

PREROUTINGPREROUTING

FORWARDFORWARD

POSTROUTINGPOSTROUTING

INPUTINPUT

LOCAL

OUTPUTOUTPUTOUTPUT

Forwarding processLocal process

ROUTING

OUTPUT TRAFFIC

Page 248: Open Source Modern Web Development

Funcionamiento iptablesINPUT TRAFFIC

FILTER

NAT

MANGLE

PREROUTINGPREROUTING

FORWARDFORWARD

POSTROUTINGPOSTROUTING

INPUTINPUT

LOCAL

OUTPUTOUTPUTOUTPUT

Forwarding processLocal process

ROUTING

OUTPUT TRAFFIC

Tablas

Cadenas

Page 249: Open Source Modern Web Development

Funcionamiento iptablesINPUT TRAFFIC

FILTER

NAT

MANGLE

PREROUTINGPREROUTING

FORWARDFORWARD

POSTROUTINGPOSTROUTING

INPUTINPUT

LOCAL

OUTPUTOUTPUTOUTPUT

Forwarding processLocal process

ROUTING

OUTPUT TRAFFIC

Page 250: Open Source Modern Web Development

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.

Page 251: Open Source Modern Web Development

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.

Page 252: Open Source Modern Web Development

>FILTER.Tabla responsable del filtrado de paquetes.

☰INPUT

☰OUTPUT

☰FORWARD

Todos 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)

Page 253: Open Source Modern Web Development

>FILTER.Tabla responsable del filtrado de paquetes.

☰INPUT

☰OUTPUT

☰FORWARD

Todos 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)

Page 254: Open Source Modern Web Development

>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

Page 255: Open Source Modern Web Development

fail2ban6.2Fail2ban nos permite bloquear ataques de fuerza bruta contra servicios como ssh, mail, http etc...

• Muy sencillo de instalar y configurar.

• Una buena contramedida activa.

• Su funcionamiento se basa en leer los logs generados por estos servicios utilizando expresiones regulares.

• Además de bloquear el trafico entrante desde estas fuentes se pueden desplegar otras medidas o enviar notificaciones.

!h#p://fail2ban.org

Page 256: Open Source Modern Web Development

SSH [email protected] la cuenta de root es una de las primeras medidas a tomar al configurar un servidor.• Si disponemos de un servicio como fail2ban estaremos impidiendo

en cierta medida que nadie tenga éxito al realizar un ataque de fuerza bruta.

• Si por alguna razón el servicio está caído tendríamos nuestra cuenta de root expuesta.

• Es muy recomendable no permitir conexiones ssh utilizando root.• Una vez en el sistema podemos identificarnos como root o utilizar

sudo.

PermitRootLogin no

/etc/ssh/sshd_config

Page 257: Open Source Modern Web Development

dev1

ops2

env3

browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamiento

herramientasbuenas prácticas

Page 258: Open Source Modern Web Development

Monitoring7

Page 259: Open Source Modern Web Development

You can’t improve

what you don’t measure“

Page 260: Open Source Modern Web Development

top7.1

Page 261: Open Source Modern Web Development

htop7.2

Page 262: Open Source Modern Web Development

munin7.3Ventajas• Muy sencillo de instalar y configurar.• Fácil de crear nuevas gráficas usando

cualquier 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

Page 263: Open Source Modern Web Development

but... What’s next?Llegado el momento las métricas se convierten en críticas para analizar no solo la salud del sistema, si no la del negocio.

;

Page 265: Open Source Modern Web Development

graphite server

graphite

tcp 80☁

Page 266: Open Source Modern Web Development

graphite server

!carbon

graphite

tcp 80☁

Page 267: Open Source Modern Web Development

graphite server

db server

!carbon

graphite

tcp 80☁

Page 268: Open Source Modern Web Development

graphite server

db server

!carbon

graphite

diamond

tcp 80☁

Page 269: Open Source Modern Web Development

graphite server

db server

!carbon

graphite

diamondstatsd

udp 8125

tcp 80☁

Page 270: Open Source Modern Web Development

graphite server

db server

!carbon

graphite

tcp 2003

diamondstatsd

udp 8125

tcp 80☁

Page 271: Open Source Modern Web Development

graphite server

web server db server

!carbon

graphite

tcp 2003

diamondstatsd

udp 8125

diamond statsd

udp 8125

diamond

statsd

udp 8125

tcp 80☁

Page 272: Open Source Modern Web Development

graphite server

web server db server

!carbon

graphite

tcp 2003

diamondstatsd

udp 8125

diamond statsd

udp 8125

diamond

statsd

udp 8125

tcp 80

logslogs

Page 273: Open Source Modern Web Development

graphite server

web server db server

!carbon

graphite

tcp 2003

diamondstatsd

udp 8125

diamond statsd

udp 8125

diamond

statsd

udp 8125

tcp 80

app

logslogs

Page 274: Open Source Modern Web Development

graphite7.4

No sólo datos... conocimiento!Descubrir que la carga de un servidor es 9.3 lo fines de semana a las 3am es útil pero... ¿cual es la causa? ¿Que otros síntomas hay? ¿Algún otro servidor se ve afectado? ¿Qué estaba haciendo el servidor? ¿Cuantos procesos teníamos en marcha? ¿Qué tamaño tenía la cola de emails? ¿Hace cuando que hicimos el último deploy?...

Page 275: Open Source Modern Web Development

graphite7.4

from pystatsd import Client

sc = Client('127.0.0.1', 8125)sc.increment('streetlife.emails.immediate.sent')

Python

echo "streetlife.emails.immediate.sent:1|c" | nc -w 1 -u 127.0.0.1 8125

Bash

Son sólo paquetes UDP.Dado que añadir estadísticas consiste en enviar un simple paquete UDP a nuestro servidor de statsd, podemos hacerlo desde cualquier sitio! Nuestra aplicación, un script en bash ... Fire-and-forget!

Page 276: Open Source Modern Web Development
Page 277: Open Source Modern Web Development
Page 278: Open Source Modern Web Development
Page 279: Open Source Modern Web Development
Page 281: Open Source Modern Web Development

pingdom7.6Yo mi me conmigo...Es muy embarazoso darse cuenta que tu web se ha caído porque te lo diga un cliente. Hay docenas de servicios como pingdom que se dedican a testear tu web 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.

Page 282: Open Source Modern Web Development

dev1

ops2

env3

browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamiento

herramientasbuenas prácticas

Page 283: Open Source Modern Web Development

Provisioning8

Page 284: Open Source Modern Web Development

$server #1

$ ssh user1@server1$ apt-get install paquete_x

Page 285: Open Source Modern Web Development

$server #1

$ ssh user1@server1$ apt-get install paquete_x

$server #2

$ ssh user2@server2$ apt-get install paquete_x

Page 286: Open Source Modern Web Development

$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

Page 287: Open Source Modern Web Development

$ 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

Page 288: Open Source Modern Web Development

$ 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

Page 289: Open Source Modern Web Development

$ 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

Page 290: Open Source Modern Web Development

$

$

$ $

$

$$$$$$$

$ $

server #1

server #3

server #11 server #12

server #2

server #4 server #5 server #6

server #7 server #8 server #9 server #10

server #13 server #14

Page 291: Open Source Modern Web Development

$

$

$ $

$

$ $ $

$ $ $ $

server #1

server #3

server #11 server #12

server #2

server #4 server #5 server #6

server #7 server #8 server #9 server #10

$ $server #11 server #12

$

$

$ $

$

$ $ $

$ $ $ $

server #1B

server #3B

server #11B server #12B

server #2B

server #4B server #5B server #6B

server #7B server #8B server #9B server #10B

$ $server #11B server #12B

live staging

Page 292: Open Source Modern Web Development

$

$

$ $

$

$ $ $

$ $ $ $

server #1

server #3

server #11 server #12

server #2

server #4 server #5 server #6

server #7 server #8 server #9 server #10

$ $server #11 server #12

$

$

$ $

$

$ $ $

$ $ $ $

server #1B

server #3B

server #11B server #12B

server #2B

server #4B server #5B server #6B

server #7B server #8B server #9B server #10B

$ $server #11B server #12B

live 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_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

$ ssh user1@server1$ apt-get install paquete_x

Page 293: Open Source Modern Web Development

Shit hapens happens... a lot.

⚠Repetition leads to boredom,boredom to horrifying mistakes,horrifying mistakes to God-I-wish-I-was-still-bored.

Page 294: Open Source Modern Web Development

Provisioning8.1Automatizar la configuración y mantenimiento de tantos servidores cómo necesitemos.• Generar plantillas que nos permitan generar nuevas máquinas sin mucho

esfuerzo y de manera automatizada.• Solucionar casos de catástrofe total ya que podemos regenerar nuestra

arquitectura en otro datacenter sin problemas.• Todo del código que automatice este proceso se convierte en último

termino en una excelente documentación.• “Code as Infrastructure”

Page 295: Open Source Modern Web Development

Puppet8.2Puppet es junto a Chef uno de los más utilizados.• Nos permite automatizar la configuración de

servidores UNIX y Windows.• El lenguaje que se utiliza puede ser tanto Ruby

como un lenguaje declarativo propio de Puppet en el que se definen tanto recursos del sistema como el estado de los mismos.

• Servicios, usuarios, paquetes, ficheros...• Puppet extrae del sistema información como CPUs,

memoria, discos direcciones IP etc... y compila nuestras plantillas junto a esta información.

• Puede ejecutarse en modo arquitectura con un servicio central encargado de compilar las plantillas o en modo “solo-mode” en el cual se compilan las plantillas en cada servidor.

Page 296: Open Source Modern Web Development

Puppet8.2

Una de las principales características de Puppet frente a otros sistemas de configuración es que es idempotente. Por ejemplo, podemos ejecutarlo cada 30 minutos y cerciorarnos de que todo está tal y como lo hemos definido.

Esta es una gran ventaja dado que además de servirnos como bootstrap para nuevas máquinas, puppet nos permite administrar nuestras máquinas a lo largo de todo su ciclo de vida desde la creación mantenimiento y migración.

Page 297: Open Source Modern Web Development

package

package { 'nginx':ensure => installed,

}presentlatest1.5.3absent

Page 298: Open Source Modern Web Development

package

package { 'nginx':ensure => installed,

}presentlatest1.5.3absent

Page 299: Open Source Modern Web Development

file

file { '/etc/nginx/nginx.conf':source => 'modules/nginx/nginx.conf',owner => 'root',group => 'root',mode => '640',require => Package['nginx'],notify => Service['nginx']

}

????

Page 300: Open Source Modern Web Development

file

file { '/etc/nginx/nginx.conf':source => 'modules/nginx/nginx.conf',owner => 'root',group => 'root',mode => '640',require => Package['nginx'],notify => Service['nginx']

}

????

Page 301: Open Source Modern Web Development

service

service { 'nginx':ensure => running,enable => true,hasstatus => true,hasrestart => true,

}

Page 302: Open Source Modern Web Development

require, notify

Package['nginx']

File['/etc/nginx/nginx.conf']

Service['nginx']

Installed

Created Updated

Page 303: Open Source Modern Web Development

user, groupuser { 'tom':

ensure => present,shell => '/bin/bash',home => '/home/tom',managehome => true,

}

group { 'friends':ensure => present

}

Page 304: Open Source Modern Web Development

nodesnode 'web.example.com' inherits web_node { include munin include python

user { 'tom':ensure => present,shell => '/bin/bash',home => '/home/tom',managehome => true,

} ...}

Page 305: Open Source Modern Web Development

apply

$ puppet apply puppet/manifests/site.pp

Page 306: Open Source Modern Web Development

dev1

ops2

env3

browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamiento

herramientasbuenas prácticas

Page 307: Open Source Modern Web Development

Herramientas9

Page 308: Open Source Modern Web Development
Page 309: Open Source Modern Web Development

Características• Wrapper de virtualbox para crear y destruir máquinas desde la

linea de comandos.• Permite crear “instancias” base para crear máquinas desde un

estado concreto en cuestión de segundos.• Integración con Puppet y Chef entre otros.• Gracias a vagrant y puppet podemos lograr que todos los

miembros del equipo dispongan del mismo setup en local sin mucho quebradero de cabeza.

• La puesta en marcha de nuevos empleados se reduce a minutos en vez de días.

• Gracias a la sencillez de uso podemos crear distintos setup en cuestión de minutos y comprobar su funcionamiento.

• Funciona en todas las plataformas: Linux, OSX y Windows.

Vagrant9.1

Page 310: Open Source Modern Web Development

Añadir un box

Vagrant9.1

$ vagrant box add ubuntu-precise http://bit.ly/ubuntu-precise

Crear una nueva instancia

$ vagrant init ubuntu-precise

Arrancar nuestra nueva máquina virtual

$ vagrant up

!h#p://vagrantbox.es

$ vagrant ssh

Page 311: Open Source Modern Web Development

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) end

config.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) end

end

Múltiples boxes

Page 312: Open Source Modern Web Development

$ vagrant up web[web] VM already created. Booting if it's 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 seconds

vagrant up

Page 313: Open Source Modern Web Development

Git branch model9.2

http://nvie.com/posts/a-successful-git-branching-model/1

Page 314: Open Source Modern Web Development
Page 315: Open Source Modern Web Development

CSS Preprocessors9.3

Page 316: Open Source Modern Web Development
Page 317: Open Source Modern Web Development
Page 318: Open Source Modern Web Development
Page 319: Open Source Modern Web Development
Page 320: Open Source Modern Web Development
Page 321: Open Source Modern Web Development

Chrome Plugins9.4

Hay docenas de plugins que pueden hacer nuestro día a día mucho más sencillo. Estos son algunos de los que encontramos más interesantes, además del inspector que Chrome tiene integrado.

Page 322: Open Source Modern Web Development

User-Agent switcher9.4

Cambiar de User-Agent con dos clicks

Podemos configurar nuestros propios User-Agent.

Page 323: Open Source Modern Web Development

Resolution test9.4

Cambiar el tamaño de la ventana con dos clicks

Page 324: Open Source Modern Web Development

Cache Killer9.4

Mientras esté activo no se utilizará la cache del navegador.

Page 325: Open Source Modern Web Development

Speed tracer9.4

Page 326: Open Source Modern Web Development
Page 327: Open Source Modern Web Development
Page 328: Open Source Modern Web Development
Page 329: Open Source Modern Web Development

dev1

ops2

env3

browserhttpoptimizaciónarquitecturadespliegueseguridadmonitorizaciónprovisionamiento

herramientasbuenas prácticas

Page 330: Open Source Modern Web Development

Buenas prácticas10

Page 331: Open Source Modern Web Development
Page 332: Open Source Modern Web Development

CI: Jenkins10.2CaracterísticasServicio que nos permite automatizar (entre otras cosas) la ejecución de tests, compilación de documentación, generar reports de test coverage...Ejecuciones• Periódicamente• Por cada commit al repositorio.

Configuración• Requiere de un poco de práctica pero

una vez configurado no necesita mucho mantenimiento.

Page 333: Open Source Modern Web Development
Page 334: Open Source Modern Web Development

Hipchat/IRC10.3La comunicación entre los empleados es muy importante (sobre todo cuando no siempre todo el mundo 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...

Page 335: Open Source Modern Web Development

Questions?

Page 336: Open Source Modern Web Development

Recursos

http://www.flickr.com/photos/marceldouwedekker/

http://pygments.org/

http://entypo.com/

Fuentes

http://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-works

http://es.wikipedia.org/wiki/Hypertext_Transfer_Protocol

http://en.wikipedia.org/wiki/List_of_HTTP_header_fields

http://en.wikipedia.org/wiki/MIME_type

http://silex.sensiolabs.org/doc/cookbook/json_request_body.html

http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-1

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4

http://en.wikipedia.org/wiki/HTTP_cookie

http://developer.yahoo.com/performance/rules.html

http://www.tldp.org/HOWTO/SSL-Certificates-HOWTO/x64.html

http://www.varnish-cache.org/docs/3.0/

http://haproxy.1wt.eu/download/1.5/doc/configuration.txt

http://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-servers

http://docs.vagrantup.com/v2/