openstack 之~keystone之網關協議

第一:靜態頁面和動態頁面

上一篇博客介紹了HTTP後,咱們知道一個web server的本質就是php

  1. 瀏覽器發送一個HTTP請求;html

  2. 服務器收到請求,生成一個HTML文檔;python

  3. 服務器把HTML文檔做爲HTTP響應的Body發送給瀏覽器;nginx

  4. 瀏覽器收到HTTP響應,從HTTP Body取出HTML文檔並顯示。git

用戶的請求的結果可分爲靜態頁面和動態頁面兩種github

靜態頁面:是實實在在保存在服務器上寫死了的html代碼,每一個網頁都是一個獨立的文件,全部的訪問者看到的內容都同樣web

動態頁面:動態的概念意味着變,程序中體現'變'的概念就是變量,於是在html代碼中須要嵌入變量,變量的值的來源須要用一段代碼動態生成,這樣不一樣的用戶會提交不一樣的數據給服務端,服務端分析用戶提交過來的數據而後執行這段代碼,動態生成值後賦值html中變量,而後返回html給用戶,這樣對每一個用戶來講收到的頁面都是不同的。數據庫

第二:什麼是Web Server

Web Service也叫XML Web Service WebService是一種能夠接收從Internet或者Intranet上的其它系統中傳遞過來的請求,輕量級的獨立的通信技術。是:經過SOAP在Web上提供的軟件服務,使用WSDL文件進行說明,並經過UDDI進行註冊。apache

通俗來講:用戶上網的本質就是在本身這端啓動socket client(瀏覽器),服務的啓動socket server(web server)。基於http協議的學習咱們知道,web server主要是用來響應用戶的http請求而後返回html頁面給用戶。編程

如今主流的web server:nginx,apache,tomcat等等

第三:什麼是網關協議

 引言:

因web server好比apache只能處理靜態請求,因此對於動態請求,你須要編寫專門的程序來處理

隨着互聯網的發展,愈來愈多的用戶數據須要永久保存下來,文件是能夠永久保存,可是文件的數據處理性能過低,因而引入了數據庫,並慢慢成爲了網站大後端的主流

apache沒法處理動態請求,因此咱們須要本身編寫一個個的功能來處理這些動態請求(注意:這些動態請求有的須要查詢數據庫有的則不須要)

舉例說明:

處理動態請求的僞代碼,能夠稱之爲web application,或者簡web app
一:接收apache提交過來的用戶請求,觸發函數運行
二:鏈接數據庫
三:操做數據庫(增刪改查)
四:根據獲取的數據進行其餘邏輯處理
五:返回給apache數據
六:關閉數據庫
以下圖:

問題一:編寫web app時,須要深刻研究apache工做的協議HTTP,這會嚴重影響了開發效率。

咱們迫切須要在web server與web app之間定義一種標準,用來明細分工,web server對外提供一種標準,web app開發者只要遵循這個標準,那麼後者就無需考慮web server究竟是如何實現的了而能夠專一web app的開發,這個標準就是網關協議

問題二:針對apache這款web server定製的代碼,換成了另外的web server你的程序沒法重用

在web server與web app之間定義了標準,那麼只要個人web app是遵循這個標準的,換另一個也遵循該標準的web server,一樣能夠運行

問題三:針對一種動態請求的代碼實現,對於其餘的動態請求呢,你仍然須要寫重複的代碼去處理

這裏須要引入一個概念叫:web app開發框架(也稱web 框架)

web app開發框架用來爲web app開發者提供一套現成的開發工具與開發模式,web app開發者再也不須要寫重複代碼了,只須要使用某種現成的web開發框架,一些重複的功能就不用再去重複造輪子了,這極大的提升了開發效率

好比web app開發框架通常本事都是基於網關協議標準實現的,由於你用web app開發框架去開發web app,天然就是遵循某種網關協議標準的,你甚至連這個協議具體是什麼都無需知道。

第四:網關協議CGI、FastCGI、WSGI、UWSGI

CGI

CGI 即通用網關接口(Common Gateway Interface), 是一種服務器和後端可執行程序之間的交互標準,或者說是web app應用程序(CGI程序)與Web服務器之間的接口標準。

