Presentation is loading. Please wait.

Presentation is loading. Please wait.

一层一层说网站 PYTHON WSGI 简介 及 常用中间件 张沈鹏 42qu.com 作者. 著名的洋葱.

Similar presentations


Presentation on theme: "一层一层说网站 PYTHON WSGI 简介 及 常用中间件 张沈鹏 42qu.com 作者. 著名的洋葱."— Presentation transcript:

1 一层一层说网站 PYTHON WSGI 简介 及 常用中间件 张沈鹏 42qu.com 作者

2 著名的洋葱

3 请求 (Request) 的构成 1. 网址 : 用户输入 2. COOKIE: 网站设置 3. 其他 HTTP 头 : 浏览器 GET /@zsp HTTP/1.1 Host: kanrss.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-cn,zh;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Cookie: B=kwyP64YM; __utma=5797929.751142743.1280312171.1280312171.1280312171.1; __utmb=5797929.5.10.1280312171; __utmz=5797929.1280312171.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); Hm_lvt_fc05ad55c7dcadfd714baf512f9146b3=1280312172072; Hm_lpvt_fc05ad55c7dcadfd714baf512f9146b3=1280312287556; __utmc=5797929 Cache-Control: max-age=0

4 响应 Response 构成 HTTP/1.1 200 OK Server: nginx/0.7.65 Date: Wed, 28 Jul 2010 10:24:29 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive Content-Encoding: gzip Content-Length: 6241 张沈鹏 (KanRSS.com/ 码农 行业 : 互 联网 ) 首页 注册 登录 追随 <img class="img9

5

6 常见洋葱核结构 简化图 Request Parser Model Control URL RouteTemplate WSGI Server Request Nginx DNS

7 CGI -> WSGI http://www.python.org/dev/peps/pep-0333/ def run_with_cgi(application): environ = dict(os.environ.items()) environ['wsgi.input'] = sys.stdin environ['wsgi.errors'] = sys.stderr environ['wsgi.version'] = (1,0) environ['wsgi.multithread'] = False environ['wsgi.multiprocess'] = True environ['wsgi.run_once'] = True if environ.get('HTTPS','off') in ('on','1'): environ['wsgi.url_scheme'] = 'https' else: environ['wsgi.url_scheme'] = 'http'.................

8 os.environ http://angeloce.javaeye.com/blog/523242 REQUEST_METHOD -> GET 或 POST PATH_INFO -> /xxx/xx QUERY_STRING -> 在 "?" 后面的请求 URL 部分. 可以为空 HTTP_ Variables -> 与客户端支持的 HTTP 请求头一致的变量.( 也就是 以 "HTTP_" 开头命名的变量.) 这些变量是否出现都要与 HTTP 请求头 中的变量保持一致................

9 WSGI Server import tornado.wsgi import tornado.httpserver import tornado.ioloop def WSGIServer(port, application): container = tornado.wsgi.WSGIContainer(application) http_server = tornado.httpserver.HTTPServer(container) http_server.listen(port) tornado.ioloop.IOLoop.instance().start()

10 洋葱核 def app(environ, start_response): status = '200 OK' response_headers = [ ('Content-type','text/plain'), ] start_response(status, response_headers) return ['Hello'] 1. environ 2. start_response 3. return ['xxxx']

11 Request Parser yaro - Yet Another Request Object http://lukearno.com/projects/yaro/ 1. 简化 environ 的访问 environ['QUERY_STRING'] hl=zh-CN&source=hp&q=python&aq=f&aqi=&aql=&oq=&gs_rfai= -> req.query = { "hl":"zh-CN", "source":"hp",....

12 Request Parser 2. 封装 start_response status = '200 OK' response_headers = [ ('Content-type','text/plain'), ] start_response(status, response_headers) return ['Hello'] -> from yaro import Yaro @Yaro def hello_world(req): return "Hello World!" 当然, 也被封装一些状态码 yaro.Request.redirect("/xxx/xxx/xxx") 301 status

