1 / 28

一层一层说网站

一层一层说网站. PYTHON WSGI简介 及 常用中间件. 张沈鹏 42qu.com作者. 著名的洋葱. 请求(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

xia
Download Presentation

一层一层说网站

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

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 <!doctype html> <head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><link href="http://stdyun.net/css/a6hYw~g.css" rel="stylesheet" type="text/css"><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script src="/js/~QFhCQ~s.js"></script><title>张沈鹏(KanRSS.com/码农 行业:互联网)</title></head><body><div id="h"><div class="C"><div id="hnav"><a href="/">首页</a> <a href="/auth/apply">注册</a> <a href="/auth/login">登录</a></div></div></div><div class="C"> <div class="at"> <div class="atimg"> <a href="/auth/login?path=/%40zsp" class="bwc" onclick="return poplogin('/@zsp')"> 追随 </a><div><a href="/@zsp"><img class="img9

  5. Request 常见洋葱核结构 简化图 WSGI Server Nginx DNS Request Parser URL Route Template Control Model

  6. 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' .................

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

  8. 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()

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

  10. 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", ....

  11. 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

  12. 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 ...

  13. 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)

  14. 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)函数的参数吃掉

  15. 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

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

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

  18. 模板 %for i in items: <item> <title>${i['title']}</title> <link>${i['link']}</link> <dc:creator>${i['author']}</dc:creator> <description><![CDATA[${i['desc']}]]></description> <pubDate>${format_rfc822_date(i['pubdate'])}</pubDate> <guid isPermaLink="true">${i['link']}</guid> </item> %endfor

  19. 被遗忘缓存 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) 需要在有改动的时候手工清理

  20. 被遗忘缓存 Template -> memcache -> WSGI Server 页面局部的memcache缓存 <%def name="mycomp" cached="True" cache_timeout="300" cache_type="memcached"> other text </%def> 节省取数据 + 模板的开销 一般自动超时失效

  21. 被遗忘缓存 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响应(比如搜索的自动完成?)

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

  23. 更多更多... • Profile?

  24. 更多更多... • Debug?

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

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

  27. import sys sys.exit()

More Related