原理:最原始的服務器,簡單到就是訪問文件目錄,每次的請求都是請求加載目錄下的文件。好比文檔放在/var/www/html 目錄下,訪問 http://domain/index.html 其實就是請求 /var/www/html/index.html 文件。

CGI 經過服務器腳本(或者二進制文件),擴展了這個基礎的『訪問過程』。它利用程序的標準輸入輸出流,完成 HTTP 通訊。每次請求的文本以標準輸入流的形式進入服務器端的 CGI 程序,建立進程並執行,而後將運行結果經過進程的標準輸出流輸出做爲響應。
eg:/usr/local/apache/htdocs/cgi-bin 是咱們的 CGI 目錄,當請求了 CGI 目錄裏的文件的時候(好比訪問 http://domain/cgi-bin/printenv.pl ),服務器並不會返回這個文件,而會運行這個程序,而後將生成的內容返回給客戶端。因此理論上,任何有輸入輸出能力的語言均可以用來寫 CGI。

CGI腳本工做原理:

  1. 瀏覽器發送動態請求(經過HTML表單或者超連接)
  2. 服務端接收該請求,調用CGI腳本,產生一個CGI進程來處理該動態請求,結果返回給服務器
  3. 服務器將html返回給瀏覽器

CGI工做原理圖:

優勢
CGI 程序提供了不少靜態網頁沒法實現的功能,好比加載數據、數據運算等等。早期的動態網頁基本都是基於 CGI 實現的。

缺點
在 CGI 協議下,解析器的反覆加載是性能低下的主要緣由。每一個發送到服務器的請求,都須要通過『啓動進程、處理請求、結束進程』三個步驟,因此當訪問量增大時,系統資源的開銷也會增大,致使服務器性能降低甚至服務中斷。
更甚至是,這種『一個請求一個進程』的模式意味着沒有『狀態』可言,致使不少資源沒法複用,好比鏈接數據庫、內存緩存、cpu消耗等等。

FastCGI:

FastCGI 是 CGI 的加強版本,用於減小 Server 與 CGI 應用之間的交互開銷,從而使 Server能夠同時處理更多的請求。

FastCGI與CGI 的 fork-and-execute 模式不一樣的是,FastCGI 以 Daemon 的形式運行,在初始化的時候會啓動一個 FastCGI Server 而後長駐內存,處理一系列的請求。

FastCGI是一個可伸縮地、高速地在HTTP server和動態腳本語言間通訊的接口。多數流行的HTTP server都支持FastCGI,包括Apache、Nginx和lighttpd等,同時,FastCGI也被許多腳本語言所支持,其中就有PHP。

FastCGI是從CGI發展改進而來的。傳統CGI接口方式的主要缺點是性能不好,由於每次HTTP服務器遇到動態程序時都須要從新啓動腳本解析器來執行解析,而後結果被返回給HTTP服務器。這在處理高併發訪問時,幾乎是不可用的。FastCGI像是一個常駐(long-live)型的CGI,它能夠一直執行着,只要激活後,不會每次都要花費時間去fork一次(這是CGI最爲人詬病的fork-and-execute 模式)。CGI 就是所謂的短生存期應用程序,FastCGI 就是所謂的長生存期應用程序。因爲 FastCGI 程序並不須要不斷的產生新進程,能夠大大下降服務器的壓力而且產生較高的應用效率。它的速度效率最少要比CGI 技術提升 5 倍以上。它還支持分佈式的運算, 即 FastCGI 程序能夠在網站服務器之外的主機上執行而且接受來自其它網站服務器來的請求。
FastCGI是語言無關的、可伸縮架構的CGI開放擴展,其主要行爲是將CGI解釋器進程保持在內存中並所以得到較高的性能。衆所周知,CGI解釋器的反覆加載是CGI性能低下的主要緣由,若是CGI解釋器保持在內存中並接受FastCGI進程管理器調度,則能夠提供良好的性能、伸縮性、Fail-Over特性等等。FastCGI接口方式採用C/S結構,能夠將HTTP服務器和腳本解析服務器分開,同時在腳本解析服務器上啓動一個或者多個腳本解析守護進程。當HTTP服務器每次遇到動態程序時,能夠將其直接交付給FastCGI進程來執行,而後將獲得的結果返回給瀏覽器。這種方式可讓HTTP服務器專注地處理靜態請求或者將動態腳本服務器的結果返回給客戶端,這在很大程度上提升了整個應用系統的性能。


FastCGI的工做流程:

Web Server啓動時載入FastCGI進程管理器(PHP-CGI或者PHP-FPM或者spawn-cgi)
FastCGI進程管理器自身初始化,啓動多個CGI解釋器進程(可見多個php-cgi)並等待來自Web Server的鏈接。
當客戶端請求到達Web Server時,FastCGI進程管理器選擇並鏈接到一個CGI解釋器。Web server將CGI環境變量和標準輸入發送到FastCGI子進程php-cgi。
FastCGI子進程完成處理後將標準輸出和錯誤信息從同一鏈接返回Web Server。當FastCGI子進程關閉鏈接時,請求便告處理完成。FastCGI子進程接着等待並處理來自FastCGI進程管理器(運行在Web Server中)的下一個鏈接。 在CGI模式中,php-cgi在此便退出。

優勢

除了繼承 CGI 原有的優勢以外, FastCGI 還有如下特色:

  • 業務分離:FastCGI 後端和 Web Server 運行在不一樣的進程中,後端的故障不會致使 Web Server 中止服務。
  • 分佈式計算:因爲 FastCGI 服務器是能夠獨立運行的,因此 FastCGI 程序能夠在服務器之外的主機上執行,而且接受來自其它服務器的請求。
  • 多個可擴展角色:在 FastCGI 中,程序被賦予明確的角色,例如響應器角色、認證器角色、過濾器角色等等。

舉例說明fastcgi工做原理:(依據nginx爲例)

Nginx+FastCGI 的工做流程是這樣的:

  • 初始化 FastCGI 進程管理器,啓動主進程和多個 CGI 子進程。主進程主要是管理子進程,同時還須要監聽端口(例如9000端口);子進程則是處於等待鏈接的狀態。
  • 當請求到達服務器時,Nginx 經過 location 指令,將請求(例如以 php 爲後綴的文件)分配到指定端口(例如9000端口)來處理。
  • FastCGI 進程管理器選擇並鏈接到一個子進程,服務器將環境變量和標準輸入發送給子進程。
  • 子進程接受請求並完成處理後,將標準輸出和錯誤信息從同一鏈接返回給服務器。
  • 子進程關閉鏈接,繼續等待下一個請求。

工做原理圖:

 

PHP-CGI是PHP自帶的FastCGI管理器。PHP-CGI的不足:
php-cgi變動php.ini配置後需重啓php-cgi才能讓新的php-ini生效,不能夠平滑重啓
直接殺死php-cgi進程php就不能運行了。(PHP-FPM和Spawn-FCGI就沒有這個問題,守護進程會平滑重新生成新的子進程。)
Spawn-FCGI是一個通用的FastCGI管理服務器,它是lighttpd中的一部份,不少人都用Lighttpd的Spawn-FCGI進行FastCGI模式下的管理工做,不過有很多缺點。而PHP-FPM的出現多少緩解了一些問題,但PHP-FPM有個缺點就是要從新編譯,這對於一些已經運行的環境可能有不小的風險),在php 5.3.3中能夠直接使用PHP-FPM了。Spawn-FCGI的代碼不多,所有才630行,用c語言編寫,最近一次提交是5年前。代碼主頁:https://github.com/lighttpd/spawn-fcgi
Spawn-FCGI代碼分析以下:
1.spawn-fcgi 首先create socket,bind,listen 3步建立服務器socket,(把這個socket叫作 fcgi_fd)
2.用dup2,把fcgi_fd 交換給 FCGI_LISTENSOCK_FILENO (FCGI_LISTENSOCK_FILENO數值上等於0,這是fastcgi協議當中指定用來listen的socket id)
3.執行execl ,replaces the current process image with a new process image. process image 進程在運行空間的代碼段
很顯然,Spawn-FCGI也是 pre-fork 模型,只是用了上古C語言編寫,充滿了N多 unix下暗黑編程技巧。
Spawn-FCGI功能很單一:
1.只管fork進程,子進程掛了,主進程僅僅log記錄一次,根本不會從新fork。在2009年一段時間內,我曾經用spawn-fcgi部署php-cgi,當跑一段時間就會全掛掉,只能用crontab定時重啓spawn-fcgi
不負責子進程中的網絡IO,把socket放到指定位置就完了,接下來的事情由被spawn的程序處理
2.Spawn-FCGI是一個很早期的程序,瞻仰一下便可。另外有:1996年的一段代碼:http://www.fastcgi.com/om_archive/kit/cgi-fcgi/cgi-fcgi.c,和spawn-fcgi一個風格
PHP-FPM是一個PHP FastCGI管理器,是隻用於PHP的,能夠在 http://php-fpm.org/download下載獲得。PHP-FPM實際上是PHP源代碼的一個補丁,旨在將FastCGI進程管理整合進PHP包中。必須將它patch到你的PHP源代碼中,在編譯安裝PHP後纔可使用。FPM(FastCGI 進程管理器)用於替換 PHP-CGI 的大部分附加功能,對於高負載網站是很是有用的。它的功能包括:
1.支持平滑中止/啓動的高級進程管理功能;
2.能夠工做於不一樣的 uid/gid/chroot 環境下,並監聽不一樣的端口和使用不一樣的 php.ini 配置文件(可取代 safe_mode 的設置);
3.stdout 和 stderr 日誌記錄;
4.在發生意外狀況的時候可以從新啓動並緩存被破壞的 opcode;
5.文件上傳優化支持;
6.「慢日誌」 – 記錄腳本(不只記錄文件名,還記錄 PHP backtrace 信息,可使用 ptrace或者相似工具讀取和分析遠程進程的運行數據)運行所致使的異常緩慢;
7.fastcgi_finish_request() – 特殊功能:用於在請求完成和刷新數據後,繼續在後臺執行耗時的工做(錄入視頻轉換、統計處理等);
8.動態/靜態子進程產生;
9.基本 SAPI 運行狀態信息(相似Apache的 mod_status);
10.基於 php.ini 的配置文件。

