Gunicorn系列之利用Gunicorn启动项目
Gunicorn是一个基于Python实现的动态Web服务器/Web容器,实现了WSGI协议,可以与Django、Flask等Web框架集成。
1. WSGI协议简单介绍
WSGI全称是 Web Server Gateway Interface。具体来说,WSGI 是一个规范,定义了Python写的动态Web服务器和Application应用程序如何交互。WSGI 最早是在PEP-333中定义的,现在已经移到PEP-3333中。
支持WSGI的Web服务器有Python下的Gunicorn,C下的uWSGI,Aapache下的mod_wsgi。而支持WSGI的Web框架(Web Application)有Django2.X、Flask等。
2. WSGI与ASGI的区别与联系
WSGI只支持同步方式,它的超集ASGI是支持异步的。我们知道从客户端到动态Web服务器走的是HTTP协议,而动态Web服务器到Application应用程序是WSGI/ASGI规范。
而HTTP1.X是请求/响应方式的同步协议,不支持异步,所以它一般与WSGI一起配合使用。而Websocket/HTTP2/HTTP3是支持异步的,所以它一般与ASGI一起配合使用。
支持ASGI规范的Web服务器有Uvicorn,Web框架(Web Application)的有FastAPI,Django3.X。
3. Gunicorn与WSGI
WSGI要求Web服务器实现HTTP和WSGI之间的转换,同时Web框架完成业务逻辑,所以WSGI实现了底层Web服务器与上层业务逻辑的解耦。
因此,不难理解Guncorn的主要功能是:
接收客户端HTTP请求,解析请求,封装成WSGI格式的【environ】的环境变量,传递给Web框架
最后接收Web框架处理结果:WSGI格式的响应,转换成HTTP格式返回给客户端。
4. 通过【python main.py】的方式
该方式,主要用于在开发Gunicorn时,测试其否能正常工作
main.py【如下例子,该文件是我们自己手动实现的py文件】
# main.pyimport multiprocessing
import gunicorn.app.basedef app_handler(environ, start_response):status = '200 OK'response_headers = [('Content-Type', 'text/plain'),]start_response(status, response_headers)# response_body = ['Works fine\n']response_body = []for key, value in environ.items():response_body.append(f'{key}: {value}')response_body.append('\nWorks fine\n')return response_body.encode('utf-8')class APPHandler(object):def __init__(self, environ, start_response):self.environ = environself.start_response = start_responsedef __call__(self, environ, start_response):self.environ = environself.start_response = start_responsedef __iter__(self):data = 'Hello, World!\n'status = '200 OK'response_headers = [('Content-type', 'text/plain'),('Content-Length', str(len(data))),('Foo', 'B\u00e5r'), # Foo: Bår]self.start_response(status, response_headers)yield data.encode("utf-8")class APPServer(gunicorn.app.base.BaseApplication):def __init__(self, app, options=None):self.options = options or {}self.application = appsuper().__init__()def load_config(self):config = {key: value for key, value in self.options.items()if key in self.cfg.settings and value is not None}for key, value in config.items():self.cfg.set(key.lower(), value)def load(self):return self.applicationif __name__ == '__main__':options = {'bind': ['0.0.0.0:6000', '[::]:6000'],'workers': multiprocessing.cpu_count(),}APPServer(app_handler, options).run()# APPServer(APPHandler, options).run()
app handler函数/类:
用于读取客户端请求数据,解析处理后,产生响应;
app handler函数需要的参数:一个为字典变量【environ】,表示环境变量。另一个为函数指针,不是函数调用,该函数【start_response()】用来产生响应体的状态和头部。
同理app handler类的_ call__ 方法也是接收环境变量和函数指针两个参数,与上面相同。另外,该类需要实现_ iter__ 方法,该方法是个生成器,产生HTTP响应。
生产环境中,一般是Web框架的接口文件,不需要我们手动实现。
app server类:
需要继承【gunicorn.app.base.BaseApplication】类;
app server类的参数:一个是app handler函数或者类,另一是server配置参数字典;
app server类实现两了个方法:【load()】和【load_config()】(用于加载配置到server)。
生产环境中,一般是调用【gunicorn.app.wsgiapp】模块完成的。
5. 通过【gunicorn project.wsgi --chdir /path/to/project-root -c /path/to/project-cfg.py】
(1) 该方式就是生产环境中使用Gunicorn来启动项目的正确姿势,与以下命令一致。
python -m gunicorn.app.wsgiapp project.wsgi --chdir /path/to/project-root -c /path/to/project-cfg.py
python -m gunicorn.app.wsgiapp
该命令会让python解释器去【sys.path】所列举的目录中,去查找模块【gunicorn.app.wsgiapp】,所以直接运行【gunicorn】和运行【python -m gunicorn.app.wsgiapp】效果一样。
说白了【gunicorn】作为可执行脚本运行时,其实就是调用【python】去执行源码文件【gunicorn/app/wsgiapp.py】,至于如何实现该功能,以后补上。
project.wsgi
一般是特定web框架,提供给Gunicorn的接口文件,比如Django中的 SomeProject.wsgi模块
project-root
为具体的Web项目根路径。
project-cfg.py
为项目的外部配置文件,必须是.py格式,用于对Gunicorn进行个性化配置,当然也可以通过命令行参数的方式加以配置。
(2) 例如Django项目中的wsgi接口文件如下
# wsgi.py"""
WSGI config for django_demo project.It exposes the WSGI callable as a module-level variable named ``application``.For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
"""import osfrom django.core.wsgi import get_wsgi_applicationos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_demo.settings')application = get_wsgi_application()
假设该django项目位于【/tmp/myporject/】,内容如下
myapp1 myapp2 myproject manage.py
那么我们可以通过以下命令启动此Django项目
gunicorn --chdir /tmp/myproject/ myproject.wsgi
Gunicorn系列之利用Gunicorn启动项目相关推荐
- 2.利用gradle启动项目
windows下安装GRAdle https://www.cnblogs.com/linkstar/p/7899191.html 安装好之后cmd java -version 和 gradle-v 查 ...
- Spring Security系列教程03--创建SpringSecurity项目
前言 在上一章节中,一一哥 已经带大家认识了Spring Security,对其基本概念已有所了解,但是作为一个合格的程序员,最关键的肯定还是得动起手来,所以从本篇文章开始,我就带大家搭建第一个Spr ...
- 破解索尼PS4系列:利用网页漏洞实现相关的ROP攻击(一)
本文讲的是破解索尼PS4系列:利用网页漏洞实现相关的ROP攻击(一), 目前关于PS4的黑客攻击还非常的少,但这并不能说明PS4 系统非常安全,黑客不会对其发动攻击.本文的目的就是找出PS4的一系列漏 ...
- 应用Rational 工具简化基于J2EE的项目(二)启动项目
第二部分:启动项目 Steven Franklin 软件设计师和过程专家 2004 年 3 月 这个有多篇文章组成的系列讲述了如何逐渐的应用 Rational 统一过程(RUP)和其他的 Ration ...
- 如何利用express新建项目(上)
如何利用express新建项目(上) 摘要 这篇文章将讲解了如何快速利用express新建项目 一.express4.x的安装 1. npm install -g express 2. npm ins ...
- 每次启动项目的服务,电脑竟然乖乖的帮我打开了浏览器,100行源码揭秘!
1. 前言 大家好,我是若川.最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12 参与,已进行三个月了,大家一起交流学习,共同进步. 想学源码,极力推荐之前我写的<学习源码整体架 ...
- Java利用jenkins做项目的自动化部署
本地的jekins密码 2722e8ea873b4cf08884c22dff732bab 这篇文章主要介绍了Java利用jenkins做项目的自动化部署,小编觉得挺不错的,现在分享给大家,也给大家做个 ...
- Django学习1---安装Django,创建、启动项目
最近在自己独立开发一套运维管理系统,在一些python的web框架中选择了Django进行开发,在这里把开发过程中的一些操作记录下来,供自己回顾,也供初学django的朋友们参考! 本例是基于pyth ...
- Guns启动项目抛出:脚本错误,flyway执行迁移异常
利用IDEA启动Guns项目的时候,控制台报了一下错误. 1.问题复现过程 (1)第一步:首先用IDEA把guns项目导入 (2)第二步:创建一个数据库:guns (3) 第三步:导入数据库脚本 (4 ...
最新文章
- POJ 2728 Desert King [最优比率生成树]
- linux 内核互斥体,Linux 内核同步(六):互斥体(mutex)
- 网站SEO优化中长尾关键词的特征有哪些?
- 错误处理:安装torch-sparse、torch-spline、torch-scatter、torch-cluster
- jQuery scroll事件
- Web前端开发笔记——第二章 HTML语言 第一节 标签、元素、属性
- html搜索框美化代码单词,CSS 漂亮搜索框美化代码
- index加载显示servlet数据_[WEB篇]-JavaWeb基础与应用-02-Servlet开发
- 【转】C# HttpWebRequest 异常时获取 HttpWebResponse 数据
- 【Python】 数字求和
- java把map值放入vector_Thinking in java基础之集合框架
- 超好用的数学教学软件:几何画板Sketchpad for Mac中文版
- miniC语言编译器设计与实现(编译原理实验课程)
- Android Toast使用的简单小结
- HTML5软件设计大赛,我院成功举行第十七届山东省大学生软件设计大赛 HTML5创意应用命题决赛...
- kdc服务器密码修改,KDC服务安装及配置
- 2022年,Python 编程需要养成这 9 个好习惯
- Problem N: 设计飞机类Plane及其派生类
- 程序员课外拓展013:桌面云涉及到的概念
- 两个经纬度坐标,计算角度