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】
可發現源碼文件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.py3. 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.pypython -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--目录结构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: reportviewer控件mysql_
- 下一篇: zookeeper清空hbase_Amb