WSGI:

 什麼是WSGI?

Web服務器網關接口(Python Web Server Gateway Interface,縮寫爲WSGI)是爲Python語言定義的Web服務器和Web應用程序或框架之間的一種簡單而通用的接口,最初是爲 Python 量身定作。

自從WSGI被開發出來之後,許多其它語言中也出現了相似接口。WSGI是做爲Web服務器與Web應用程序或應用框架之間的一種低級別的接口,以提高可移植Web應用開發的共同點。WSGI是基於現存的CGI標準而設計的。

有了WSGI,你就不用去考慮,服務器程序的具體實現,應用程序得到了很好的適用性。好比一個雲平臺提供了對 WSGI 接口的支持,那麼,只要應用是基於 WSGI 的,就能夠直接跑起來。其實keystone就是一款python開發的基於WSGI標準的app。

 

什麼是WSGI中間件?

基於WSGI 的設計哲學,咱們能夠寫一些對 server 和 application 都兼容的模塊,即WSGI中間件(middleware)。所謂的 WSGI 中間件同時實現了API的兩方,所以能夠在WSGI服務和WSGI應用之間起調解做用:從WSGI服務器的角度來講,中間件扮演應用程序,而從應用程序的角度來講,中間件扮演服務器。

 

WSGI中間件的功能與好處?

