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启动项目相关推荐

  1. 2.利用gradle启动项目

    windows下安装GRAdle https://www.cnblogs.com/linkstar/p/7899191.html 安装好之后cmd java -version 和 gradle-v 查 ...

  2. Spring Security系列教程03--创建SpringSecurity项目

    前言 在上一章节中,一一哥 已经带大家认识了Spring Security,对其基本概念已有所了解,但是作为一个合格的程序员,最关键的肯定还是得动起手来,所以从本篇文章开始,我就带大家搭建第一个Spr ...

  3. 破解索尼PS4系列:利用网页漏洞实现相关的ROP攻击(一)

    本文讲的是破解索尼PS4系列:利用网页漏洞实现相关的ROP攻击(一), 目前关于PS4的黑客攻击还非常的少,但这并不能说明PS4 系统非常安全,黑客不会对其发动攻击.本文的目的就是找出PS4的一系列漏 ...

  4. 应用Rational 工具简化基于J2EE的项目(二)启动项目

    第二部分:启动项目 Steven Franklin 软件设计师和过程专家 2004 年 3 月 这个有多篇文章组成的系列讲述了如何逐渐的应用 Rational 统一过程(RUP)和其他的 Ration ...

  5. 如何利用express新建项目(上)

    如何利用express新建项目(上) 摘要 这篇文章将讲解了如何快速利用express新建项目 一.express4.x的安装 1. npm install -g express 2. npm ins ...

  6. 每次启动项目的服务,电脑竟然乖乖的帮我打开了浏览器,100行源码揭秘!

    1. 前言 大家好,我是若川.最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12 参与,已进行三个月了,大家一起交流学习,共同进步. 想学源码,极力推荐之前我写的<学习源码整体架 ...

  7. Java利用jenkins做项目的自动化部署

    本地的jekins密码 2722e8ea873b4cf08884c22dff732bab 这篇文章主要介绍了Java利用jenkins做项目的自动化部署,小编觉得挺不错的,现在分享给大家,也给大家做个 ...

  8. Django学习1---安装Django,创建、启动项目

    最近在自己独立开发一套运维管理系统,在一些python的web框架中选择了Django进行开发,在这里把开发过程中的一些操作记录下来,供自己回顾,也供初学django的朋友们参考! 本例是基于pyth ...

  9. Guns启动项目抛出:脚本错误,flyway执行迁移异常

    利用IDEA启动Guns项目的时候,控制台报了一下错误. 1.问题复现过程 (1)第一步:首先用IDEA把guns项目导入 (2)第二步:创建一个数据库:guns (3) 第三步:导入数据库脚本 (4 ...

最新文章

  1. POJ 2728 Desert King [最优比率生成树]
  2. linux 内核互斥体,Linux 内核同步(六):互斥体(mutex)
  3. 网站SEO优化中长尾关键词的特征有哪些?
  4. 错误处理:安装torch-sparse、torch-spline、torch-scatter、torch-cluster
  5. jQuery scroll事件
  6. Web前端开发笔记——第二章 HTML语言 第一节 标签、元素、属性
  7. html搜索框美化代码单词,CSS 漂亮搜索框美化代码
  8. index加载显示servlet数据_[WEB篇]-JavaWeb基础与应用-02-Servlet开发
  9. 【转】C# HttpWebRequest 异常时获取 HttpWebResponse 数据
  10. 【Python】 数字求和
  11. java把map值放入vector_Thinking in java基础之集合框架
  12. 超好用的数学教学软件:几何画板Sketchpad for Mac中文版
  13. miniC语言编译器设计与实现(编译原理实验课程)
  14. Android Toast使用的简单小结
  15. HTML5软件设计大赛,我院成功举行第十七届山东省大学生软件设计大赛 HTML5创意应用命题决赛...
  16. kdc服务器密码修改,KDC服务安装及配置
  17. 2022年,Python 编程需要养成这 9 个好习惯
  18. Problem N: 设计飞机类Plane及其派生类
  19. 程序员课外拓展013:桌面云涉及到的概念
  20. 两个经纬度坐标,计算角度

热门文章

  1. TOF/结构光camera区别、TOF同时成像深度图、IR图原理?
  2. 使用Java-Maven操作MongoDB增删改查
  3. python如何设置rgb颜色_Python 转换RGB颜色值的示例代码
  4. 原生table 边框重叠 粗细不一样等问题,秒懂,只需几秒就能完成
  5. Android Settings模块
  6. redhat 7配置ftp server
  7. 用php打印出日历_PHP实现简单的日历程序
  8. 基于彩色直方图自适应检测电影镜头切换
  9. 扩充计算机内存是扩充什么,怎么增加电脑内存 三种方法让你电脑内存扩大
  10. Mac-----Tickeys模拟机械键盘音效软件使用