Blog | Phodal - A Growth Engineerhttp://www.phodal.com/blog/2015-02-02T13:26:59.058183+00:00BlogPeewee falcon打造高性能python RESTful服务(三)——集成2015-02-02T13:19:43+00:002015-02-02T13:26:59.058183+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/use-falcon-peewee-build-high-performance-restful-services-wordpress/这是一个很简单的博客系列,太长了似乎也不合适。
最后的代码可以见[https://github.com/phodal/falcon-wordpress](https://github.com/phodal/falcon-wordpress)
##Falcon Peewee 集成
我们还要做的就是建一个RESTful Server,有了前面的基础剩下的事情已经很简单了。
在我们的``server.py``大概有下面的内容:
import falcon
from gevent import monkey
from gevent.wsgi import WSGIServer
from api.resources import PostsResource, AllPostsResource, CommentsResource, PostsCommentsResource
def main():
monkey.patch_thread()
api = falcon.API()
api.add_route('/posts/{post_id}', PostsResource())
api.add_route('/posts/{post_id}/comments', PostsCommentsResource())
api.add_route('/comment/{comment_id}', CommentsResource())
api.add_route('/all/posts', AllPostsResource())
server = WSGIServer(('0.0.0.0', 8000), api)
server.serve_forever()
gevent在这里的目的就是为了和gunicorn一起使用,方便部署。
简单地看一下依照ID取posts
class PostsResource():
def __init__(self):
pass
@staticmethod
def on_get(req, resp, post_id):
post = WpPosts.get(WpPosts.id == post_id)
user = WpUsers.get(WpUsers.id == post.post_author)
resp.status = falcon.HTTP_200
resp.body = json.dumps({"post_content": post.post_content,
"author": user.display_name})
过程似乎就是这么简单,因为构建一个RESTful Services不是一件很麻烦的事,当你已经选好框架、语言、数据库的时候。
##部署
Run
gunicorn server:app -k geventPeewee falcon打造高性能python RESTful服务(二)——Peewee初入2015-02-02T13:07:16+00:002015-02-02T13:18:42.483380+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/use-falcon-peewee-build-high-performance-restful-services-use-peewee/Peewee是一个易用轻巧的ORM。
##Peewee简介
> Peewee is a simple and small ORM. It has few (but expressive) concepts, making it easy to learn and intuitive to use.
而ORM则是
> 对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。
##Python Peewee
官网来的示例很糟糕,一个简化的示例如下所示:
from peewee import *
import datetime
db = SqliteDatabase('my_database.db', threadlocals=True)
class BaseModel(Model):
class Meta:
database = db
不过,却也提供了几个很实用的模型构建脚本。
##Peewee pwiz 模型生成
> pwiz is a little script that ships with peewee and is capable of introspecting an existing database and generating model code suitable for interacting with the underlying data. If you have a database already, pwiz can give you a nice boost by generating skeleton code with correct column affinities and foreign keys.
类似的示例有一个:
python -m pwiz --engine=postgresql my_postgresql_database
而我是用它来生成WordPress的模型,于是有:
python -m pwiz -e mysql "MK_xunzhao" -uroot > blog_models.py
就这样我们生成了WordPress的Models
接着我们要做的就是一个简单的查询。
##Peewee WordPress
下面是WordPress的wp_posts生成的models
class WpPosts(BaseModel):
id = BigIntegerField(db_column='ID', primary_key=True)
comment_count = BigIntegerField()
comment_status = CharField()
guid = CharField()
menu_order = IntegerField()
ping_status = CharField()
pinged = TextField()
post_author = BigIntegerField(index=True)
post_content = TextField(index=True)
post_content_filtered = TextField()
post_date = DateTimeField()
post_date_gmt = DateTimeField()
post_excerpt = TextField()
post_mime_type = CharField()
post_modified = DateTimeField()
post_modified_gmt = DateTimeField()
post_name = CharField(index=True)
post_parent = BigIntegerField(index=True)
post_password = CharField()
post_status = CharField()
post_title = TextField(index=True)
post_type = CharField()
to_ping = TextField()
class Meta:
db_table = 'wp_posts'
而我们查询语句对应的便是:
blog_posts = WpPosts.select().where(
(WpPosts.post_status == "publish") &
(WpPosts.post_type == "post")
).offset(offset).limit(10)
Peewee falcon打造高性能python RESTful服务(一)——Falcon初入2015-01-29T12:41:11+00:002015-01-29T13:16:40.818220+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/user-falcon-peewee-build-high-performance-restful-services/之前用nodejs打造过一个编辑发布分离的博客。想着从头打造一个编辑发布分离网站,才发现原来自己的时间没有那么充足。于是先从打造一个RESTful做起,。。
##RESTful 性能对比
网上找了一个RESTful框架的性能对比,发现falcon已经表现得不错了。至少是在python中是最好的
Framework|best|vs|Platform|best|Ratio
------|-------|--|-------|-------|-----
gemini|914,749|vs|servlet|831,515|110.0%
start|51,235|vs|dart|54,896|93.3%
stream|50,310|vs|dart|54,896|91.6%
beego|297,377|vs|go|348,555|85.3%
revel|284,683|vs|go|348,555|81.7%
falcore|274,991|vs|go|348,555|78.9%
falcon|171,773|vs|wsgi|220,602|77.9%
ringojs-conv|82,404|vs|ringojs|106,037|77.7%
bottle|159,153|vs|wsgi|220,602|72.1%
再看看官网的一个对比
Framework|req/sec|μs/req|Performance
------|-------|------|--|--
Falcon|(0.1.8)|24,358|41|8x
Bottle|(0.11.6)|13,623|73|4x
Pecan|(0.4.4)|6,604|151|2x
Werkzeug|(0.9.4)|5,163|194|2x
Flask|(0.10.1)|3,041|329|1x
虽然没有看懂,但是这个意思明显就是这个框架性能不错。
##Falcon Framework
官网有这么一个简介没有看懂
> Unburdening cloud apps for over 2.07 x 10-2 centuries.
###falcon安装
pip install falcon
有下面的结果:
Downloading/unpacking falcon
Downloading falcon-0.1.10.tar.gz (59kB): 59kB downloaded
Running setup.py (path:/Users/fdhuang/test/build/falcon/setup.py) egg_info for package falcon
WARNING: Cython not installed. Falcon modules will still work fine, but will run a bit slower.
Requirement already satisfied (use --upgrade to upgrade): six in /Users/fdhuang/test/lib/python2.7/site-packages (from falcon)
Requirement already satisfied (use --upgrade to upgrade): python-mimeparse in /Users/fdhuang/test/lib/python2.7/site-packages (from falcon)
Installing collected packages: falcon
Running setup.py install for falcon
WARNING: Cython not installed. Falcon modules will still work fine, but will run a bit slower.
Installing falcon-bench script to /Users/fdhuang/test/bin
Successfully installed falcon
Cleaning up...
才意识到我要先安装cython,这就是为什么这货速度这么快的原因么?
WARNING: Cython not installed. Falcon modules will still work fine, but will run a bit slower.
###安装Cython
pip install cython
##falcon示例
官方有一个简单的示例
import falcon
class ThingsResource:
def on_get(self, req, resp):
"""Handles GET requests"""
resp.body = ('\nI've always been more interested in\n
'the future than in the past.\n'
'\n'
' ~ Grace Hopper\n\n')
app = falcon.API()
things = ThingsResource()
app.add_route('/things', things)
和flask看上去区别不大,后面发现区别真tmd大。
如果我们的这个``server.py``是基于``flask``的话,那么:
python server.py
就可以启动我们地server,于是我试了试,发现什么也没有返回。。
##falcon gunicorn示例
官网是这样子写到的
> The falcon.API class instances are WSGI applications and can be run with any WSGI server
我们要这样去写
gunicorn things:app
瞬间觉得ciao了,也只能
gunicorn server:app
去运行了。。。