syslog源码_Gunicorn源码分析01--目录结构
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】
![](/assets/blank.gif)
├── 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源码关系图
![](/assets/blank.gif)
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--目录结构相关推荐
- Solr6.7 学习笔记(01) -- 目录结构
Solr解压后的目录结构 --contrib: Solr的一些扩展 --analysis-extras: 包含一些文本分析组件及其依赖 --clustering: 包含一个用于集群搜索结果的引擎 -- ...
- php 框架获取服务器,Thinkphp 框架基础之源码获取、环境要求与目录结构分析
本文实例讲述了Thinkphp 框架基础之源码获取.环境要求与目录结构.分享给大家供大家参考,具体如下: 获取ThinkPHP 获取ThinkPHP的方式很多,官方网站(http://thinkphp ...
- plink源码_putty源码阅读----plink
一直对ssh协议的各种客户端实现比较入迷,遍寻了很多ssh协议实现也用了很多的库,发现依赖太多 putty是最纯洁依赖第三方几乎为0的客户端实现,先从plink处开始入手. 1.putty目录 才刚开 ...
- 【转】Spring AMQP 源码分析 01 - Impatient
转自首夜盲毒预言家的文章 Spring AMQP 源码分析 01 - Impatient ### 准备 ## 目标 了解 Spring AMQP 核心代码 ## 前置知识 RabbitMQ 入门 ## ...
- 【Busybox】Busybox源码分析-01 | 源码目录结构和程序入口
文章目录 一.Busybox简介 (1-1)开源项目 (1-2)程序本体较小 (1-3)使用简单 二.Busybox源码目录结构 三.Busybox程序主体 四.Busybox程序运行剖析
- 【中级】 微信小程序 - 腾讯云 - wafer2 - PHP - DEMO - 003 - 源码分析 - 01 - 文件组成详细分析
1 前言: 本文原创,欢迎转载,但是,务必保持原文并且给出原文链接. 微信小程序 - 腾讯云 - PHP - DEMO 是微信提供的一个微信小程序和腾讯云小程序云服务wafer 进行接口的例子. 本仓 ...
- 【SemiDrive源码分析】【X9芯片启动流程】08 - X9平台 lk 目录源码分析 之 目录介绍
[SemiDrive源码分析][X9芯片启动流程]08 - X9平台 lk 目录源码分析 之 目录介绍 一./rtos/lk/ 目录结构分析 1.1 /rtos/lk_boot/ 目录结构分析 1.2 ...
- Linux驱动入门(三)——源码下载阅读、分析和嵌入式文件系统介绍
文章目录 从内核出发 获取内核源码 使用Git 安装内核源码 使用补丁 阅读Linux内核源码 Source Insight简介 阅读源码 内核开发的特点 无libc库抑或无标准头文件 GNU C 没 ...
- Colly源码解析——结合例子分析底层实现
通过<Colly源码解析--框架>分析,我们可以知道Colly执行的主要流程.本文将结合http://go-colly.org上的例子分析一些高级设置的底层实现.(转载请指明出于break ...
最新文章
- 最新调查:等这一波COBOL程序员退休,很多关键岗位就后继无人了
- Windows 2008 R2+iis7.5环境下Discuz!X3论坛伪静态设置方法
- deeplearning
- 算法学习:主席树(可持久化线段树)
- 152.信道划分及其典型应用
- try...catch的方式处理多个异常
- python标准库math用来计算平方根的函数_《Python程序设计方案》题库
- @action 注解
- C++学习笔记-DLL中动态内存管理
- c语言参数传入函数赋值后传出来,c语言第10次实验内容函数2邹显春.ppt
- UVA10505 Montesco vs Capuleto【DFS】
- 怎么样测试需要登录的接口?需要登录的接口怎么测试性能?
- 影响Google Adsense广告单价高低的因素分析获取更高的收入
- 写公众号一个月关注量破900,聊聊我的感受
- 墨迹天气3.0引导动画
- Bootstrap学习笔记——缩略图、警示框、进度条、媒体对象、列表组、画板
- bte上了b网_酷站推荐 - tukkk.com - 小语种口语网
- 什么是大数据(Big Data)?
- BPM那些事儿——开源BPM引擎
- ubuntu18.0404 aws 云服务器启动和登陆 windows 虚拟机
热门文章
- 自定义JAVA注解_深入理解Java:自定义java注解
- git log 查看某文件的修改历史
- python3.6 websocket异步高并发_Python3.6 websocket开发
- oracle dump 文件解析,oracle 事件转储udump文件
- 删除ubuntu linux系统,从Windows双启动中卸载Ubuntu Linux
- docker容器内访问外部mysql_详解Docker容器内应如何访问本机(宿主机)
- l298n电机驱动模块_带DRV8825驱动器模块和Arduino的控制步进电机
- java链表实现_数据结构——基于java的链表实现(真正理解链表这种数据结构)...
- mysql独立服务器_独立服务器linux系统mysql设置方法
- python 数字证书模拟登录_用于生成WebService使用的数字证书及签署证书.python脚本...