1. Gunicorn基本介绍

Gunicorn是一个基于Python实现的动态Web服务器,实现了WSGI协议,可以与Django、Flask等Web框架集成。

与Apache、Nginx等静态Web服务器相比,Gunicorn动态处理能力强。可以通过HTTP或者Unix Socket来与之通信,以此实现动静分离。

Gunicorn由于源码调用了fcntl、fork等接口,因此只能跑在类Unix系统上,Windows上跑不了。

Gunicorn通过pre-worker模型来实现并发,worker的工作模式有sync、gthread、gevent等,即可以通过多线程、或者协程来处理请求。

Gunicorn是可配置的,可以通过命令行参数或者配置文件的形式,来完成对其配置。

Gunicorn的日志功能丰富,可以输出到控制台、日志文件或者syslog服务器,另外日志分为http请求访问日志和程序运行时的错误日志,这点借鉴了Apache的思路。

2. Gunicorn源码结构【版本为 20.0.4】

可发现源码文件34个,总行数为7867行,不到万行。定义了147个类,75个函数,43个全局变量。
├── app                   【与Web框架通信相关】
│   ├── base.py
│   ├── __init__.py
│   ├── pasterapp.py
│   └── wsgiapp.py
├── arbiter.py            【master进程,在gunicorn中叫arbiter】
├── config.py             【配置相关,可以通过命令行参数、配置文件等方式来配置guniconrn】
├── debug.py
├── errors.py
├── glogging.py           【产生的日志,可以发送到屏幕或者日志文件(access和error)】
├── http                  【处理客户端发送过来的http请求】
│   ├── body.py
│   ├── errors.py
│   ├── __init__.py
│   ├── message.py
│   ├── parser.py
│   ├── unreader.py
│   └── wsgi.py
├── __init__.py
├── instrument
│   ├── __init__.py
│   └── statsd.py
├── pidfile.py            【gunicorn运行时的进程编号,可以写到一个文件】
├── reloader.py
├── sock.py               【gunicorn作为动态Web服务器,需要使用socket】
├── systemd.py
├── util.py               【工具性函数和类】
└── workers               【pre-worker模型中,worker有syncgthreadggevent等模式】├── base_async.py├── base.py├── geventlet.py├── ggevent.py├── gthread.py├── gtornado.py├── __init__.py├── sync.py└── workertmp.py

3. Gunicorn源码关系图

4. 如何启动 Gunicorn Server

从源码关系图中可知,Gunicorn server有两种启动方式【源码关系图中最左侧】

(1)通过【python main.py】的方式【图中左侧下半部】

该方式,主要用于在开发Gunicorn时,测试Gunicorn是否能正常工作

main.py【如下官网的例子】

该文件是我们自己手动实现的py文件,里面至少要实现一个app handler函数或者app handler类和一个app server类。

app handler函数/类:

用于读取客户端请求数据,解析处理后,产生响应;
app handler函数需要的参数:一个为字典变量【environ】,表示环境变量。另一个为函数指针,不是函数调用,该函数【start_response()】用来产生响应体的状态和头部。
同理app handler类的_call__ 方法也是接收环境变量和函数指针两个参数,与上面相同。另外,该类需要实现_iter__ 方法,该方法是个生成器,产生HTTP响应。

app server类:

需要继承【gunicorn.app.base.BaseApplication】;app server类的参数:一个是app handler函数或者类,另一是server配置参数字典;app server类需要实现两个方法:【load()】和【load_config()】(用于加载配置到server)。

# 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 finen']response_body = []for key, value in environ.items():response_body.append(f'{key}: {value}')response_body.append('nWorks finen')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', 'Bu00e5r'),  # 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()

(2)通过【gunicorn project.wsgi --chdir /path/to/project-root -c /path/to/project-cfg.py】【源码关系图中左侧上半部】

该方式,就是生产环境中使用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进行个性化配置,当然也可以通过命令行参数的方式加以配置。

例如Django项目中的wsgi接口文件如下,假设该django项目位于【/tmp/myporject/】,内容如下

myapp1 myapp2 myproject  manage.py

那么我们可以通过以下命令启动此Django项目

gunicorn --chdir /tmp/myproject/ myproject.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()

