Aiohttp官方文档翻译-服务端-部署

项目部署

aiohttp服务器部署有几个选项:

  • 独立服务器
  • 在nginx,HAProxy或其他反向代理服务器后面运行后端服务器池
  • 反向代理服务器后面使用Gunicorn

独立服务器

该方法非常简单,在某些琐碎的情况下可能是最佳解决方案。但是它并没有利用所有的CPU内核。

要运行多个aiohttp服务器实例,请使用反向代理。

 from aiohttp import web
 
 app = web.Application()
 web.run_app(app)

Nginx+supervisord

在nginx后面运行aiohttp服务器具有许多优点。

  • nginx是理想的前端服务器。它可以防止基于格式错误的http协议等的多种攻击。
  • 在nginx后面运行几个aiohttp实例可以利用所有CPU内核。
  • nginx提供的静态文件比内置的aiohttp静态文件支持要快得多。

但是这种方式需要更复杂的配置。

Nginx

配置HTTP服务器本身

http {
  server {
    listen 80;
    client_max_body_size 4G;

    server_name example.com;

    location / {
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_redirect off;
      proxy_buffering off;
      proxy_pass http://aiohttp;
    }

    location /static {
      # path for static files
      root /path/to/app/static;
    }

  }
}

配置aiohttp上游组

http {
  upstream aiohttp {
    # fail_timeout=0 means we always retry an upstream even if it failed
    # to return a good HTTP response

    # Unix domain servers
    server unix:/tmp/example_1.sock fail_timeout=0;
    server unix:/tmp/example_2.sock fail_timeout=0;
    server unix:/tmp/example_3.sock fail_timeout=0;
    server unix:/tmp/example_4.sock fail_timeout=0;

    # Unix domain sockets are used in this example due to their high performance,
    # but TCP/IP sockets could be used instead:
    # server 127.0.0.1:8081 fail_timeout=0;
    # server 127.0.0.1:8082 fail_timeout=0;
    # server 127.0.0.1:8083 fail_timeout=0;
    # server 127.0.0.1:8084 fail_timeout=0;
  }
}

Supervisord

配置Nginx之后,我们需要启动aiohttp后端。最好使用一些工具在系统重新引导或后端崩溃后自动启动它们。

有很多方法可以做到:Supervisord,Upstart,Systemd,Gaffer,Circus,Runit等。

numprocs = 4
numprocs_start = 1
process_name = example_%(process_num)s

; Unix socket paths are specified by command line.
command=/path/to/aiohttp_example.py --path=/tmp/example_%(process_num)s.sock

; We can just as easily pass TCP port numbers:
; command=/path/to/aiohttp_example.py --port=808%(process_num)s

user=nobody
autostart=true
autorestart=true

aiohttp

假设我们已经正确配置了aiohttp.web.Application,并且端口是通过命令行指定的

# aiohttp_example.py
import argparse
from aiohttp import web

parser = argparse.ArgumentParser(description="aiohttp server example")
parser.add_argument('--path')
parser.add_argument('--port')


if __name__ == '__main__':
    app = web.Application()
    # configure app

    args = parser.parse_args()
    web.run_app(app, path=args.path, port=args.port)

Nginx+Gunicorn

可以使用基于pre-fork worker模型的Gunicorn来部署aiohttp。Gunicorn将您的应用程序启动为用于处理传入请求的工作进程。

与使用Nginx进行部署相反,该解决方案无需手动运行多个aiohttp进程,也无需使用诸如supervisor之类的工具来对其进行监视。

但是在gunicorn下运行aiohttp应用程序会稍微慢一些。

准备环境

示例基于Ubuntu16.04

# 创建应用目录
mkdir myapp
cd myapp
# 创建python虚拟环境
python3 -m venv venv
source venv/bin/activate
# 安装模块
pip install gunicorn
pip install aiohttp

应用

创建一个简单应用

# my_app_module.py
from aiohttp import web

async def index(request):
    return web.Response(text="Welcome home!")


my_web_app = web.Application()
my_web_app.router.add_get('/', index)

应用工厂

作为选择,入口点可以是不接受任何参数并返回应用程序实例的协程

from aiohttp import web

async def index(request):
    return web.Response(text="Welcome home!")


async def my_web_app():
    app = web.Application()
    app.router.add_get('/', index)
    return app

开启Gunicorn

在运行Gunicorn时,您需要提供模块的名称,即my_app_module,以及应用程序或应用程序工厂的名称,即my_web_app,以及作为命令行标志或配置文件提供的其他Gunicorn设置。

在这个示例中

  • --bind标志设置服务器的套接字地址;
  • --worker-class标志告诉Gunicorn我们要使用自定义工作程序子类,而不是Gunicorn默认工作程序类型之一;
  • --workers标志告诉Gunicorn有多少个工作进程用于处理请求。
  • --accesslog标志来启用访问日志

自定义worker子类在aiohttp.GunicornWebWorker中定义

>> gunicorn my_app_module:my_web_app --bind localhost:8080 --worker-class aiohttp.GunicornWebWorker
[2017-03-11 18:27:21 +0000] [1249] [INFO] Starting gunicorn 19.7.1
[2017-03-11 18:27:21 +0000] [1249] [INFO] Listening at: http://127.0.0.1:8080 (1249)
[2017-03-11 18:27:21 +0000] [1249] [INFO] Using worker: aiohttp.worker.GunicornWebWorker
[2015-03-11 18:27:21 +0000] [1253] [INFO] Booting worker with pid: 1253

Gunicorn现在正在运行,并准备为您的应用程序的工作进程提供请求。

如果要使用备用asyncio事件循环uvloop,则可以使用aiohttp.GunicornUVLoopWebWorker类。

日志

aiohttp和gunicorn使用不同的格式来指定访问日志。

默认情况下,aiohttp使用自己的默认值:

'%a %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"'
原文地址:https://www.cnblogs.com/fhkankan/p/13522943.html