python使用aiohttp异步框架编写web 并部署到centos上

简介

web框架使用aiohttp,模板引擎jinja2,数据库操作使用aiomysql稍作封装的一个ORM(廖雪峰的教程上提供的 编写ORM)

安装python3.5.2

centos6.4上自带了2.6的Python,YUM命令会依赖python 2.X,下面是安装python 3.5.X 的步骤

  • wget –no-check-certificate http://mirrors.sohu.com/python/3.5.2/Python-3.5.2.tgz
  • tar -zxvf Python-3.5.2.tgz
  • cd Python-3.5.2
  • ./configure –prefix=/usr/local/python3.5 –enable-shared
  • make && make install
  • ln -s /usr/local/python3.5/bin/python3 /usr/bin/python3
  • 此时运行python3命令的话会报错,缺少.so文件,我们需要进行如下操作
  • cp -R /usr/local/python3.5/lib/* /usr/lib64/

安装python3.5.2的时候,会自动把setuptoolspip一起安装了

依赖库

  • /usr/bin/python3 -m pip install aiohttp_jinja2 –trusted-host pypi.douban.com
  • /usr/bin/python3 -m pip install aiomysql –trusted-host * pypi.douban.com
  • /usr/bin/python3 -m pip install aiohttp_session –trusted-host pypi.douban.com
  • /usr/bin/python3 -m pip install cryptography –trusted-host pypi.douban.com
  • /usr/bin/python3 -m pip install –upgrade pip –trusted-host pypi.douban.com

系统默认的python版本依然是2.6,运行pip 带上python3的路径即可。另外搜狐的镜像和豆瓣的资源,速度确实快。。。aiohttp_session会依赖cryptography

部署

将编辑好的代码上传到服务器,Xshell 进入 www 目录,使用nohup命令后台运行..

  • nohup /usr/bin/python3 app.py &
  • exit

    nginx配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    upstream python_app {server 127.0.0.1:9000;}
    server {
    listen 80;
    server_name test.wxwztj.com;
    location / {
    proxy_pass http://python_app;
    }
    location ~* .(gif|jpg|jpeg|png|css|js|ico)$ {
    root /www/web/awesome-python3-webapp/www;
    expires 1h;
    }
    }

必须使用exit退出,直接断开或关闭Xshell,nohup的这条后台进程会挂掉。。。
nohup /usr/bin/python3 test.py >/dev/null 2>&1 & 如果不想输出任何信息,可以在nohup command 后面加上>/dev/null 2>&1,最后末尾加上&结束,只输出错误日志并指定错误输出文件nohup ./program >/dev/null 2>log & 文件名缺省则默认为nohup.out.

界面使用UikitVue.js.Vue的绑定感觉和Angularjs相似,aiohttp也可以编写middleware实现错误处理、验证登录、控制访问权限等。

网站最后效果展示

代码下载

test.py是入口文件,app.py以及其他文件是廖老师的demo。

orm想使用SQLAlchemy异步编程的话,只能使用aiomysql.sa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import asyncio
import sqlalchemy as sa
from sqlalchemy.types import *
from sqlalchemy.sql import func
import time,uuid,hashlib
from aiomysql.sa import create_engine
metadata=sa.MetaData()
users = sa.Table('users', metadata,
sa.Column('id', Integer, primary_key=True),
sa.Column('email',String(50)),
sa.Column('passwd',String(50)),
sa.Column('image',String(500)),
sa.Column('admin',BOOLEAN),
sa.Column('name', String(255)),
sa.Column('created_at',FLOAT())
)
def next_id():
return '%015d%s000' % (int(time.time() * 1000),uuid.uuid4().hex)
def pwd_user(id,passwd):
sha1 = hashlib.sha1()
sha1.update(id.encode('utf-8'))
sha1.update(b':')
sha1.update(passwd.encode('utf-8'))
return sha1.hexdigest()
@asyncio.coroutine
def create_pool(loop,**kw):
global __pool
__pool = yield from create_engine(
host = kw.get('host','127.0.0.1'),
port = kw.get('port',3306),
user = kw['user'],
password = kw['password'],
db = kw['db'],
charset = kw.get('charset','utf8'),
autocommit = kw.get('autocommit',True),
maxsize = kw.get('maxsize',10),
minsize = kw.get('minsize',1),
loop = loop
)
@asyncio.coroutine
def go(in_loop):
yield from create_pool(in_loop,user='root',password='root',db='awesome')
global __pool
with (yield from __pool) as conn:
user_id=next_id()
print(users.insert().values(name='jinja2',id=user_id,passwd=pwd_user(user_id,'123456'),
email='222@qq.com',image='image:blank'))
res = yield from conn.execute(users.select())
for row in res:
print(row)
loop=asyncio.get_event_loop()
loop.run_until_complete(go(loop))
__pool.close()
loop.run_until_complete(__pool.wait_closed())
loop.close()