设为首页 收藏本站
查看: 446|回复: 0

[经验分享] python WSGI

[复制链接]

尚未签到

发表于 2017-4-21 09:55:56 | 显示全部楼层 |阅读模式
  WSGI是作为Web服务器与Web应用程序或应用框架之间的一种低级别的接口 。WSGI is the Web Server Gateway Interface. It is a specification for web
servers and application servers to communicate with web applications
(though it can also be used for more than that
  WSGI有两方:“服务器
”或“网关”一方,以及“应用程序”或“应用框架”一方。WSIG架构:
  
DSC0000.gif
  WSGI
中间件
同时实现了API的两方,因此可以在WSGI服务和WSGI应用之间起调解作用,“中间件”组件可以执行以下功能:


  • 重写环境变量
    后,根据目标URL
    ,将请求消息路由到不同的应用对象。
  • 允许在一个进程
    中同时运行多个应用程序或应用框架。

  • 负载均衡
    和远程处理,通过在网络
    上转发请求和响应消息。
  • 进行内容后处理,例如应用XSLT
    样式表。
  用Python
语言写的一个符合WSGI的“Hello World
”应用程序如下所示:

def hello_world_app(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return "Hello world!\n"

  • 第一行定义了一个名为app的callable,
    接受两个参数,environ和start_response,environ是一个字典包含了CGI中的环境变量,start_response也是一
    个callable,接受两个必须的参数,status(HTTP状态)和response_headers(响应消息的头)。
  • 第二行调用了start_response,状态指定为“200 OK”,消息头指定为内容类型是“text/plain”
  • 第三行将响应消息的消息体返回。
  调用这个程序

from wsgiref.simple_server import make_server
httpd = make_server('', 8080, hello_world_app)
print "Serving on port 8080..."
# Serve until process is killed
httpd.serve_forever()
   完整的代码:

#/bin/py
from wsgiref.simple_server import make_server
def hello_world_app(environ, start_response):
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/plain')] # HTTP Headers
start_response(status, headers)
# The returned object is going to be printed
return ["Hello World"]
httpd = make_server('', 8080, hello_world_app)
print "Serving on port 8080..."
# Serve until process is killed
httpd.serve_forever()
  访问地址: http://localhost:8080/
  参考
  http://smartzxy.iteye.com/blog/734050
  http://zh.wikipedia.org/wiki/Web%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%BD%91%E5%85%B3%E6%8E%A5%E5%8F%A3
  更多关于BaseServer的解释:
  BaseServer: 定义基础服务器接口,这些功能接口提供给子类继承。同时提供服务处理的骨架

serve_forever()  循环调用 handle_request()

handle_request()  调用子类的get_request() ,在tcpServer时实则进行accept()应答; 验证处理 verify_request();

最终处理请求 process_request(),

verify_request()   虚函数

process_request()  虚函数,这个函数并没有直接在BaseServer的子类TcpServer中被重载,而是在TcpServer的派生类中通过另一个父类来实

现,比如 ThreadingTCPServer的基类ThreadingMixIn.process_request()实现了此功能函数

finish_request(request, client_address)
执行一次完整的socket数据读入处理,如果是ThreadMixInTcpServer产生的request,这个方法内必须实行循环读取
socket数据,直到socket关闭。(此处 request 就是 socket对象)

def finish_request(self, request, client_address):

“”"Finish one request by instantiating RequestHandlerClass.”"”

self.RequestHandlerClass(request, client_address, self)在finish_request里面便将读取socket数据的任务扔给了RequestHandler去处理了,代码可以跳过去看了

##———————————————
  TcpServer:  tcp服务器

__init__(self, server_address, RequestHandlerClass) 需要提供服务侦听地址和请求处理类对象

server_bind() 绑定服务器地址

server_activate() 激活服务器

server_close()  关闭服务器

fileno()  返回服务器socket的句柄fd编号

get_request() 接收应答accept()

close_request(request) 关闭socket,request即为socket对象
  三种输出处理方式: 阻塞方式、线程处理(ThreadingMixIn)、进程处理(ForkingMixIn)
  ThreadingMixIn: 线程模型

process_request( request, client_address) 为请求的链接创建新的线程,在创建线程时直接指定线程入口和参数:

import threading

t = threading.Thread(target = self.process_request_thread,

args = (request, client_address))

if self.daemon_threads:

t.setDaemon (1)process_request_thread() 线程处理socket入口,负责接收数据,代码实现有点绕,看看代码

def process_request_thread(self, request, client_address):

try:

self.finish_request(request, client_address)

self.close_request(request)

except:

self.handle_error(request, client_address)

self.close_request(request)ThreadingMixIn其实就是线程代理,
还是调用finish_request()进入处理tcp数据的循环,处理完成便close_request()。但是finish_request和
close_request并未在ThreadingMinxIn内定义,在哪里呢?
通过研读ThreadingTcpServer,原来通过ThreadingTcpServer这个finish_request又跑回了
BaseServer.finish_request()
  ThreadingTCPServer(ThreadingMixIn, TCPServer) 装配成线程池处理的tcp服务器
  BaseRequestHandler:  请求处理基础对象,提供统一的行为接口实现处理socket数据。
BaseRequestHandler比较好玩,在构造函数内完成了所有的操作,见代码: def __init__(self, request,
client_address, server):

self.request = request

self.client_address = client_address

self.server = server

try:

self.setup()

self.handle()

self.finish()

finally:

sys.exc_traceback = None    # Help garbage collectionsetup()对应的子类会进行初始化处理

self.handle()  直接调用子类的处理函数,可以参考 BaseHTTPRequestHandler(SocketServer.StreamRequestHandler)::handle()
  StreamRequestHandler(BaseRequestHandler) 流式socket处理类

setup() 设置好socket对象和读写文件句柄 rfile/wfile
  HTTPServer(SocketServer.TCPServer) http服务器
  BaseHTTPRequestHandler(SocketServer.StreamRequestHandler) 流式的请求处理类

handle() 处理入口,在基类BaseRequestHandle()的构造函数中直接调用

handle_one_request() 如果不是处理一次则返回false。接收一次socket数据,解析parse_request(),调用对应的do_xxx事件
  python 的daemon线程:
  如果一个进程的主线程运行完毕而子线程还在执行的话,那么进程就不会退出,直到所有子线程结束为止,如何让主线程结束的时候其他子线程也乖乖的跟老
大撤退呢?那就要把那些不听话的人设置为听话的小弟,使用线程对象的setDaemon()方法,参数为bool型。True的话就代表你要听话,我老大
(主线程)扯呼,你也要跟着撤,不能拖后腿。如果是False的话就不用那么听话了,老大允许你们将在外军命有所不受的。需要注意的是
setDaemon()方法必须在线程对象没有调用start()方法之前调用,否则没效果。

转载过来以后用

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-367217-1-1.html 上篇帖子: python test3 下篇帖子: python学习之旅
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表