http://talks.apsl.net/deploy_python/
bcabezas@apsl.net · @bercab
Concurrencia
Paralelismo
Escalabilidad
Escalabilidad y concurrencia
Introducimos modelos de concurrencia, para exponer problemática y acabar viendo porqué usamos procesos simples, sincronos, bloqueantes.
En términos de peticiones y respuestas web, métricas interesantes:
Y las estadísticas a mirar en el servidor:
Otra forma de verlo: el uso de recursos aumenta y escala con la carga.
Modos de I/O a bajo nivel en Linux:
El proceso principal abre socket, crea procesos hijos y comparte socket con ellos. Cada request handler bloquea esperando conexion.
Num workers?
Decisiones:
http://ruslanspivak.com/lsbaws-part2/
# from the past!
<Location "/mysite/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonOption django.root /mysite
PythonDebug On
</Location>
https://www.python.org/dev/peps/pep-0333/
# simple.py
def app(environ, start_response):
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/plain')] # HTTP Headers
start_response(status, headers)
return ["Hello from ", "simple app", ]
# flaskapp.py
from flask import Flask
from flask import Response
flask_app = Flask('flaskapp')
@flask_app.route('/hello')
def hello_world():
return Response(
'Hello world from Flask!\n',
mimetype='text/plain'
)
app = flask_app.wsgi_app
# djangoapp/views.py
from django.http import HttpResponse
def index(request):
return HttpResponse(
'Hello world from Django!\n',
content_type='text/plain'
)
# djangoapp/urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
url(r'^hello/', 'djangoapp.views.index'),
url(r'^admin/', include(admin.site.urls)),
)
# djangoapp/wsgi.py
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
Tareas a gestionar:
Nuestro app server tendrá varios componentes que se repartirán la responsabilidad de cada tarea.
gunicorn -w 2 flaskapp:app gunicorn -w 2 djangoapp.wsgi:application
.
uwsgi --http :8000 --module flaskapp:app \
--master --processes 4 --threads 2
¿Por qué no usamos sysvinit, upstart, systemd?
groupadd -g 500 creantbits
useradd -g 500 -d /creantbits -m -s /bin/bash creantbits
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh
mkvirtualenv django
workon django
export WORKON_HOME=$HOME/.virtualenvs
PS1="\[\033[01;34m\]\$(basename '$VIRTUAL_ENV')\e[0m$PS1"
pew-new django
pew-workon django
pew-in django python manage.py runserver
http://circus.readthedocs.org/en/latest/
pip install circus
pip install circus-web
[circus]
httpd = True
statsd = True
httpd_host = 0.0.0.0
httpd_port = 8080
[watcher:creantbits]
working_dir = /creantbits/djangoapp
cmd = /usr/local/bin/chaussette --fd $(circus.sockets.creantbits) djangoapp.wsgi.application
#working_dir = /creantbits
#cmd = /usr/local/bin/chaussette --fd $(circus.sockets.creantbits) flaskapp.app
numprocesses = 60
use_sockets = True
uid = django
gid = django
virtualenv = /var/pywww/creantbits/.virtualenvs/creantbits
copy_env = True
[socket:creantbits]
host = 0.0.0.0
port = 8000
[uwsgi]
socket = /tmp/creantbits.sock
http = :8000
chmod-socket = 666
master = true
processes = 4
threads = 5
harakiri = 60
max-requests = 2000
chdir = /creantbits/djangoapp
pythonpath = /creantbits/djangoapp
virtualenv = /creantbits/.virtualenvs/creantbits
#env = DJANGO_SETTINGS_MODULE=djangoapp.settings
#module = django.core.handlers.wsgi:WSGIHandler()
module = djangoapp.wsgi
uid = creantbits
gid = creantbits
vacuum = true
touch-reload = /tmp/creantbits.reload
#static-map = /static=/tmp/static
#static-map = /media=/tmp/media
disable-logging = 0
memory-report = 1
log-master = 1
log-date = 1
log-slow = 1
log-4xx = 1
log-sendfile = 1
log-micros = 0
log-slow = 1
[program:trespamsz]
command = /usr/local/bin/uwsgi --ini /etc/uwsgi-prod.d/trespamsz.ini
directory = /tmp
user=trespamsz
process_name=trespamsz
numprocs=1
autostart=true
redirect_stderr=true
stdout_logfile=/var/log/apps-prod/trespamsz-uwsgi.log
priority=10
umask=002
stopsignal=QUIT
# uwsgi
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
}
# proxy
location / {
include proxy_params;
proxy_pass http://localhost:8000;
}
server {
listen 80;
server_name trespams.com;
access_log /var/log/nginx/trespamsz-access.log;
error_log /var/log/nginx/trespamsz-error.log;
location / {
uwsgi_pass unix:/var/pywww/trespamsz/nginx.sock;
include uwsgi_params;
}
location /media/trespamsz {
root /var/www;
expires max;
access_log off;
}
location /static/trespamsz {
root /var/www;
expires max;
access_log off;
}
location ~ /\.hg {
deny all;
}
}
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;
keepalive_timeout 15;
https://github.com/APSL/deploy_talk
Thanks to:
Table of contents | t |
---|---|
Exposé | ESC |
Autoscale | e |
Full screen slides | f |
Presenter view | p |
Source files | s |
Slide numbers | n |
Blank screen | b |
Notes | 2 |
Help | h |