一坝初、HTTP 介紹
HTTP協(xié)議是Hyper Text Transfer Protocol(超文本傳輸協(xié)議)的縮寫,是用于從萬維網(wǎng)(WWW:World Wide Web )服務器傳輸超文本到本地瀏覽器的傳送協(xié)議。
HTTP是一個基于TCP/IP通信協(xié)議來傳遞數(shù)據(jù)(HTML 文件, 圖片文件, 音視頻文件等)吏恭。
1樱哼、HTTP 工作原理
HTTP協(xié)議工作于客戶端-服務端架構上搅幅。瀏覽器作為HTTP客戶端通過URL向HTTP服務端即WEB服務器發(fā)送所有請求茄唐。
可以實現(xiàn) Web服務器 軟件有:
- 一般部署在 Linux 環(huán)境下的有
- Nginx沪编,Apache 推出的 HTTPD 軟件包處理靜態(tài)頁面(HTM蚁廓、 CSS文件相嵌、JavaScript 文件饭宾、 圖片文件等)
- Tomcat 一般用于處理 Java 語言編寫的動態(tài)網(wǎng)站跃赚。
- Windos Server 環(huán)境下
- IIS服務器(Internet Information Services)是 微軟開發(fā)的部署在 Windows Server 操作系統(tǒng)上的一個服務纬傲。
Web服務器根據(jù)接收到的請求后叹括,向客戶端發(fā)送響應信息汁雷。
HTTP協(xié)議規(guī)定,服務的默認端口號為80厢漩,但是你也可以改為8080或者其他端口溜嗜。
HTTP三點注意事項:
- HTTP是無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求土全,并收到客戶的應答后涯曲,即斷開連接幻件。采用這種方式可以節(jié)省傳輸時間篱蝇。
- HTTP是無狀態(tài):HTTP協(xié)議是無狀態(tài)協(xié)議零截。無狀態(tài)是指協(xié)議對于事務處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息弧哎,則它必須重傳,這樣可能導致每次連接傳送的數(shù)據(jù)量增大序攘。另一方面,在服務器不需要先前信息時它的應答就較快。
以下圖表展示了HTTP協(xié)議通信流程:
2泛粹、HTTP 消息結構
HTTP是基于客戶端/服務端(C/S)的架構模型扒接,通過一個可靠的鏈接來交換信息蒙挑,是一個無狀態(tài)的請求/響應協(xié)議矾利。
一個HTTP"客戶端"是一個應用程序(Web瀏覽器或其他任何客戶端)姑裂,通過連接到服務器達到向服務器發(fā)送一個或多個HTTP的請求的目的。
一個HTTP"服務器"同樣也是一個應用程序(通常是一個Web服務男旗,如Apache Web服務器或IIS服務器等)舶斧,通過接收客戶端的請求并向客戶端發(fā)送HTTP響應數(shù)據(jù)。
HTTP使用統(tǒng)一資源標識符(Uniform Resource Identifiers, URI)來傳輸數(shù)據(jù)和建立連接察皇。
3茴厉、客戶端請求消息
客戶端發(fā)送一個HTTP請求到服務器的請求消息包括以下格式:請求行(request line)、請求頭部(header)什荣、空行和請求數(shù)據(jù)四個部分組成矾缓,下圖給出了請求報文的一般格式。
4溃睹、服務器響應消息
HTTP響應也由四個部分組成而账,分別是:狀態(tài)行、消息報頭因篇、空行和響應正文泞辐。
5、HTTP 請求方法
根據(jù)HTTP標準竞滓,HTTP請求可以使用多種請求方法咐吼。
HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法商佑。
6锯茄、HTTP 響應頭信息
應答頭 | 說明 |
---|---|
Allow(掌握) | 服務器支持哪些請求方法(如GET、POST等)茶没。 |
Content-Encoding(掌握) | 文檔的字符編碼(Encode)方法肌幽。只有在解碼之后才可以得到Content-Type頭指定的內(nèi)容類型∽グ耄可以利用gzip對響應內(nèi)容進行壓縮喂急,這樣能夠顯著地減少HTML文檔的下載時間,通樣也節(jié)省了網(wǎng)絡流量笛求。Java的GZIPOutputStream可以很方便地進行gzip壓縮廊移。但是也比較舊的瀏覽器(比如 IE4 之前的瀏覽器)不支持 gzip, 因此,Servlet應該通過查看Accept-Encoding頭(即request.getHeader("Accept-Encoding"))檢查瀏覽器是否支持gzip探入,為支持gzip的瀏覽器返回經(jīng)gzip壓縮的HTML頁面狡孔,為其他瀏覽器返回普通頁面。 |
Content-Length(掌握) | 表示內(nèi)容長度蜂嗽。只有當瀏覽器使用持久HTTP連接時才需要這個數(shù)據(jù)苗膝。如果你想要利用持久連接的優(yōu)勢,可以把輸出文檔寫入 ByteArrayOutputStream植旧,完成后查看其大小荚醒,然后把該值放入Content-Length頭芋类,最后通過byteArrayStream.writeTo(response.getOutputStream()發(fā)送內(nèi)容。 |
Content-Type(重點掌握) | 表示POST請求或者響應的文檔內(nèi)容屬于什么MIME類型界阁。Servlet默認為text/plain侯繁,但通常需要顯式地指定為text/html。由于經(jīng)常要設置Content-Type泡躯,因此HttpServletResponse提供了一個專用的方法setContentType贮竟。 |
Date(掌握) | 當前的GMT時間。你可以用setDateHeader來設置這個頭以避免轉換時間格式的麻煩较剃。 |
Expires | 告訴客戶端咕别,應該在什么時候認為文檔已經(jīng)過期,從而不再緩存它写穴,而發(fā)送一次新的HTTP請求惰拱。 |
Last-Modified | 文檔的最后改動時間“∷停客戶可以通過If-Modified-Since請求頭提供一個日期偿短,該請求將被視為一個條件GET,只有改動時間遲于指定時間的文檔才會返回馋没,否則返回一個304(Not Modified)狀態(tài)昔逗。Last-Modified也可用setDateHeader方法來設置。 |
Location(掌握) | 表示客戶應當?shù)侥睦锶ヌ崛∥臋n篷朵。Location通常不是直接設置的勾怒,而是通過HttpServletResponse的sendRedirect方法,該方法同時設置狀態(tài)代碼為302声旺。 |
Refresh | 表示瀏覽器應該在多少時間之后刷新文檔笔链,以秒計。除了刷新當前文檔之外腮猖,你還可以通過setHeader("Refresh", "5; URL=http://host/path")讓瀏覽器讀取指定的頁面鉴扫。 注意這種功能通常是通過設置HTML頁面HEAD區(qū)的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">實現(xiàn),這是因為缚够,自動刷新或重定向對于那些不能使用CGI或Servlet的HTML編寫者十分重要幔妨。但是鹦赎,對于Servlet來說谍椅,直接設置Refresh頭更加方便。 注意Refresh的意義是"N秒之后刷新本頁面或訪問指定頁面"古话,而不是"每隔N秒刷新本頁面或訪問指定頁面"雏吭。因此,連續(xù)刷新要求每次都發(fā)送一個Refresh頭陪踩,而發(fā)送204狀態(tài)代碼則可以阻止瀏覽器繼續(xù)刷新杖们,不管是使用Refresh頭還是<META HTTP-EQUIV="Refresh" ...>悉抵。 注意Refresh頭不屬于HTTP 1.1正式規(guī)范的一部分,而是一個擴展摘完,但Netscape和IE都支持它姥饰。 |
Server(掌握) | 服務器名字。Servlet一般不設置這個值孝治,而是由Web服務器自己設置列粪。 |
Set-Cookie | 設置和頁面關聯(lián)的Cookie。Servlet不應使用response.setHeader("Set-Cookie", ...)谈飒,而是應使用HttpServletResponse提供的專用方法addCookie岂座。參見下文有關Cookie設置的討論。 |
WWW-Authenticate | 客戶應該在Authorization頭中提供什么類型的授權信息杭措?在包含401(Unauthorized)狀態(tài)行的應答中這個頭是必需的费什。例如,response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")手素。 注意Servlet一般不進行這方面的處理鸳址,而是讓Web服務器的專門機制來控制受密碼保護頁面的訪問(例如.htaccess)。 |
7刑桑、HTTP 狀態(tài)碼
當瀏覽者訪問一個網(wǎng)頁時氯质,瀏覽者的瀏覽器會向網(wǎng)頁所在服務器發(fā)出請求。當瀏覽器接收并顯示網(wǎng)頁前祠斧,此網(wǎng)頁所在的服務器會返回一個包含HTTP狀態(tài)碼的信息頭(server header)用以響應瀏覽器的請求闻察。
HTTP狀態(tài)碼的英文為HTTP Status Code。
注意:狀態(tài)碼及其包含的含義琢锋,只是 HTTP 協(xié)議中規(guī)定的而已辕漂。實際開發(fā)網(wǎng)站時,大家都遵守這樣的規(guī)定吴超,這樣便于溝通傳遞信息钉嘹。
下面是常見的HTTP狀態(tài)碼及其含義:
- 200 - 請求成功
- 301 - 資源(網(wǎng)頁等)被永久轉移到其它URL
- 302 - 請求的資源被臨時重定向到其他 URL
- 403 - 無權獲取請求的資源
- 404 - 請求的資源(網(wǎng)頁等)不存在
- 500 - 內(nèi)部服務器錯誤(一般是開發(fā)寫的程序代碼出現(xiàn)了錯誤)
HTTP狀態(tài)碼分類
HTTP狀態(tài)碼由三個十進制數(shù)字組成,第一個十進制數(shù)字定義了狀態(tài)碼的類型鲸阻。HTTP狀態(tài)碼共分為5種類型:
HTTP狀態(tài)碼列表:
TP狀態(tài)碼列表:
狀態(tài)碼 | 狀態(tài)碼英文名稱 | 中文描述 |
---|---|---|
100 | Continue | 繼續(xù)跋涣。客戶端應繼續(xù)其請求 |
101 | Switching Protocols | 切換協(xié)議鸟悴。服務器根據(jù)客戶端的請求切換協(xié)議陈辱。只能切換到更高級的協(xié)議,例如细诸,切換到HTTP的新版本協(xié)議 |
200 | OK | 請求成功沛贪。一般用于GET與POST請求 |
201 | Created | 已創(chuàng)建。成功請求并創(chuàng)建了新的資源 |
202 | Accepted | 已接受。已經(jīng)接受請求利赋,但未處理完成 |
203 | Non-Authoritative Information | 非授權信息水评。請求成功。但返回的meta信息不在原始的服務器媚送,而是一個副本 |
204 | No Content | 無內(nèi)容中燥。服務器成功處理,但未返回內(nèi)容塘偎。在未更新網(wǎng)頁的情況下褪那,可確保瀏覽器繼續(xù)顯示當前文檔 |
205 | Reset Content | 重置內(nèi)容。服務器處理成功式塌,用戶終端(例如:瀏覽器)應重置文檔視圖博敬。可通過此返回碼清除瀏覽器的表單域 |
206 | Partial Content | 部分內(nèi)容峰尝。服務器成功處理了部分GET請求 |
300 | Multiple Choices | 多種選擇偏窝。請求的資源可包括多個位置,相應可返回一個資源特征與地址的列表用于用戶終端(例如:瀏覽器)選擇 |
301 | Moved Permanently | 永久移動武学。請求的資源已被永久的移動到新URI祭往,返回信息會包括新的URI,瀏覽器會自動定向到新URI火窒。今后任何新的請求都應使用新的URI代替 |
302 | Found | 臨時移動硼补。與301類似。但資源只是臨時被移動熏矿∫押В客戶端應繼續(xù)使用原有URI |
303 | See Other | 查看其它地址。與301類似票编。使用GET和POST請求查看 |
304 | Not Modified | 未修改褪储。所請求的資源未修改,服務器返回此狀態(tài)碼時慧域,不會返回任何資源鲤竹。客戶端通常會緩存訪問過的資源昔榴,通過提供一個頭信息指出客戶端希望只返回在指定日期之后修改的資源 |
305 | Use Proxy | 使用代理辛藻。所請求的資源必須通過代理訪問 |
306 | Unused | 已經(jīng)被廢棄的HTTP狀態(tài)碼 |
307 | Temporary Redirect | 臨時重定向。與302類似互订。使用GET請求重定向 |
400 | Bad Request | 客戶端請求的語法錯誤吱肌,服務器無法理解 |
401 | Unauthorized | 請求要求用戶的身份認證 |
402 | Payment Required | 保留,將來使用 |
403 | Forbidden | 服務器理解請求客戶端的請求屁奏,但是拒絕執(zhí)行此請求 |
404 | Not Found | 服務器無法根據(jù)客戶端的請求找到資源(網(wǎng)頁)岩榆。通過此代碼错负,網(wǎng)站設計人員可設置"您所請求的資源無法找到"的個性頁面 |
405 | Method Not Allowed | 客戶端請求中的方法被禁止 |
406 | Not Acceptable | 服務器無法根據(jù)客戶端請求的內(nèi)容特性完成請求 |
407 | Proxy Authentication Required | 請求要求代理的身份認證坟瓢,與401類似勇边,但請求者應當使用代理進行授權 |
408 | Request Time-out | 服務器等待客戶端發(fā)送的請求時間過長,超時 |
409 | Conflict | 服務器完成客戶端的PUT請求是可能返回此代碼折联,服務器處理請求時發(fā)生了沖突 |
410 | Gone | 客戶端請求的資源已經(jīng)不存在粒褒。410不同于404,如果資源以前有現(xiàn)在被永久刪除了可使用410代碼诚镰,網(wǎng)站設計人員可通過301代碼指定資源的新位置 |
411 | Length Required | 服務器無法處理客戶端發(fā)送的不帶Content-Length的請求信息 |
412 | Precondition Failed | 客戶端請求信息的先決條件錯誤 |
413 | Request Entity Too Large | 由于請求的實體過大奕坟,服務器無法處理,因此拒絕請求清笨。為防止客戶端的連續(xù)請求月杉,服務器可能會關閉連接。如果只是服務器暫時無法處理抠艾,則會包含一個Retry-After的響應信息 |
414 | Request-URI Too Large | 請求的URI過長(URI通常為網(wǎng)址)苛萎,服務器無法處理 |
415 | Unsupported Media Type | 服務器無法處理請求附帶的媒體格式 |
416 | Requested range not satisfiable | 客戶端請求的范圍無效 |
417 | Expectation Failed | 服務器無法滿足Expect的請求頭信息 |
500 | Internal Server Error | 服務器內(nèi)部錯誤,無法完成請求 |
501 | Not Implemented | 服務器不支持請求的功能检号,無法完成請求 |
502 | Bad Gateway | 作為網(wǎng)關或者代理工作的服務器嘗試執(zhí)行請求時腌歉,從遠程服務器接收到了一個無效的響應 |
503 | Service Unavailable | 由于超載或系統(tǒng)維護,服務器暫時的無法處理客戶端的請求齐苛。延時的長度可包含在服務器的Retry-After頭信息中 |
504 | Gateway Time-out | 充當網(wǎng)關或代理的服務器翘盖,未及時從遠端服務器獲取請求 |
505 | HTTP Version not supported | 服務器不支持請求的HTTP協(xié)議的版本,無法完成處理 |
二凹蜂、nginx 服務
1馍驯、nginx 介紹
Nginx (engine x) 是一個輕量級,高性能的 HTTP 和 反向代理 服務玛痊,也是一個IMAP/POP3/SMTP服務(這是初衷)泥彤。因它的穩(wěn)定性、豐富的功能集卿啡、示例配置文件和低系統(tǒng)資源的消耗而聞名吟吝。
創(chuàng)始人伊戈爾·賽索耶夫
2、為什么選擇 nginx
Nginx 是一個高性能的 Web 和反向代理服務器, 它具有很多非常優(yōu)越的特性:
單機環(huán)境下颈娜。 并發(fā)連接數(shù)在7000+ -8000左右剑逃。 集群模式20000+
作為 Web 服務器:相比 Apache,Nginx 使用更少的資源官辽,支持更多的并發(fā)連接蛹磺,體現(xiàn)更高的效率,這點使 Nginx 尤其受到虛擬主機提供商的歡迎同仆。能夠支持高達 50,000 個并發(fā)連接數(shù)(官方宣稱)的響應萤捆。
作為負載均衡服務器:Nginx 既可以在內(nèi)部直接支持 PHP,也可以支持作為 HTTP代理服務器 對外進行服務。
**作為郵件代理服務器: **Nginx 同時也是一個非常優(yōu)秀的郵件代理服務器(最早開發(fā)這個產(chǎn)品的目的之一也是作為郵件代理服務器)俗或。
Nginx 安裝非常的簡單市怎,配置文件 非常簡潔(還能夠支持Perl語言的語法),Bug非常少的服務器: Nginx 啟動特別容易辛慰,并且?guī)缀蹩梢宰龅?*24不間斷運行区匠,即使運行數(shù)個月也不需要重新啟動。你還能夠在 不間斷服務的情況下進行軟件版本的升級帅腌。
3驰弄、高并發(fā)實現(xiàn)方式
1、I/O multiplexing【多并發(fā)】
第一種方法就是最傳統(tǒng)的多線程并發(fā)模型 (每進來一個新的I/O流會分配一個新的線程管理速客。)
第二種方法就是I/O多路復用 (單個線程戚篙,通過記錄跟蹤每個I/O流(sock)的狀態(tài),來同時管理多個I/O流 溺职。)
I/O multiplexing 這里面的 multiplexing 指的其實是在單個線程通過記錄跟蹤每一個Sock(I/O流)的狀態(tài)來同時管理多個I/O流已球。發(fā)明它的原因,是盡量多的提高服務器的吞吐能力辅愿。在同一個線程里面智亮, 通過撥開關的方式,來同時傳輸多個I/O流
2点待、一個請求到來了阔蛉,nginx使用epoll接收請求的過程是怎樣的?
ngnix會有很多連接進來, epoll會把他們都監(jiān)視起來癞埠,然后像撥開關一樣状原,誰有數(shù)據(jù)就撥向誰,然后調(diào)用相應的代碼處理苗踪。
- epoll.
epoll 可以說是I/O 多路復用最新的一個實現(xiàn)颠区,epoll 修復了poll 和select絕大部分問題, 比如:
? epoll 現(xiàn)在是線程安全的。
? epoll 現(xiàn)在不僅告訴你socket組里面數(shù)據(jù)通铲,還會告訴你具體哪個socket有數(shù)據(jù)毕莱,你不用自己去找了。
3颅夺、異步朋截,非阻塞
$ pstree |grep nginx
|-+= 81666 root nginx: master process nginx
| |--- 82500 nobody nginx: worker process
| --- 82501 nobody nginx: worker process
1個master進程,2個work進程
每進來一個request吧黄,會有一個worker進程去處理部服。但不是全程的處理,處理到什么程度呢拗慨?處理到可能發(fā)生阻塞的地方廓八,比如向上游(后端)服務器轉發(fā)request奉芦,并等待請求返回。那么剧蹂,這個處理的worker不會這么一直等著声功,他會在發(fā)送完請求后,注冊一個事件:“如果upstream返回了国夜,告訴我一聲,我再接著干”短绸。于是他就休息去了车吹。這就是異步。此時醋闭,如果再有request 進來窄驹,他就可以很快再按照相同的這種方式處理。這就是非阻塞和IO多路復用证逻。而一旦上游服務器返回了乐埠,就會觸發(fā)這個事件,worker才會來接手囚企,這個request才會接著往下走丈咐。這就是異步回調(diào)。