WSGI中間件能夠完成好比緩存、字符編碼轉換、根據 url 作應用 routing 等功能。

這種設計模式,是 WSGI 下降了 server 和 application 耦合度以後的產物,同時,它從另外一個角度大大提高了設計的靈活性。

 

WSGI的處理模式

WSGI將 web 組件分爲三類: web服務器,web中間件,web應用程序

wsgi基本處理模式爲 : WSGI Server -> (WSGI Middleware)* -> WSGI Application 。

在處理一個WSGI請求時,服務器會爲應用程序提供環境資訊及一個回呼函數(Callback Function)。當應用程序完成處理請求後,透過前述的回呼函數,將結果回傳給服務器。

 

wsgi server能夠理解爲一個符合wsgi規範的web server,接收request請求,封裝一系列環境變量,按照wsgi規範調用註冊的wsgi app,最後將response返回給客戶端。文字很難解釋清楚wsgi server究竟是什麼東西,以及作些什麼事情,最直觀的方式仍是看wsgi server的實現代碼。以python自帶的wsgiref爲例,wsgiref是按照wsgi規範實現的一個簡單wsgi server。它的代碼也不復雜。

  1. 服務器建立socket,監聽端口,等待客戶端鏈接。
  2. 當有請求來時,服務器解析客戶端信息放到環境變量environ中,並調用綁定的handler來處理請求。
  3. handler解析這個http請求,將請求信息例如method,path等放到environ中。
  4. wsgi handler再將一些服務器端信息也放到environ中,最後服務器信息,客戶端信息,本次請求信息所有都保存到了環境變量environ中。
  5. wsgi handler 調用註冊的wsgi app,並將environ和回調函數傳給wsgi app
  6. wsgi app 將reponse header/status/body 回傳給wsgi handler
  7. 最終handler仍是經過socket將response信息塞回給客戶端。