syslog源码_Gunicorn源码分析01--目录结构相关推荐

  1. Solr6.7 学习笔记(01) -- 目录结构

    Solr解压后的目录结构 --contrib: Solr的一些扩展 --analysis-extras: 包含一些文本分析组件及其依赖 --clustering: 包含一个用于集群搜索结果的引擎 -- ...

  2. php 框架获取服务器,Thinkphp 框架基础之源码获取、环境要求与目录结构分析

    本文实例讲述了Thinkphp 框架基础之源码获取.环境要求与目录结构.分享给大家供大家参考,具体如下: 获取ThinkPHP 获取ThinkPHP的方式很多,官方网站(http://thinkphp ...

  3. plink源码_putty源码阅读----plink

    一直对ssh协议的各种客户端实现比较入迷,遍寻了很多ssh协议实现也用了很多的库,发现依赖太多 putty是最纯洁依赖第三方几乎为0的客户端实现,先从plink处开始入手. 1.putty目录 才刚开 ...

  4. 【转】Spring AMQP 源码分析 01 - Impatient

    转自首夜盲毒预言家的文章 Spring AMQP 源码分析 01 - Impatient ### 准备 ## 目标 了解 Spring AMQP 核心代码 ## 前置知识 RabbitMQ 入门 ## ...

  5. 【Busybox】Busybox源码分析-01 | 源码目录结构和程序入口

    文章目录 一.Busybox简介 (1-1)开源项目 (1-2)程序本体较小 (1-3)使用简单 二.Busybox源码目录结构 三.Busybox程序主体 四.Busybox程序运行剖析

  6. 【中级】 微信小程序 - 腾讯云 - wafer2 - PHP - DEMO - 003 - 源码分析 - 01 - 文件组成详细分析

    1 前言: 本文原创,欢迎转载,但是,务必保持原文并且给出原文链接. 微信小程序 - 腾讯云 - PHP - DEMO 是微信提供的一个微信小程序和腾讯云小程序云服务wafer 进行接口的例子. 本仓 ...

  7. 【SemiDrive源码分析】【X9芯片启动流程】08 - X9平台 lk 目录源码分析 之 目录介绍

    [SemiDrive源码分析][X9芯片启动流程]08 - X9平台 lk 目录源码分析 之 目录介绍 一./rtos/lk/ 目录结构分析 1.1 /rtos/lk_boot/ 目录结构分析 1.2 ...

  8. Linux驱动入门(三)——源码下载阅读、分析和嵌入式文件系统介绍

    文章目录 从内核出发 获取内核源码 使用Git 安装内核源码 使用补丁 阅读Linux内核源码 Source Insight简介 阅读源码 内核开发的特点 无libc库抑或无标准头文件 GNU C 没 ...

  9. Colly源码解析——结合例子分析底层实现

    通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...

最新文章

  1. 最新调查:等这一波COBOL程序员退休,很多关键岗位就后继无人了
  2. Windows 2008 R2+iis7.5环境下Discuz!X3论坛伪静态设置方法
  3. deeplearning
  4. 算法学习:主席树(可持久化线段树)
  5. 152.信道划分及其典型应用
  6. try...catch的方式处理多个异常
  7. python标准库math用来计算平方根的函数_《Python程序设计方案》题库
  8. @action 注解
  9. C++学习笔记-DLL中动态内存管理
  10. c语言参数传入函数赋值后传出来,c语言第10次实验内容函数2邹显春.ppt
  11. UVA10505 Montesco vs Capuleto【DFS】
  12. 怎么样测试需要登录的接口?需要登录的接口怎么测试性能?
  13. 影响Google Adsense广告单价高低的因素分析获取更高的收入
  14. 写公众号一个月关注量破900,聊聊我的感受
  15. 墨迹天气3.0引导动画
  16. Bootstrap学习笔记——缩略图、警示框、进度条、媒体对象、列表组、画板
  17. bte上了b网_酷站推荐 - tukkk.com - 小语种口语网
  18. 什么是大数据(Big Data)?
  19. BPM那些事儿——开源BPM引擎
  20. ubuntu18.0404 aws 云服务器启动和登陆 windows 虚拟机

热门文章

  1. 自定义JAVA注解_深入理解Java:自定义java注解
  2. git log 查看某文件的修改历史
  3. python3.6 websocket异步高并发_Python3.6 websocket开发
  4. oracle dump 文件解析,oracle 事件转储udump文件
  5. 删除ubuntu linux系统,从Windows双启动中卸载Ubuntu Linux
  6. docker容器内访问外部mysql_详解Docker容器内应如何访问本机(宿主机)
  7. l298n电机驱动模块_带DRV8825驱动器模块和Arduino的控制步进电机
  8. java链表实现_数据结构——基于java的链表实现(真正理解链表这种数据结构)...
  9. mysql独立服务器_独立服务器linux系统mysql设置方法
  10. python 数字证书模拟登录_用于生成WebService使用的数字证书及签署证书.python脚本...