13 URL Route URL -> Python Function http://kanrss.com/at/cloudwu/t/1270561 -> mysite/ctrl/at/__init__.py @route_render_func def t(id=None): owner = request.owner...

14 URL Route 常用方式 正则匹配 application = tornado.web.Application([ (r"/", MainHandler), (r"/story/([0-9]+)", StoryHandler), ]) class StoryHandler(tornado.web.RequestHandler): def get(self, story_id): self.write("You requested the story " + story_id)

15 Url Route -- 文件路径映射 http://mayoufour.googlecode.com/svn/trunk/mypylib/mypy/urlroute.py 创意衍生自 Quixote 查找映射的函数 = { 路径 1 :{ 路径 2:{ 模块名 : 函数名称 } "/at/cloudwu/t/1270561".split("") -> 'at', 'cloudwu', // 被当作 at._access(id) 函数的参数吃掉 't', '1270561', // 被当作 at.t(id) 函数的参数吃掉

16 Model 表 的 映射 CREATE TABLE `user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varbinary(24) NOT NULL, `url` varbinary(60) DEFAULT NULL, `ver` tinyint(3) unsigned NOT NULL DEFAULT '0', `state` tinyint(3) unsigned NOT NULL DEFAULT '40', PRIMARY KEY (`id`), UNIQUE KEY `url` (`url`), KEY `state` (`state`), KEY `name` (`name`) ) -> user.name, user.state

17 Model 表的行为 ban_user -> 设置 user.state + 删除 user_session 使其退出登录 表 与的 表 互动 table user table user follow -> def follower_by_user_id(user_id):....

18 Control 1. 提交表单的数据格式效验 2. 从 Model 获取页面需要的数据 3. 权限不对的时候 给出错误提示 if not user.can_admin(group): G.error = " 你没有权限管理该小组 " -- 传递变量 --> 模板

19 模板 %for i in items: ${i['title']} ${i['link']} ${i['author']} ${format_rfc822_date(i['pubdate'])} ${i['link']} %endfor

20 被遗忘缓存 Model -> memcache -> Control 1. 缓存 id 列表 mc_book_section_id_ordered_can_view = McCacheA("BookSectionIdOrderedCanView:%s") @mc_book_section_id_ordered_can_view("{id}") def book_section_id_ordered_can_view(id): book_list = book_section_ordered(id) return [ i.id for i in book_list if i.can_view ] 2. 缓存对象 user_list = User.mc_get_list(user_id_list) 需要在有改动的时候手工清理

21 被遗忘缓存 Template -> memcache -> WSGI Server 页面局部的 memcache 缓存 other text 节省取数据 + 模板的开销 一般自动超时失效

22 被遗忘缓存 WSGI Server -> Nginx Proxy Cache ->... server_name rss_group.kanrss.com; location ~ ^/(\d+)$ { proxy_pass http://kanrss/vgroup/$1/rss_feed; proxy_cache KFS; proxy_cache_valid 200 304 301 302 30m; proxy_cache_valid any 1m; proxy_cache_key "$host$request_uri"; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; } 比如 RSS (firefox 会检查收藏夹中的 rss 更新 -> 压力不小 ) 比如 一些不经常变的 Ajax 响应 ( 比如搜索的自动完成 ?)

23 还没有说的... 辅助开发 WEB 前端优化 异步运行 长连接 OpenID...........

24 更多更多... Profile?

25 更多更多... Debug?

26 更多更多... Auto Restart ? https://mayoufour.googlecode.com/svn/trunk/mypylib/mypy/reloader.py https://mayoufour.googlecode.com/svn/trunk/mypylib/mypy/reload_server.py

27 42 qu.com 区 找到给你答案的人

28 import sys sys.exit()


Download ppt "一层一层说网站 PYTHON WSGI 简介 及 常用中间件 张沈鹏 42qu.com 作者. 著名的洋葱."

Similar presentations


Ads by Google