中間件:

Middleware 是一個比較特殊的存在,它是夾在兩者之間的,對於 Server 端而言它是個 Application ,而對於 Application 而言它就是 Server 端。

它能夠實現如下功能:

  • 重寫環境變量,根據目標 URL,將請求消息路由到不一樣的應用對象。
  • 容許在一個進程中同時運行多個應用程序或應用框架。
  • 負載均衡和遠程處理,經過在網絡上轉發請求和響應消息。
  • 進行內容後處理,例如應用 XSLT 樣式表。

優勢

WSGI 將請求的工做經過異步回調進行拆解,能夠很方便的在一個線程空間裏同時處理多個請求。

另外,方便進行負載均衡和請求轉發,不會形成後端應用阻塞。

 

Application

Application 會處理請求並經過回調函數將結果返回給 Server。

和 Serve 對應,一個標準的 Application 接受兩個參數:

  • environ:一個包含全部 HTTP 請求信息的 dict 對象
  • start_response:一個發送 HTTP 響應的函數

Server

Server 端從規定的輸入中獲取 Request 數據,而後把環境變量(environ)和回調函數(start_response)傳給 Application 

 

uWSGI

uWSGI 項目旨在爲部署分佈式集羣的網絡應用開發一套完整的解決方案。uWSGI主要面向web及其標準服務,已經成功的應用於多種不一樣的語言。因爲uWSGI的可擴展架構,它可以被無限制的擴展用來支持更多的平臺和語言。目前,你可使用C,C++和Objective-C來編寫插件。項目名稱中的「WSGI」是爲了向同名的Python Web標準表示感謝,由於WSGI爲該項目開發了第一個插件。uWSGI是一個Web服務器,它實現了WSGI協議、uwsgi、http等協議。uWSGI,既不用wsgi協議也不用FastCGI協議,而是自創了一個uwsgi的協議,uwsgi協議是一個uWSGI服務器自有的協議,它用於定義傳輸信息的類型(type of information),每個uwsgi packet前4byte爲傳輸信息類型描述,它與WSGI相比是兩樣東西。聽說該協議大約是fcgi協議的10倍那麼快。

  1. uWSGI的主要特色以下:
  2. 超快的性能。
  3. 低內存佔用(實測爲apache2的mod_wsgi的一半左右)。
  4. 多app管理。
  5. 詳盡的日誌功能(能夠用來分析app性能和瓶頸)。
  6. 高度可定製(內存大小限制,服務必定次數後重啓等)。

第五:網關協議與keystone

keystone本質就是python開發的一款基於wsgi的app,社區提倡的部署方法:

apache(wsgi)+keystone

nginx(uwsgi)+keystone

相關文章
相關標籤/搜索