您好,登錄后才能下訂單哦!
HTTP
HTTP協(xié)議是Hyper Text Transfer Protocol(超文本傳輸協(xié)議)的縮寫(xiě),是用于從萬(wàn)維網(wǎng)(WWW:World Wide Web )服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議。HTTP是一個(gè)基于TCP/IP通信協(xié)議
來(lái)傳遞數(shù)據(jù)(HTML 文件, 圖片文件, 查詢(xún)結(jié)果等)。
http工作原理
1、HTTP 工作原理
HTTP協(xié)議工作于客戶(hù)端-服務(wù)端架構(gòu)上。瀏覽器作為HTTP客戶(hù)端通過(guò)URL向HTTP服務(wù)端即WEB服務(wù)器發(fā)送所有請(qǐng)求。
Web服務(wù)器有:Nginx,Apache服務(wù)器,IIS服務(wù)器(Internet Information Services)等。
Web服務(wù)器根據(jù)接收到的請(qǐng)求后,向客戶(hù)端發(fā)送響應(yīng)信息。
HTTP默認(rèn)端口號(hào)為80,但是你也可以改為8080或者其他端口。HTTP三點(diǎn)注意事項(xiàng):
-HTTP是無(wú)連接:無(wú)連接的含義是限制每次連接只處理一個(gè)請(qǐng)求。服務(wù)器處理完客戶(hù)的請(qǐng)求,并收到客戶(hù)的應(yīng)答后,即斷開(kāi)連接。采用這種方式可以節(jié)省傳輸時(shí)間。
-HTTP是媒體獨(dú)立的:這意味著,只要客戶(hù)端和服務(wù)器知道如何處理的數(shù)據(jù)內(nèi)容,任何類(lèi)型的數(shù)據(jù)都可以通過(guò)HTTP發(fā)送??蛻?hù)端以及服務(wù)器指定使用適合的MIME-type內(nèi)容類(lèi)型。
-HTTP是無(wú)狀態(tài):HTTP協(xié)議是無(wú)狀態(tài)協(xié)議。無(wú)狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒(méi)有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導(dǎo)致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務(wù)器不需要先前信息時(shí)它的應(yīng)答就較快。
2.HTTP協(xié)議通信流程
1/87
http消息結(jié)構(gòu)
消息結(jié)構(gòu):
HTTP是基于客戶(hù)端/服務(wù)端(C/S)的架構(gòu)模型,通過(guò)一個(gè)可靠的鏈接來(lái)交換信息,是一個(gè)無(wú)狀態(tài)的請(qǐng)求/響應(yīng)協(xié)議。
一個(gè)HTTP"客戶(hù)端"是一個(gè)應(yīng)用程序(Web瀏覽器或其他任何客戶(hù)端),通過(guò)連接到服務(wù)器達(dá)到向服務(wù)
器發(fā)送一個(gè)或多個(gè)HTTP的請(qǐng)求的目的。
一個(gè)HTTP"服務(wù)器"同樣也是一個(gè)應(yīng)用程序(通常是一個(gè)Web服務(wù),如Apache Web服務(wù)器或IIS服務(wù)器等),通過(guò)接收客戶(hù)端的請(qǐng)求并向客戶(hù)端發(fā)送HTTP響應(yīng)數(shù)據(jù)。
HTTP使用統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifiers, URI)來(lái)傳輸數(shù)據(jù)和建立連接。
客戶(hù)端請(qǐng)求
客戶(hù)端發(fā)送一個(gè)HTTP請(qǐng)求到服務(wù)器的請(qǐng)求消息包括以下格式:請(qǐng)求行(request line)、請(qǐng)求頭部(header)、空行和請(qǐng)求數(shù)據(jù)四個(gè)部分組成,下圖給出了請(qǐng)求報(bào)文的一般格式。
服務(wù)器響應(yīng)消息
HTTP響應(yīng)也由四個(gè)部分組成,分別是:狀態(tài)行、消息報(bào)頭、空行和響應(yīng)正文。
2/87
下面實(shí)例是一點(diǎn)典型的使用GET來(lái)傳遞數(shù)據(jù)的實(shí)例:客戶(hù)端請(qǐng)求:
Connected to www.testpm.cn (47.244.247.240) port 80 (#0)
GET /hello.txt HTTP/1.1 # 請(qǐng)求方式與版本協(xié)議。
User-Agent: curl/7.29.0 #用什么客戶(hù)端訪問(wèn)
Host: www.testpm.cn #主機(jī)名,域名。主機(jī)和端口號(hào),
Accept: / #匹配什么文件類(lèi)型,“*” 是通用匹配。匹配所有類(lèi)型
服務(wù)端響應(yīng):
< HTTP/1.1 200 OK #請(qǐng)求返回的狀態(tài)碼
<Server: nginx/1.16.0 #請(qǐng)求的服務(wù)和版本號(hào)
<Date: Thu, 04 Jul 2019 08:19:40 GMT
<Content-Type: text/plain #文本類(lèi)型,有html,plain:普通文本
<Content-Length: 12
<Last-Modified: Thu, 04 Jul 2019 08:13:25 GMT
<Connection: keep-alive #是否支持長(zhǎng)連接
<ETag: "5d1db525-c" #標(biāo)識(shí),每次訪問(wèn)如果與最開(kāi)始的一樣返回304否則校驗(yàn)不一致返回200
<Accept-Ranges: bytes
HTTP 請(qǐng)求方法
根據(jù)HTTP標(biāo)準(zhǔn),HTTP請(qǐng)求可以使用多種請(qǐng)求方法。
HTTP1.0定義了三種請(qǐng)求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五種請(qǐng)求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
3/87
HTTP 響應(yīng)頭信息
HTTP請(qǐng)求頭提供了關(guān)于請(qǐng)求,響應(yīng)或者其他的發(fā)送實(shí)體的信息。在本章節(jié)中我們將具體來(lái)介紹HTTP響應(yīng)頭信息。
4/87
應(yīng)答頭 說(shuō)明
Allow 服務(wù)器支持哪些請(qǐng)求方法(如GET、POST等)。
Content-Encoding 文檔的編碼(Encode)方法。只有在解碼之后才可以得到Content-Type頭指
定的內(nèi)容類(lèi)型。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載時(shí)間。
Java的GZIPOutputStream可以很方便地進(jìn)行g(shù)zip壓縮,但只有Unix上的
Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet應(yīng)該通過(guò)查看
Accept-Encoding頭(即request.getHeader("Accept-Encoding"))檢查瀏覽器是
否支持gzip,為支持gzip的瀏覽器返回經(jīng)gzip壓縮的HTML頁(yè)面,為其他瀏覽器
返回普通頁(yè)面。
Content-Length 表示內(nèi)容長(zhǎng)度。只有當(dāng)瀏覽器使用持久HTTP連接時(shí)才需要這個(gè)數(shù)據(jù)。如果你
想要利用持久連接的優(yōu)勢(shì),可以把輸出文檔寫(xiě)入 ByteArrayOutputStream,完
成后查看其大小,然后把該值放入Content-Length頭,最后通過(guò)
byteArrayStream.writeTo(response.getOutputStream()發(fā)送內(nèi)容。
Content-Type 表示后面的文檔屬于什么MIME類(lèi)型。Servlet默認(rèn)為text/plain,但通常需要顯
式地指定為text/html。由于經(jīng)常要設(shè)置Content-Type,因此
HttpServletResponse提供了一個(gè)專(zhuān)用的方法setContentType。
Date 當(dāng)前的GMT時(shí)間。你可以用setDateHeader來(lái)設(shè)置這個(gè)頭以避免轉(zhuǎn)換時(shí)間格式
的麻煩。
Expires 應(yīng)該在什么時(shí)候認(rèn)為文檔已經(jīng)過(guò)期,從而不再緩存它?
Last-Modified 文檔的最后改動(dòng)時(shí)間。客戶(hù)可以通過(guò)If-Modified-Since請(qǐng)求頭提供一個(gè)日期,
該請(qǐng)求將被視為一個(gè)條件GET,只有改動(dòng)時(shí)間遲于指定時(shí)間的文檔才會(huì)返
回,否則返回一個(gè)304(Not Modified)狀態(tài)。Last-Modified也可用
setDateHeader方法來(lái)設(shè)置。
Location 表示客戶(hù)應(yīng)當(dāng)?shù)侥睦锶ヌ崛∥臋n。Location通常不是直接設(shè)置的,而是通過(guò)
HttpServletResponse的sendRedirect方法,該方法同時(shí)設(shè)置狀態(tài)代碼為302。
Refresh 表示瀏覽器應(yīng)該在多少時(shí)間之后刷新文檔,以秒計(jì)。除了刷新當(dāng)前文檔之
外,你還可以通過(guò)setHeader("Refresh", "5; URL=http://host/path")讓瀏覽器讀
取指定的頁(yè)面。 注意這種功能通常是通過(guò)設(shè)置HTML頁(yè)面HEAD區(qū)的<META
HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">實(shí)現(xiàn),這是因
為,自動(dòng)刷新或重定向?qū)τ谀切┎荒苁褂肅GI或Servlet的HTML編寫(xiě)者十分重
要。但是,對(duì)于Servlet來(lái)說(shuō),直接設(shè)置Refresh頭更加方便。 注意Refresh的
意義是"N秒之后刷新本頁(yè)面或訪問(wèn)指定頁(yè)面",而不是"每隔N秒刷新本頁(yè)面或
訪問(wèn)指定頁(yè)面"。因此,連續(xù)刷新要求每次都發(fā)送一個(gè)Refresh頭,而發(fā)送204
狀態(tài)代碼則可以阻止瀏覽器繼續(xù)刷新,不管是使用Refresh頭還是<META
HTTP-EQUIV="Refresh" ...>。 注意Refresh頭不屬于HTTP 1.1正式規(guī)范的一
部分,而是一個(gè)擴(kuò)展,但Netscape和IE都支持它。
Server 服務(wù)器名字。Servlet一般不設(shè)置這個(gè)值,而是由Web服務(wù)器自己設(shè)置。
Set-Cookie 設(shè)置和頁(yè)面關(guān)聯(lián)的Cookie。Servlet不應(yīng)使用response.setHeader("Set-
Cookie", ...),而是應(yīng)使用HttpServletResponse提供的專(zhuān)用方法addCookie。參
見(jiàn)下文有關(guān)Cookie設(shè)置的討論。
WWW-Authenticate 客戶(hù)應(yīng)該在Authorization頭中提供什么類(lèi)型的授權(quán)信息?在包含401
(Unauthorized)狀態(tài)行的應(yīng)答中這個(gè)頭是必需的。例如,
response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")。
注意Servlet一般不進(jìn)行這方面的處理,而是讓W(xué)eb服務(wù)器的專(zhuān)門(mén)機(jī)制來(lái)控制
受密碼保護(hù)頁(yè)面的訪問(wèn)(例如.htaccess)。
HTTP 狀態(tài)碼
當(dāng)瀏覽者訪問(wèn)一個(gè)網(wǎng)頁(yè)時(shí),瀏覽者的瀏覽器會(huì)向網(wǎng)頁(yè)所在服務(wù)器發(fā)出請(qǐng)求。當(dāng)瀏覽器接收并顯示網(wǎng)頁(yè)前,此網(wǎng)頁(yè)所在的服務(wù)器會(huì)返回一個(gè)包含HTTP狀態(tài)碼的信息頭(server header)用以響應(yīng)瀏覽器的請(qǐng)求。
HTTP狀態(tài)碼的英文為HTTP Status Code。
下面是常見(jiàn)的HTTP狀態(tài)碼:
5/87
?200 - 請(qǐng)求成功
?301 - 資源(網(wǎng)頁(yè)等)被永久轉(zhuǎn)移到其它URL
?404 - 請(qǐng)求的資源(網(wǎng)頁(yè)等)不存在
?500 - 內(nèi)部服務(wù)器錯(cuò)誤
HTTP狀態(tài)碼分類(lèi)
HTTP狀態(tài)碼由三個(gè)十進(jìn)制數(shù)字組成,第一個(gè)十進(jìn)制數(shù)字定義了狀態(tài)碼的類(lèi)型,后兩個(gè)數(shù)字沒(méi)有分類(lèi)的作用。HTTP狀態(tài)碼共分為5種類(lèi)型:
HTTP狀態(tài)碼列表:
6/87
100 Continue 繼續(xù)??蛻?hù)端應(yīng)繼續(xù)其請(qǐng)求
101 Switching Protocols 切換協(xié)議。服務(wù)器根據(jù)客戶(hù)端的請(qǐng)求切換協(xié)議。只能切換到更高級(jí)的協(xié)
例如,切換到HTTP的新版本協(xié)議
200 OK 請(qǐng)求成功。一般用于GET與POST請(qǐng)求
201 Created 已創(chuàng)建。成功請(qǐng)求并創(chuàng)建了新的資源
202 Accepted 已接受。已經(jīng)接受請(qǐng)求,但未處理完成
203 Non-Authoritative Information 非授權(quán)信息。請(qǐng)求成功。但返回的meta信息不在原始的服務(wù)器,而是一
本
204 No Content 無(wú)內(nèi)容。服務(wù)器成功處理,但未返回內(nèi)容。在未更新網(wǎng)頁(yè)的情況下,可
瀏覽器繼續(xù)顯示當(dāng)前文檔
205 Reset Content 重置內(nèi)容。服務(wù)器處理成功,用戶(hù)終端(例如:瀏覽器)應(yīng)重置文檔視
可通過(guò)此返回碼清除瀏覽器的表單域
206 Partial Content 部分內(nèi)容。服務(wù)器成功處理了部分GET請(qǐng)求
300 Multiple Choices 多種選擇。請(qǐng)求的資源可包括多個(gè)位置,相應(yīng)可返回一個(gè)資源特征與地
列表用于用戶(hù)終端(例如:瀏覽器)選擇
301 Moved Permanently 永久移動(dòng)。請(qǐng)求的資源已被永久的移動(dòng)到新URI,返回信息會(huì)包括新的U
瀏覽器會(huì)自動(dòng)定向到新URI。今后任何新的請(qǐng)求都應(yīng)使用新的URI代替
302 Found 臨時(shí)移動(dòng)。與301類(lèi)似。但資源只是臨時(shí)被移動(dòng)。客戶(hù)端應(yīng)繼續(xù)使用原有
303 See Other 查看其它地址。與301類(lèi)似。使用GET和POST請(qǐng)求查看
304 Not Modified 未修改。所請(qǐng)求的資源未修改,服務(wù)器返回此狀態(tài)碼時(shí),不會(huì)返回任何
源。客戶(hù)端通常會(huì)緩存訪問(wèn)過(guò)的資源,通過(guò)提供一個(gè)頭信息指出客戶(hù)端
只返回在指定日期之后修改的資源
305 Use Proxy 使用代理。所請(qǐng)求的資源必須通過(guò)代理訪問(wèn)
306 Unused 已經(jīng)被廢棄的HTTP狀態(tài)碼
307 Temporary Redirect 臨時(shí)重定向。與302類(lèi)似。使用GET請(qǐng)求重定向
400 Bad Request 客戶(hù)端請(qǐng)求的語(yǔ)法錯(cuò)誤,服務(wù)器無(wú)法理解
401 Unauthorized 請(qǐng)求要求用戶(hù)的身份認(rèn)證
402 Payment Required 保留,將來(lái)使用
403 Forbidden 服務(wù)器理解請(qǐng)求客戶(hù)端的請(qǐng)求,但是拒絕執(zhí)行此請(qǐng)求
404 Not Found 服務(wù)器無(wú)法根據(jù)客戶(hù)端的請(qǐng)求找到資源(網(wǎng)頁(yè))。通過(guò)此代碼,網(wǎng)站設(shè)
員可設(shè)置"您所請(qǐng)求的資源無(wú)法找到"的個(gè)性頁(yè)面
405 Method Not Allowed 客戶(hù)端請(qǐng)求中的方法被禁止
406 Not Acceptable 服務(wù)器無(wú)法根據(jù)客戶(hù)端請(qǐng)求的內(nèi)容特性完成請(qǐng)求
407 Proxy Authentication Required 請(qǐng)求要求代理的身份認(rèn)證,與401類(lèi)似,但請(qǐng)求者應(yīng)當(dāng)使用代理進(jìn)行授權(quán)
408 Request Time-out 服務(wù)器等待客戶(hù)端發(fā)送的請(qǐng)求時(shí)間過(guò)長(zhǎng),超時(shí)
409 Conflict 服務(wù)器完成客戶(hù)端的PUT請(qǐng)求是可能返回此代碼,服務(wù)器處理請(qǐng)求時(shí)發(fā)生
沖突
410 Gone 客戶(hù)端請(qǐng)求的資源已經(jīng)不存在。410不同于404,如果資源以前有現(xiàn)在被
刪除了可使用410代碼,網(wǎng)站設(shè)計(jì)人員可通過(guò)301代碼指定資源的新位置
411 Length Required 服務(wù)器無(wú)法處理客戶(hù)端發(fā)送的不帶Content-Length的請(qǐng)求信息
412 Precondition Failed 客戶(hù)端請(qǐng)求信息的先決條件錯(cuò)誤
狀態(tài)碼 狀態(tài)碼英文名稱(chēng) 中文描述
7/87
413 Request Entity Too Large 由于請(qǐng)求的實(shí)體過(guò)大,服務(wù)器無(wú)法處理,因此拒絕請(qǐng)求。為防止客
端的連續(xù)請(qǐng)求,服務(wù)器可能會(huì)關(guān)閉連接。如果只是服務(wù)器暫時(shí)無(wú)法
理,則會(huì)包含一個(gè)Retry-After的響應(yīng)信息
414 Request-URI Too Large 請(qǐng)求的URI過(guò)長(zhǎng)(URI通常為網(wǎng)址),服務(wù)器無(wú)法處理
415 Unsupported Media Type 服務(wù)器無(wú)法處理請(qǐng)求附帶的媒體格式
416 Requested range not satisfiable 客戶(hù)端請(qǐng)求的范圍無(wú)效
417 Expectation Failed 服務(wù)器無(wú)法滿足Expect的請(qǐng)求頭信息
500 Internal Server Error 服務(wù)器內(nèi)部錯(cuò)誤,無(wú)法完成請(qǐng)求
501 Not Implemented 服務(wù)器不支持請(qǐng)求的功能,無(wú)法完成請(qǐng)求
502 Bad Gateway 作為網(wǎng)關(guān)或者代理工作的服務(wù)器嘗試執(zhí)行請(qǐng)求時(shí),從遠(yuǎn)程服務(wù)器接收到
個(gè)無(wú)效的響應(yīng)
503 Service Unavailable 由于超載或系統(tǒng)維護(hù),服務(wù)器暫時(shí)的無(wú)法處理客戶(hù)端的請(qǐng)求。延時(shí)的長(zhǎng)
包含在服務(wù)器的Retry-After頭信息中
504 Gateway Time-out 充當(dāng)網(wǎng)關(guān)或代理的服務(wù)器,未及時(shí)從遠(yuǎn)端服務(wù)器獲取請(qǐng)求
505 HTTP Version not supported 服務(wù)器不支持請(qǐng)求的HTTP協(xié)議的版本,無(wú)法完成處理
狀態(tài)碼 狀態(tài)碼英文名稱(chēng) 中文描述
apache虛擬主機(jī)
創(chuàng)建apache虛擬主機(jī)
1.安裝apache服務(wù) yum -y install httpd httpd-tools httpd-devel mod_ssl (支持https認(rèn)證) systemctl start httpd
systemctl enable httpd 2.創(chuàng)建虛擬主機(jī)的配置文件 /etc/httpd/conf.d/ 下創(chuàng)建.conf的虛擬主機(jī)配置文件 (主配置文件在/etc/httpd/ conf/httpd.conf)
分類(lèi):
基于 端口
基于ip
基于域名
第一種:基于域名的虛擬主機(jī) vim /etc/httpd/conf.d/web.conf < VirtualHost *:80 >
Servername www.blackmed.cn serverAlias blackmed.cn DocumentRoot /web1
</VirtualHost >
<Directory "/wed1" > Require all granted
</Directory >
<VirtualHost *:80 >
ServerName www.blackcloud.cn
ServerAlias blackcloud.cn
DocumentRoot /web2
</VirtualHost >
<Directory " /web2 "> Require all granted
</Directory>
3.創(chuàng)建網(wǎng)站發(fā)布目錄和網(wǎng)站
mkdir /web1 /web2
8/87
注意:一般的公司都是基于域名創(chuàng)建虛擬主機(jī)基于ip創(chuàng)建的虛擬主機(jī),其他的相同,ip不同
基于端口創(chuàng)建的虛擬主機(jī),其他的相同,端口不同
Nginx
簡(jiǎn)介
Nginx (engine x) 是一個(gè)高性能的 HTTP 和 反向代理 服務(wù),也是一個(gè)IMAP/POP3/SMTP服務(wù)。Nginx是由伊戈?duì)枴べ愃饕驗(yàn)槎砹_斯訪問(wèn)量第二的Rambler.ru站點(diǎn)(俄文:Рамблер)開(kāi)發(fā)的,第一個(gè)公開(kāi)版本0.1.0發(fā)布于
2004年10月4日。其將源代碼以類(lèi)BSD許可證的形式發(fā)布,因它的穩(wěn)定性、豐富的功能集、示例配置文件和低系統(tǒng)資源的消耗而聞名。2011年6月1日,nginx 1.0.4發(fā)布。
Nginx是一款輕量級(jí)的Web 服務(wù)器/反向代理服務(wù)器及電子郵件(IMAP/POP3)代理服務(wù)器,并在一個(gè)BSD-like 協(xié)議下發(fā)行。其特點(diǎn)是占有內(nèi)存少,并發(fā)能力強(qiáng),事實(shí)上nginx的并發(fā)能力確實(shí)在同類(lèi)型的網(wǎng)頁(yè)服務(wù)器中表現(xiàn)較好,中國(guó)大陸使用nginx網(wǎng)站用戶(hù)有:百度、京東、新浪、網(wǎng)易、騰訊、淘寶等。
在高連接并發(fā)的情況下,Nginx是Apache服務(wù)器不錯(cuò)的替代品。
創(chuàng)始人伊戈?duì)枴べ愃饕?/p>
9/87
nginx功能
Nginx 是一個(gè)高性能的 Web 和反向代理服務(wù)器, 它具有有很多非常優(yōu)越的特性:
單機(jī)環(huán)境下參考服務(wù)器配置。 并發(fā)連接數(shù)在7000+ -8000左右。 集群模式20000+
作為 Web 服務(wù)器:相比 Apache,Nginx 使用更少的資源,支持更多的并發(fā)連接,體現(xiàn)更高的效率,這
點(diǎn)使 Nginx 尤其受到虛擬主機(jī)提供商的歡迎。能夠支持高達(dá) 50,000 個(gè)并發(fā)連接數(shù)的響應(yīng),感謝 Nginx 為我們選擇了 epoll and kqueue 作為開(kāi)發(fā)模型.
作為負(fù)載均衡服務(wù)器:Nginx 既可以在內(nèi)部直接支持 Rails 和 PHP,也可以支持作為 HTTP代理服務(wù)器對(duì)外進(jìn)行服務(wù)。Nginx 用 C 編寫(xiě), 不論是系統(tǒng)資源開(kāi)銷(xiāo)還是 CPU 使用效率都比 Perlbal 要好的多。
作為郵件代理服務(wù)器: Nginx 同時(shí)也是一個(gè)非常優(yōu)秀的郵件代理服務(wù)器(最早開(kāi)發(fā)這個(gè)產(chǎn)品的目的之
一也是作為郵件代理服務(wù)器),Last.fm 描述了成功并且美妙的使用經(jīng)驗(yàn)。
Nginx 安裝非常的簡(jiǎn)單,配置文件 非常簡(jiǎn)潔(還能夠支持perl語(yǔ)法),Bugs非常少的服務(wù)器: Nginx 啟
動(dòng)特別容易,并且?guī)缀蹩梢宰龅?*24不間斷運(yùn)行,即使運(yùn)行數(shù)個(gè)月也不需要重新啟動(dòng)。你還能夠在 不間斷服務(wù)的情況下進(jìn)行軟件版本的升級(jí)。
異步,非阻塞
$ pstree |grep nginx
|-+= 81666 root nginx: master process nginx
| |--- 82500 nobody nginx: worker process
| --- 82501 nobody nginx: worker process
1個(gè)master進(jìn)程,2個(gè)work進(jìn)程
10/87
注意:Input/Output====I/O
每進(jìn)來(lái)一個(gè)request,會(huì)有一個(gè)worker進(jìn)程去處理。但不是全程的處理,處理到什么程度呢?處理到可能發(fā)生阻塞的地方,比如向上游(后端)服務(wù)器轉(zhuǎn)發(fā)request,并等待請(qǐng)求返回。那么,這個(gè)處理的worker不會(huì)這么一直等著,他會(huì)在發(fā)送完請(qǐng)求后,注冊(cè)一個(gè)事件:“如果upstream返回了,告訴我一聲,我再接著干”。于是他就休息去了。這就是異步。此時(shí),如果再有request 進(jìn)來(lái),他就可以很快再按這種方式處理。這就是非阻塞和IO多路復(fù)用。而一旦上游服務(wù)器返回了,就會(huì)觸發(fā)這個(gè)事件,worker才會(huì)來(lái)接手,這個(gè)request才會(huì)接著往下走。這就是異步回調(diào)。
客戶(hù)(發(fā)送方)向收款員(接收方)付款(發(fā)送請(qǐng)求)后在等待收款員找零的過(guò)程中,還可以做其他
事情,比如打電話、聊天等;而收款員在等待收款機(jī)處理交易(IO操作)的過(guò)程中還可以幫助客戶(hù)將商品打包,當(dāng)收款機(jī)產(chǎn)生結(jié)果后,收款員給客戶(hù)結(jié)賬(響應(yīng)請(qǐng)求)。在四種方式中,這種方式是發(fā)送方和接收方通信效率最高的一種。
同步與異步的重點(diǎn)在消息通知的方式上,也就是調(diào)用結(jié)果通知的方式。
同步:當(dāng)一個(gè)同步調(diào)用發(fā)出去后,調(diào)用者要一直等待調(diào)用結(jié)果的通知后,才能進(jìn)行后續(xù)的執(zhí)行。異步:當(dāng)一個(gè)異步調(diào)用發(fā)出去后,調(diào)用者不能立即得到調(diào)用結(jié)果的返回。
同步取快遞:小明收到快遞將送達(dá)的短信,在樓下一直等到快遞送達(dá)。
異步取快遞:小明收到快遞將送達(dá)的短信,快遞到樓下后,小明再下樓去取。異步取快遞,小明知道快遞到達(dá)樓下有兩種方式:
1、不停的電話問(wèn)快遞小哥到了沒(méi)有,即主動(dòng)輪詢(xún);
2、快遞小哥到樓下后,打電話通知小明,然后小明下樓取快遞,即回調(diào)通知。
阻塞與非阻塞在于進(jìn)/線程等待消息時(shí)候的行為,也就是在等待消息的時(shí)候,當(dāng)前進(jìn)/線程是掛起還是非掛起狀態(tài)。
-阻塞阻塞調(diào)用在發(fā)出去后,在消息返回之前,當(dāng)前進(jìn)/線程會(huì)被掛起,直到有消息返回,當(dāng)前進(jìn)/線程才會(huì)被激活
-非阻塞非阻塞調(diào)用在發(fā)出去后,不會(huì)阻塞當(dāng)前進(jìn)/線程,而會(huì)立即返回。
阻塞取快遞:小明收到快遞即將送達(dá)的信息后,什么事都不做,一直專(zhuān)門(mén)等快遞。
非阻塞取快遞:小明收到快遞即將送達(dá)的信息后,等快遞的時(shí)候,還一邊敲代碼、一邊刷微信。
總結(jié): 異步非阻塞:小明收到信息后,邊刷著微博,邊等快遞員通知他取快遞。
I/O多路復(fù)用 epoll()
epoll能更高效的檢查大量fd,UNIX中提供了類(lèi)似功能的kqueue調(diào)用。epoll可以理解為event poll,不同于忙輪詢(xún)和無(wú)差別輪詢(xún),當(dāng)連接有I/O流事件產(chǎn)生的時(shí)候,epoll就會(huì)去告
訴進(jìn)程哪個(gè)連接有I/O流事件產(chǎn)生,然后進(jìn)程就去處理這個(gè)事件。此時(shí)我們對(duì)這些流的操作都是有意義的。(復(fù)雜度降低到了O(k),k為產(chǎn)生I/O事件的流的個(gè)數(shù),也有認(rèn)為O(1)的)
小明家樓下有一個(gè)收發(fā)室,每次有快遞到了,就先代收并做了標(biāo)記;然后通知小明去取送給小明的快遞。
nginx 的內(nèi)部技術(shù)架構(gòu)
Nginx服務(wù)器,以其處理網(wǎng)絡(luò)請(qǐng)求的高并發(fā)、高性能及高效率,獲得了行業(yè)界的廣泛認(rèn)可,近年已穩(wěn)居web服務(wù)器部署排名第二的位置,并被廣泛用于反向代理和負(fù)載均衡。
Nginx是如何實(shí)現(xiàn)這些目標(biāo)的呢?答案就是其獨(dú)特的內(nèi)部技術(shù)架構(gòu)設(shè)計(jì)。看懂下面這張圖,就明白了
Nginx的內(nèi)部技術(shù)架構(gòu)。
簡(jiǎn)要說(shuō)明幾點(diǎn):
1)nginx啟動(dòng)時(shí),會(huì)生成兩種類(lèi)型的進(jìn)程,一個(gè)是主進(jìn)程(Master),一個(gè)(windows版本的目前只有一
11/87
個(gè))或多個(gè)工作進(jìn)程(Worker)。主進(jìn)程并不處理網(wǎng)絡(luò)請(qǐng)求,主要負(fù)責(zé)調(diào)度工作進(jìn)程,也就是圖示的三
項(xiàng):加載配置、啟動(dòng)工作進(jìn)程及非停升級(jí)。所以,nginx啟動(dòng)以后,查看操作系統(tǒng)的進(jìn)程列表,我們就能看到至少有兩個(gè)nginx進(jìn)程。
2)服務(wù)器實(shí)際處理網(wǎng)絡(luò)請(qǐng)求及響應(yīng)的是工作進(jìn)程(worker),在類(lèi)unix系統(tǒng)上,nginx可以配置多個(gè)worker,而每個(gè)worker進(jìn)程都可以同時(shí)處理數(shù)以千計(jì)的網(wǎng)絡(luò)請(qǐng)求。
3)模塊化設(shè)計(jì)。nginx的worker,包括核心和功能性模塊,核心模塊負(fù)責(zé)維持一個(gè)運(yùn)行循環(huán)(run-loop),執(zhí)行網(wǎng)絡(luò)請(qǐng)求處理的不同階段的模塊功能,如網(wǎng)絡(luò)讀寫(xiě)、存儲(chǔ)讀寫(xiě)、內(nèi)容傳輸、外出過(guò)濾,以及將請(qǐng)求發(fā)往上游服務(wù)器等。而其代碼的模塊化設(shè)計(jì),也使得我們可以根據(jù)需要對(duì)功能模塊進(jìn)行適當(dāng)?shù)倪x擇和修改,編譯成具有特定功能的服務(wù)器。
4)事件驅(qū)動(dòng)、異步及非阻塞,可以說(shuō)是nginx得以獲得高并發(fā)、高性能的關(guān)鍵因素,同時(shí)也得益于對(duì)
Linux、Solaris及類(lèi)BSD等操作系統(tǒng)內(nèi)核中事件通知及I/O性能增強(qiáng)功能的采用,如kqueue、epoll及event ports。5)代理(proxy)設(shè)計(jì),可以說(shuō)是nginx深入骨髓的設(shè)計(jì),無(wú)論是對(duì)于HTTP,還是對(duì)于FastCGI、
memcache、Redis等的網(wǎng)絡(luò)請(qǐng)求或響應(yīng),本質(zhì)上都采用了代理機(jī)制。所以,nginx天生就是高性能的代理服務(wù)器
nginx安裝部署
nginx部署-Yum安裝
訪問(wèn)nginx的官方網(wǎng)站:http://www.nginx.org/ Nginx版本類(lèi)型 Mainline version: 主線版,即開(kāi)發(fā)版
Stable version: 最新穩(wěn)定版,生產(chǎn)環(huán)境上建議使用的版本
Legacy versions: 遺留的老版本的穩(wěn)定版
Yum安裝nginx
配置Yum源的官網(wǎng):http://nginx.org/en/linux_packages.html
1、配置nginx的Yum源 Installation instructions
Before you install nginx for the first time on a new machine, you need to set up the nginx packages repository. Afterward, you can install and update nginx from the repository.
安裝說(shuō)明
在新計(jì)算機(jī)上首次安裝nginx之前,需要設(shè)置nginx軟件包存儲(chǔ)庫(kù)。 之后,您可以從存儲(chǔ)庫(kù)安裝和更新nginx。
To set up the yum repository, create the file named /etc/yum.repos.d/nginx.repo with the following contents:
[nginx-stable] name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1
enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key
[nginx-mainline] name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1
enabled=0
12/87
gpgkey=https://nginx.org/keys/nginx_signing.key
yum install yum-utils -y yum-config-manager --enable nginx-mainline yum install nginx -y
這里我們用穩(wěn)定版本 nginx -V //格式化打印
nginx version: nginx/1.16.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) built with OpenSSL 1.0.2k-fips
26 Jan 2017 TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx -- modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/ error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/ proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/ uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module -- with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
[root@nginx-server yum.repos.d]# nginx -v nginx version: nginx/1.16.0 關(guān)閉防火墻和selinux:
[root@nginx-server ~]# getenforce Enforcing
[root@nginx-server ~]# sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config [root@nginx-server ~]# systemctl stop firewalld
[root@nginx-server ~]# systemctl disable firewalld
啟動(dòng)并設(shè)置開(kāi)機(jī)啟動(dòng)
[root@nginx-server ~]# systemctl start nginx [root@nginx-server ~]# systemctl enable nginx
nginx編譯安裝
1、安裝編譯環(huán)境
yum -y install gcc gcc-c++ make ncurses ncurses-devel
2、安裝pcre軟件包(使nginx支持http rewrite模塊) yum install -y pcre pcre-devel
3、安裝openssl-devel(使nginx支持ssl) yum install -y openssl openssl-devel
4、安裝zlib yum install -y zlib zlib-devel
5、創(chuàng)建用戶(hù)nginx useradd nginx passwd nginx 6、安裝nginx
[root@localhost ~]# wget http://nginx.org/download/nginx-1.16.0.tar.gz [root@localhost ~]# tar xzf nginx-1.16.0.tar.gz -C /usr/local/ [root@localhost ~]# cd /usr/local/nginx-1.16.0/
13/87
[root@localhost nginx-1.16.0]# ./configure --prefix=/usr/local/nginx --group=nginx --user=nginx --sbin-path=/ usr/local/nginx/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/tmp/nginx/client_body --http-proxy-temp-path=/ tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/ nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre --with-http_realip_module --with-stream
[root@localhost nginx-1.16.0]# make && make install
編譯參數(shù)
[root@localhost ~]#/usr/local/nginx/sbin/nginx -V
--with-cc-opt='-g -O2 -fPIE -fstack-protector //設(shè)置額外的參數(shù)將被添加到CFLAGS變量。(FreeBSD或者ubuntu使用)
--param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now'
--prefix=/usr/local/nginx //指向安裝目錄
--conf-path=/etc/nginx/nginx.conf //指定配置文件
--http-log-path=/var/log/nginx/access.log//指定訪問(wèn)日志
--error-log-path=/var/log/nginx/error.log //指定錯(cuò)誤日志
--lock-path=/var/lock/nginx.lock //指定lock文件
--pid-path=/run/nginx.pid //指定pid文件
--http-client-body-temp-path=/var/lib/nginx/body //設(shè)定http客戶(hù)端請(qǐng)求臨時(shí)文件路徑
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi //設(shè)定http fastcgi臨時(shí)文件路徑
--http-proxy-temp-path=/var/lib/nginx/proxy //設(shè)定http代理臨時(shí)文件路徑
--http-scgi-temp-path=/var/lib/nginx/scgi //設(shè)定http scgi臨時(shí)文件路徑
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi //設(shè)定http uwsgi臨時(shí)文件路徑
--with-debug //啟用debug日志
--with-pcre-jit //編譯PCRE包含“just-in-time compilation”
--with-ipv6 //啟用ipv6支持
--with-http_ssl_module //啟用ssl支持
--with-http_stub_status_module //獲取nginx自上次啟動(dòng)以來(lái)的狀態(tài)
--with-http_realip_module //允許從請(qǐng)求標(biāo)頭更改客戶(hù)端的IP地址值,默認(rèn)為關(guān)
--with-http_auth_request_module //實(shí)現(xiàn)基于一個(gè)子請(qǐng)求的結(jié)果的客戶(hù)端授權(quán)。如果該子請(qǐng)求返回的
2xx響應(yīng)代碼,所述接入是允許的。如果它返回401或403中,訪問(wèn)被拒絕與相應(yīng)的錯(cuò)誤代碼。由子請(qǐng)求返回的任何其他響應(yīng)代碼被認(rèn)為是一個(gè)錯(cuò)誤。
--with-http_addition_module //作為一個(gè)輸出過(guò)濾器,支持不完全緩沖,分部分響應(yīng)請(qǐng)求
--with-http_dav_module //增加PUT,DELETE,MKCOL:創(chuàng)建集合,COPY和MOVE方法 默認(rèn)關(guān)閉,需
編譯開(kāi)啟
--with-http_geoip_module //使用預(yù)編譯的MaxMind數(shù)據(jù)庫(kù)解析客戶(hù)端IP地址,得到變量值
--with-http_gunzip_module //它為不支持“gzip”編碼方法的客戶(hù)端解壓具有“Content-Encoding:
gzip”頭的響應(yīng)。
--with-http_gzip_static_module //在線實(shí)時(shí)壓縮輸出數(shù)據(jù)流
--with-http_image_filter_module //傳輸JPEG/GIF/PNG 圖片的一個(gè)過(guò)濾器)(默認(rèn)為不啟用。gd庫(kù)要用
到)
--with-http_spdy_module //SPDY可以縮短網(wǎng)頁(yè)的加載時(shí)間
--with-http_sub_module //允許用一些其他文本替換nginx響應(yīng)中的一些文本
--with-http_xslt_module //過(guò)濾轉(zhuǎn)換XML請(qǐng)求
--with-mail //啟用POP3/IMAP4/SMTP代理模塊支持
--with-mail_ssl_module //啟用ngx_mail_ssl_module支持啟用外部模塊支持
14/87
nginx部署
nginx.conf的組成:nginx.conf一共由三部分組成,分別為:全局塊、events塊、http塊。在http塊中又包含http全局塊、多個(gè)server塊。每個(gè)server塊中又包含server全局塊以及多個(gè)location塊。在統(tǒng)一配置塊中嵌套的配置快,各個(gè)之間不存在次序關(guān)系。
worker_processes 4; #設(shè)置nginx啟動(dòng)進(jìn)程的數(shù)量,一般設(shè)置成與邏輯cpu數(shù)量相同 error_log logs/error.log; #指定錯(cuò)誤日志 worker_rlimit_nofile 102400; #設(shè)置一個(gè)nginx進(jìn)程能打開(kāi)的最大文件數(shù) pid /var/run/nginx.pid;
events {
worker_connections 1024; #設(shè)置一個(gè)進(jìn)程的最大并發(fā)連接數(shù)
}
include mime.types;
default_type application/octet-stream;
log_format main 'remote_addr - remote_user [time_local] "request" ' 'status body_bytes_sent "$http_referer" '
'"http_user_agent" "http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; #設(shè)置訪問(wèn)日志的位置和格式
sendfile on; #是否調(diào)用sendfile函數(shù)輸出文件,一般設(shè)置為on,若nginx是用來(lái)進(jìn)行磁盤(pán)IO負(fù)載應(yīng)用
時(shí),可以設(shè)置為off,降低系統(tǒng)負(fù)載
gzip on; #是否開(kāi)啟gzip壓縮,將注釋去掉開(kāi)啟
keepalive_timeout 65; #設(shè)置長(zhǎng)連接的超時(shí)時(shí)間
#虛擬服務(wù)器的相關(guān)設(shè)置 server {
listen 80;#設(shè)置監(jiān)聽(tīng)的端口
server_name localhost; #設(shè)置綁定的主機(jī)名、域名或ip地址
charset koi8-r; # 設(shè)置編碼字符
location / {
root /var/www/nginx; #設(shè)置服務(wù)器默認(rèn)網(wǎng)站的根目錄位置,需要手動(dòng)創(chuàng)建
index index.html index.htm; #設(shè)置默認(rèn)打開(kāi)的文檔
}
error_page 500 502 503 504 /50x.html; #設(shè)置錯(cuò)誤信息返回頁(yè)面
location = /50x.html {
root html; #這里的絕對(duì)位置是/usr/local/nginx/html
}
}
}
檢測(cè)nginx配置文件是否正確
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t [root@localhost ~]# mkdir -p /tmp/nginx
啟動(dòng)nginx服務(wù)
[root@localhost ~]# /usr/local/nginx/sbin/nginx
通過(guò) nginx 命令控制 nginx 服務(wù)
nginx -c /path/nginx.conf # 以特定目錄下的配置文件啟動(dòng)nginx:
nginx -s reload # 修改配置后重新加載生效
nginx -s reopen # 重新打開(kāi)日志文件
nginx -s stop # 快速停止nginx
nginx -s quit # 完整有序的停止nginx
nginx -t # 測(cè)試當(dāng)前配置文件是否正確
nginx -t -c /path/to/nginx.conf # 測(cè)試特定的nginx配置文件是否正確
15/87
注意:
nginx -s reload 命令加載修改后的配置文件,命令下達(dá)后發(fā)生如下事件
1.Nginx的master進(jìn)程檢查配置文件的正確性,若是錯(cuò)誤則返回錯(cuò)誤信息,nginx繼續(xù)采用原配置文件進(jìn)行工作(因?yàn)閣orker未受到影響)
2.Nginx啟動(dòng)新的worker進(jìn)程,采用新的配置文件
3.Nginx將新的請(qǐng)求分配新的worker進(jìn)程
4.Nginx等待以前的worker進(jìn)程的全部請(qǐng)求已經(jīng)都返回后,關(guān)閉相關(guān)worker進(jìn)程
5.重復(fù)上面過(guò)程,知道全部舊的worker進(jìn)程都被關(guān)閉掉
實(shí)現(xiàn)nginx開(kāi)機(jī)自啟
[root@localhost ~]# vim /etc/init.d/nginx #!/bin/sh
#
#nginx - this script starts and stops the nginx daemon
#
#chkconfig: - 85 15
#description: Nginx is an HTTP(S) server, HTTP(S) reverse \
#proxy and IMAP/POP3 proxy server
#processname: nginx
#config: /etc/nginx/nginx.conf
#config: /etc/sysconfig/nginx
#pidfile: /var/run/nginx.pid
#Source function library.
. /etc/rc.d/init.d/functions
#Source networking configuration.
. /etc/sysconfig/network
#Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/local/nginx/sbin/nginx" prog=$(basename $nginx)
NGINX_CONF_FILE="/etc/nginx/nginx.conf"
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
lockfile=/var/lock/nginx
make_dirs() {
user=nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -
options=$nginx -V 2>&1 | grep 'configure arguments:'
for opt in $options; do
if [ echo $opt | grep '.*-temp-path'
]; then value=echo $opt | cut -d "=" -f 2
16/87
if [ ! -d "$value" ]; then
mkdir -p $value && chown -R $user $value
fi
fi done
}
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6 make_dirs
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile return $retval
}
stop() {
echo -n $"Stopping $prog: " killproc $prog -QUIT retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile return $retval
}
restart() {
configtest || return $? stop
sleep 1 start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: " killproc $nginx -HUP RETVAL=$?
echo
}
force_reload() { restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() { status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
17/87
start)
rh_status_q && exit 0 $1
;;
stop)
rh_status_q || exit 0 $1
;;
restart|configtest) $1
;;
reload)
rh_status_q || exit 7 $1
;;
force-reload) force_reload
;;
status) rh_status
;;
condrestart|try-restart) rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" exit 2
esac
添加權(quán)限
chmod +x /etc/init.d/nginx
重新加載系統(tǒng)啟動(dòng)文件
systemctl daemon-reload
啟動(dòng)并設(shè)置開(kāi)機(jī)自啟 systemctl start nginx
[root@localhost ~]# /sbin/chkconfig nginx on ---開(kāi)機(jī)啟動(dòng)
nginx自帶變量
nginx 日志文件分為 log_format 和 access_log 兩部分 log_format 定義記錄的格式,其語(yǔ)法格式為 access_log 樣式名稱(chēng) 樣式詳情
log_format main 'remote_addr - remote_user [time_local] "request" ' 'status body_bytes_sent "$http_referer" ' '"http_user_agent" "http_x_forwarded_for"';
18/87
nginx虛擬主機(jī)
什么是虛擬主機(jī)?
虛擬主機(jī)是一種特殊的軟硬件技術(shù),它可以將網(wǎng)絡(luò)上的每一臺(tái)計(jì)算機(jī)分成多個(gè)虛擬主機(jī),每個(gè)虛擬主
機(jī)可以獨(dú)立對(duì)外提供www服務(wù),這樣就可以實(shí)現(xiàn)一臺(tái)主機(jī)對(duì)外提供多個(gè)web服務(wù),每個(gè)虛擬主機(jī)之間是獨(dú)立的,互不影響。
nginx可以實(shí)現(xiàn)虛擬主機(jī)的配置,nginx支持三種類(lèi)型的虛擬主機(jī)配置。1、基于域名的虛擬主機(jī) (server_name來(lái)區(qū)分虛擬主機(jī)——應(yīng)用:外部網(wǎng)站)2、基于ip的虛擬主機(jī), (一塊主機(jī)綁定多個(gè)ip地址)
3、基于端口的虛擬主機(jī) (端口來(lái)區(qū)分虛擬主機(jī)——應(yīng)用:公司內(nèi)部網(wǎng)站,外部網(wǎng)站的管理后臺(tái))
19/87
基于域名
1、 基于域名的虛擬主機(jī)
[root@localhost ~]# cat /etc/nginx/nginx.conf worker_processes 4;
#error_log logs/error.log; worker_rlimit_nofile 102400;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name web.testpm.com;
location / {
root /var/www/nginx/;
index index.html index.htm;
limit_rate 2k;
}
}
server {
listen 80;
server_name web.1000phone.com;
location / {
root /1000phone/html;
index index.html index.htm;
}
}
}
2.為 域名為 web.1000phone.com 的虛擬機(jī),創(chuàng)建 index 文件 [root@localhost ~]# mkdir -p /1000phone/html [root@localhost ~]# vim /1000phone/html/index.html
<html>
<p>
this is my 1000phone </p>
</html> 3.重新加載配置文件
[root@nginx]# /usr/local/nginx/sbin/nginx -s reload
[root@nginx]# nginx -s reload
4.客戶(hù)端配置路由映射
10.0.105.199 web.testpm.com 10.0.105.199 web.1000phone.com 5. 測(cè)試訪問(wèn)瀏覽器輸入:http://web.testpm.com/
瀏覽器輸入:http://web.1000phone.com/
20/87
基于IP
[root@localhost ~]# ip a
1:lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2:ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:17:f1:af brd ff:ff:ff:ff:ff:ff
inet 10.0.105.199/24 brd 10.0.105.255 scope global dynamic ens33 valid_lft 81438sec preferred_lft 81438sec
inet6 fe80::9d26:f3f0:db9c:c9be/64 scope link valid_lft forever preferred_lft forever
[root@localhost ~]# ifconfig ens33:1 10.0.105.201/24 [root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.105.199 netmask 255.255.255.0 broadcast 10.0.105.255 inet6 fe80::9d26:f3f0:db9c:c9be prefixlen 64 scopeid 0x20<link> ether 00:0c:29:17:f1:af txqueuelen 1000 (Ethernet)
RX packets 9844 bytes 1052722 (1.0 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 5567 bytes 886269 (865.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens33:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.105.201 netmask 255.255.255.0 broadcast 10.0.105.255 ether 00:0c:29:17:f1:af txqueuelen 1000 (Ethernet)
2、配置通過(guò)ip區(qū)分的虛擬機(jī)
[root@localhost ~]# cat /etc/nginx/nginx.conf user root;
worker_processes 4;
#error_log logs/error.log; worker_rlimit_nofile 102400;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
server {
listen 10.0.105.199:80; server_name web.testpm.com; location / {
21/87
root /var/www/nginx/; index index.html index.htm; limit_rate 2k;
}
server {
listen 10.0.105.201:80; server_name web.testpm.com; location / {
root /1000phone/html/; index index.html index.htm;
}
}
}
3、重新加載配置文件
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
4、 測(cè)試訪問(wèn)瀏覽器輸入:http://10.0.105.199
瀏覽器輸入:http://10.0.105.201
5、補(bǔ)充
[root@localhost ~]# ifconfig ens33:1 10.0.105.201/24 down 重啟一下nginx [root@localhost ~]# systemctl restart nginx
基于端口
[root@localhost ~]# cat /etc/nginx/nginx.conf user root;
worker_processes 4;
worker_rlimit_nofile 102400;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name web.testpm.com; location / {
root /var/www/nginx/; index index.html index.htm; limit_rate 2k;
22/87
}
server {
listen 8080;
server_name web.1000phone.com; location / {
root /1000phone/html/; index index.html index.htm;
}
}
}
重新加載配置文件:
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
測(cè)試訪問(wèn):
瀏覽器輸入:http://web.testpm.com/
瀏覽器輸入:http://web.1000phone.com:8080
錯(cuò)誤解決
一. 問(wèn)題描述: 配置完 nginx 兩個(gè)虛擬機(jī)后,客戶(hù)端能夠訪問(wèn)原始的server ,新增加的 server 虛擬機(jī) 不能夠訪問(wèn),報(bào)錯(cuò)如下頁(yè)面
解決過(guò)程:
[root@localhost ~]# cat /var/log/nginx/error.log
2017/06/15 04:00:57 [error] 6702#0: *14 "/root/html/index.html" is forbidden (13: Permission denied), client:
10.219.24.1, server: web.1000phone.com, request: "GET / HTTP/1.1", host: "web.1000phone.com" 2.檢查權(quán)限
[root@localhost html]# ll
drwxr-xr-x. 2 root root 4096 Jun 15 03:59 html [root@localhost nginx]# ll
total 8
-rw-r--r--. 1 root root 537 Jun 15 03:59 50x.html -rw-r--r--. 1 root root 616 Jun 15 03:51 index.html
說(shuō)明:發(fā)現(xiàn)目錄權(quán)限沒(méi)有問(wèn)題
3.檢查nginx啟動(dòng)進(jìn)程 [root@localhost nginx]# ps -ef | grep nginx
root 2079 1 0 12:16 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /etc/nginx/
nginx.conf
nobody 2080 2079 0 12:16 ? 00:00:00 nginx: worker process
nobody 2081 2079 0 12:16 ? 00:00:00 nginx: worker process
nobody 2082 2079 0 12:16 ? 00:00:00 nginx: worker process
說(shuō)明:發(fā)現(xiàn)nginx的work process是 nobody 的4.修改 nginx.conf 文件
23/87
打開(kāi)nginx.conf文件所在的目錄,查看文件的屬性 (root root) [root@nginx]# ll
drwxr-xr-x. 2 root root 4096 Jun 15 04:08 conf 在nginx.conf文件的第一行加上 user root root; [root@nginx]# cat conf/nginx.conf
user root;
5.重新 reload nginx進(jìn)程
nginx Proxy 代理
1、代理原理反向代理產(chǎn)生的背景:
在計(jì)算機(jī)世界里,由于單個(gè)服務(wù)器的處理客戶(hù)端(用戶(hù))請(qǐng)求能力有一個(gè)極限,當(dāng)用戶(hù)的接入請(qǐng)求蜂擁而入時(shí),會(huì)造成服務(wù)器忙不過(guò)來(lái)的局面,可以使用多個(gè)服務(wù)器來(lái)共同分擔(dān)成千上萬(wàn)的用戶(hù)請(qǐng)求,這些服務(wù)器提供相同的服務(wù),對(duì)于用戶(hù)來(lái)說(shuō),根本感覺(jué)不到任何差別。
反向代理服務(wù)的實(shí)現(xiàn):
需要有一個(gè)負(fù)載均衡設(shè)備(即反向代理服務(wù)器)來(lái)分發(fā)用戶(hù)請(qǐng)求,將用戶(hù)請(qǐng)求分發(fā)到空閑的服務(wù)器上。服務(wù)器返回自己的服務(wù)到負(fù)載均衡設(shè)備。
負(fù)載均衡設(shè)備將服務(wù)器的服務(wù)返回用戶(hù)。
24/87
2、正/反向代理的區(qū)別
那么問(wèn)題來(lái)了,很多人這時(shí)會(huì)問(wèn)什么是反向代理?為什么叫反向代理?什么是正向代理?我們來(lái)舉例說(shuō)明
? 正向代理:舉例:
貸款
正向代理的過(guò)程隱藏了真實(shí)的請(qǐng)求客戶(hù)端,服務(wù)器不知道真實(shí)的客戶(hù)端是誰(shuí),客戶(hù)端請(qǐng)求的服務(wù)都被代理服務(wù)器代替請(qǐng)求。我們常說(shuō)的代理也就是正向代理,正向代理代理的是請(qǐng)求方,也就是客戶(hù)端;比如
我們要訪問(wèn)youtube,可是不能訪問(wèn),只能先安裝個(gè)FQ軟件代你去訪問(wèn),通過(guò)FQ軟件才能訪問(wèn),F(xiàn)Q軟件就叫作正向代理。
正向代理中,proxy和client同屬一個(gè)LAN
25/87
反向代理:
反向代理的過(guò)程隱藏了真實(shí)的服務(wù)器,客戶(hù)不知道真正提供服務(wù)的人是誰(shuí),客戶(hù)端請(qǐng)求的服務(wù)都被代理服務(wù)器處理。反向代理代理的是響應(yīng)方,也就是服務(wù)端;我們請(qǐng)求www.baidu.com時(shí)這www.baidu.com就是反向代理服務(wù)器,真實(shí)提供服務(wù)的服務(wù)器有很多臺(tái),反向代理服務(wù)器會(huì)把我們的請(qǐng)求分轉(zhuǎn)發(fā)到真實(shí)提供
服務(wù)的各臺(tái)服務(wù)器。Nginx就是性能非常好的反向代理服務(wù)器,用來(lái)做負(fù)載均衡。訪問(wèn)www.baidu.com是正向代理的過(guò)程
反向代理中,proxy和server同屬一個(gè)LAN
正向代理和反向代理對(duì)比示意圖兩者的區(qū)別在于代理的對(duì)象不一樣:
正向代理中代理的對(duì)象是客戶(hù)端,proxy和client同屬一個(gè)LAN,對(duì)server透明;反向代理中代理的對(duì)象是服務(wù)端,proxy和server同屬一個(gè)LAN,對(duì)client透明。
26/87
27/87
nginx proxy
1、代理模塊 ngx_http_proxy_module
2、代理配置
代理
Syntax: proxy_pass URL; #代理的后端服務(wù)器URL
Default: —
Context: location, if in location, limit_except
緩沖區(qū)
Syntax: proxy_buffering on | off;
Default: proxy_buffering on; #緩沖開(kāi)關(guān)
Context: http, server, location
proxy_buffering開(kāi)啟的情況下,nignx會(huì)把后端返回的內(nèi)容先放到緩沖區(qū)當(dāng)中,然后再返回給客戶(hù)端(邊收邊傳,不是全部接收完再傳給客戶(hù)端)。
Syntax: proxy_buffer_size size;
Default: proxy_buffer_size 4k|8k; #緩沖區(qū)大小
Context: http, server, location
Syntax: proxy_buffers number size;
Default: proxy_buffers 8 4k|8k; #緩沖區(qū)數(shù)量
Context: http, server, location
Syntax: proxy_busy_buffers_size size;
Default: proxy_busy_buffers_size 8k|16k;#忙碌的緩沖區(qū)大小控制同時(shí)傳遞給客戶(hù)端的buffer數(shù)量
Context: http, server, location
頭信息
Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host; #設(shè)置真實(shí)客戶(hù)端地址 proxy_set_header Connection close;
Context: http, server, location
超時(shí)
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s; #鏈接超時(shí)
Context: http, server, location
Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location
3、啟用 nginx proxy 代理
環(huán)境兩臺(tái)nginx真實(shí)服務(wù)器a、nginx-1 啟動(dòng)網(wǎng)站(內(nèi)容)(作為網(wǎng)站服務(wù)器)
nginx-1的ip:10.0.105.199:已經(jīng)編譯安裝好,檢查nginx是否啟動(dòng)是否可以訪問(wèn)b、nginx-2 啟動(dòng)代理程序nginx-2的ip:10.0.105.202配置nginx的yum源直接yum安裝啟動(dòng)編輯nginx的配置文件:
[root@nginx-server ~]# vim /etc/nginx/conf.d/default.conf server {
server { listen 80;
server_name localhost;
28/87
location / {
proxy_pass http://10.0.105.199:80; proxy_redirect default; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; #proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30; proxy_send_timeout 60; proxy_read_timeout 60;
proxy_buffering on; proxy_buffer_size 32k; proxy_buffers 4 128k; proxy_busy_buffers_size 256k; proxy_max_temp_file_size 256k;
}
}
重新加載nginx配置文件
[root@nginx-server ~]# nginx -s reload
c、nginx proxy 具體配置詳解
proxy_pass :真實(shí)服務(wù)器的地址,可以是ip也可以是域名和url地址 proxy_redirect :如果真實(shí)服務(wù)器使用的是的真實(shí)IP:非默認(rèn)端口。則改成IP:默認(rèn)端口。proxy_set_header:重新定義或者添加發(fā)往后端服務(wù)器的請(qǐng)求頭
proxy_set_header X-Real-IP :?jiǎn)⒂每蛻?hù)端真實(shí)地址(否則日志中顯示的是代理在訪問(wèn)網(wǎng)站) proxy_set_header X-Forwarded-For:記錄代理地址
proxy_connect_timeout::后端服務(wù)器連接的超時(shí)時(shí)間發(fā)起三次握手等候響應(yīng)超時(shí)時(shí)間proxy_send_timeout:后端服務(wù)器數(shù)據(jù)回傳時(shí)間就是在規(guī)定時(shí)間之內(nèi)后端服務(wù)器必須傳完所有的數(shù)據(jù) proxy_read_timeout :nginx接收upstream(上游/真實(shí)) server數(shù)據(jù)超時(shí), 默認(rèn)60s, 如果連續(xù)的60s內(nèi)沒(méi)有收到
1個(gè)字節(jié), 連接關(guān)閉。像長(zhǎng)連接
proxy_buffering on;開(kāi)啟緩存proxy_buffer_size:proxy_buffer_size只是響應(yīng)頭的緩沖區(qū) proxy_buffers 4 128k; 內(nèi)容緩沖區(qū)域大小
proxy_busy_buffers_size 256k; 從proxy_buffers劃出一部分緩沖區(qū)來(lái)專(zhuān)門(mén)向客戶(hù)端傳送數(shù)據(jù)的地方 proxy_max_temp_file_size 256k;超大的響應(yīng)頭存儲(chǔ)成文件。
注意:
29/87
2.proxy_pass http:// 填寫(xiě)nginx-1服務(wù)器的地址。
d、 使用PC客戶(hù)端訪問(wèn)nginx-2服務(wù)器地址 瀏覽器中輸入http://10.0.105.202 (也可以是nginx-2服務(wù)器的域名)成功訪問(wèn)nginx-1服務(wù)器頁(yè)面
e、 觀察nginx-1服務(wù)器的日志
10.0.105.202 - - [27/Jun/2019:15:54:17 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "10.0.105.207" 10.0.105.202 代理服務(wù)器地址 10.0.105.207 客戶(hù)機(jī)地址。
訪問(wèn)成功。 記錄了客戶(hù)機(jī)的IP和代理服務(wù)器的IP
30/87
擴(kuò)展1
nginx 負(fù)載均衡
隨著網(wǎng)站、應(yīng)用訪問(wèn)量的增加,一臺(tái)服務(wù)器已經(jīng)不能滿足應(yīng)用的需求,而需要多臺(tái)服務(wù)器集群,這時(shí)就會(huì)用到負(fù)載均衡
upstream標(biāo)簽
負(fù)載均衡配置: upstream testapp {
server 10.0.105.199:8081; server 10.0.105.202:8081;
}
server {
....
location / {
proxy_pass http://testapp; #請(qǐng)求轉(zhuǎn)向 testapp 定義的服務(wù)器列表
}
upstream mysvr {
server http://10.0.105.199:8081; server http://10.0.105.202:8081;
}
server {
....
location / {
proxy_pass http://mysvr; #請(qǐng)求轉(zhuǎn)向mysvr 定義的服務(wù)器列表
}
負(fù)載均衡算法
upstream 支持4種負(fù)載均衡調(diào)度算法: A、輪詢(xún)(默認(rèn)):每個(gè)請(qǐng)求按時(shí)間順序逐一分配到不同的后端服務(wù)器;
B、ip_hash:每個(gè)請(qǐng)求按訪問(wèn)IP的hash結(jié)果分配,同一個(gè)IP客戶(hù)端固定訪問(wèn)一個(gè)后端服務(wù)器??梢员WC來(lái)自同一ip的請(qǐng)求被打到固定的機(jī)器上,可以解決session問(wèn)題。C、url_hash:按訪問(wèn)url的hash結(jié)果來(lái)分配請(qǐng)求,使每個(gè)url定向到同一個(gè)后端服務(wù)器。
D、fair:這是比上面兩個(gè)更加智能的負(fù)載均衡算法。按后端服務(wù)器的響應(yīng)時(shí)間來(lái)分配請(qǐng)求,響應(yīng)時(shí)間短的優(yōu)先分配。Nginx本身是不支持 fair的,如果需要使用這種調(diào)度算法,必須下載Nginx的 upstream_fair模塊。
2、配置實(shí)例
1)、熱備:如果你有2臺(tái)服務(wù)器,當(dāng)一臺(tái)服務(wù)器發(fā)生事故時(shí),才啟用第二臺(tái)服務(wù)器給提供服務(wù)。服務(wù)器處理請(qǐng)求的順序:AAAAAA突然A掛啦,BBBBBBBBBBBBBB.....
upstream myweb {
server 172.17.14.2:8080;
31/87
server 172.17.14.3:8080 backup; #熱備
}
2)、輪詢(xún):nginx默認(rèn)就是輪詢(xún)其權(quán)重都默認(rèn)為1,服務(wù)器處理請(qǐng)求的順序:ABABABABAB....
upstream myweb {
server 172.17.14.2:8080; server 172.17.14.3:8080;
}
3)、加權(quán)輪詢(xún):跟據(jù)配置的權(quán)重的大小而分發(fā)給不同服務(wù)器不同數(shù)量的請(qǐng)求。如果不設(shè)置,則默認(rèn)為1。下
面服務(wù)器的請(qǐng)求順序?yàn)椋篈BBABBABBABBABB....
upstream myweb {
server 172.17.14.2:8080 weight=1; server 172.17.14.3:8080 weight=2;
}
4、ip_hash:nginx會(huì)讓相同的客戶(hù)端ip請(qǐng)求相同的服務(wù)器。 upstream myweb {
server 172.17.14.2:8080; server 172.17.14.3:8080; ip_hash;
}
5)、nginx負(fù)載均衡配置狀態(tài)參數(shù)
?down,表示當(dāng)前的server暫時(shí)不參與負(fù)載均衡。
?backup,預(yù)留的備份機(jī)器。當(dāng)其他所有的非backup機(jī)器出現(xiàn)故障或者忙的時(shí)候,才會(huì)請(qǐng)求backup機(jī)器,因此這臺(tái)機(jī)器的壓力最輕。
?max_fails,允許請(qǐng)求失敗的次數(shù),默認(rèn)為1。當(dāng)超過(guò)最大次數(shù)時(shí),返回proxy_next_upstream 模塊定義的錯(cuò)誤。
?fail_timeout,在經(jīng)歷了max_fails次失敗后,暫停服務(wù)的時(shí)間單位秒。max_fails可以和fail_timeout一起使用。
upstream myweb {
server 172.17.14.2:8080 weight=2 max_fails=2 fail_timeout=2; server 172.17.14.3:8080 weight=1 max_fails=2 fail_timeout=1;
}
nginx七層和四層方法
所謂四層就是基于IP+端口的負(fù)載均衡;七層就是基于URL等應(yīng)用層信息的負(fù)載均衡。
所謂的四層、七層負(fù)載均衡,就是在對(duì)后臺(tái)的服務(wù)器進(jìn)行負(fù)載均衡時(shí),依據(jù)四層的信息或七層的信息來(lái)決定怎么樣轉(zhuǎn)發(fā)流量。
七層負(fù)載均衡:準(zhǔn)備三臺(tái)機(jī)器:
一臺(tái)代理服務(wù)器兩臺(tái)WEB服務(wù)器
配置代理服務(wù)器的nginx配置文件 worker_processes 4;
32/87
worker_rlimit_nofile 102400;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on; keepalive_timeout 65; gzip on;
upstream testweb { ip_hash;
server 10.0.105.199:80 weight=2 max_fails=2 fail_timeout=2s; server 10.0.105.202:80 weight=2 max_fails=2 fail_timeout=2s;
}
server {
listen 80;
server_name www.test.com;
charset utf-8;
#access_log logs/host.access.log main;
location / {
proxy_pass http://testweb;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
upstream testapp {
server 10.0.105.202:8081 weight=2 max_fails=2 fail_timeout=2s; server 10.0.105.199:8081 weight=2 max_fails=2 fail_timeout=2s;
}
server {
listen 81;
server_name www.app.com; charset utf-8;
#access_log logs/host.access.log main; location / {
proxy_pass http://testapp; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
33/87
}
}
}
四層負(fù)載均衡(練習(xí))
nginx在1.9.0的時(shí)候,增加了一個(gè) stream 模塊,用來(lái)實(shí)現(xiàn)四層協(xié)議(網(wǎng)絡(luò)層和傳輸層)的轉(zhuǎn)發(fā)、代
理、負(fù)載均衡等。stream模塊的用法跟http的用法類(lèi)似,允許我們配置一組TCP或者UDP等協(xié)議的監(jiān)聽(tīng),然后通過(guò)proxy_pass來(lái)轉(zhuǎn)發(fā)我們的請(qǐng)求,通過(guò)upstream添加多個(gè)后端服務(wù),實(shí)現(xiàn)負(fù)載均衡。
#4層tcp負(fù)載 stream {
upstream myweb {
hash $remote_addr consistent; server 172.17.14.2:8080; server 172.17.14.3:8080;
}
server { listen 82;
proxy_connect_timeout 10s; proxy_timeout 30s; proxy_pass myweb;
}
}
nginx會(huì)話保持
nginx會(huì)話保持主要有以下幾種實(shí)現(xiàn)方式。
1、ip_hash ip_hash使用源地址哈希算法,將同一客戶(hù)端的請(qǐng)求總是發(fā)往同一個(gè)后端服務(wù)器,除非該服務(wù)器不可用。
ip_hash語(yǔ)法:
upstream backend { ip_hash;
server backend1.example.com; server backend2.example.com; server backend3.example.com down;
}
注意:
ip_hash簡(jiǎn)單易用,但有如下問(wèn)題:當(dāng)后端服務(wù)器宕機(jī)后,session會(huì)丟失;
來(lái)自同一局域網(wǎng)的客戶(hù)端會(huì)被轉(zhuǎn)發(fā)到同一個(gè)后端服務(wù)器,可能導(dǎo)致負(fù)載失衡;
2.sticky_cookie_insert
使用sticky_cookie_insert啟用會(huì)話親緣關(guān)系,這會(huì)導(dǎo)致來(lái)自同一客戶(hù)端的請(qǐng)求被傳遞到一組服務(wù)器的同一臺(tái)服務(wù)器。與ip_hash不同之處在于,它不是基于IP來(lái)判斷客戶(hù)端的,而是基于cookie來(lái)判斷。因此可以避
34/87
免上述ip_hash中來(lái)自同一局域網(wǎng)的客戶(hù)端和前段代理導(dǎo)致負(fù)載失衡的情況。(需要引入第三方模塊才能實(shí)現(xiàn) sticky)
下載地址:https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/08a395c66e42.zip
下載后進(jìn)行編譯安裝語(yǔ)法: upstream backend {
server backend1.example.com; server backend2.example.com;
sticky_cookie_insert srv_id expires=1h domain=3evip.cn path=/;
}
expires:設(shè)置瀏覽器中保持cookie的時(shí)間domain:定義cookie的域path:為cookie定義路徑
nginx動(dòng)靜分離
為了加快網(wǎng)站的解析速度,可以把動(dòng)態(tài)頁(yè)面和靜態(tài)頁(yè)面由不同的服務(wù)器來(lái)解析,加快解析速度。降低
原來(lái)單個(gè)服務(wù)器的壓力。 在動(dòng)靜分離的tomcat的時(shí)候比較明顯,因?yàn)閠omcat解析靜態(tài)很慢,其實(shí)這些原理的話都很好理解,簡(jiǎn)單來(lái)說(shuō),就是使用正則表達(dá)式匹配過(guò)濾,然后交個(gè)不同的服務(wù)器。
靜態(tài)分離部署
一:實(shí)驗(yàn)環(huán)境
準(zhǔn)備一個(gè)nginx代理 兩個(gè)http 分別處理動(dòng)態(tài)和靜態(tài)。
1.配置nginx反向代理upstream; upstream static {
server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=60s;
}
upstream php {
server 10.0.105.200:80 weight=1 max_fails=1 fail_timeout=60s;
}
server {
listen 80; server_name localhost
#動(dòng)態(tài)資源加載 location ~ .(php|jsp)$ {
proxy_pass http://phpserver; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
35/87
}
#靜態(tài)資源加載
location ~ .*.(html|gif|jpg|png|bmp|swf|css|js)$ { proxy_pass http://static;
proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
2.單獨(dú)的靜態(tài)配置 server {
listen 80;
server_name localhost;
location ~ .(html|jpg|png|js|css|gif|bmp|jpeg) { root /home/www/nginx;
}
}
3.動(dòng)態(tài)資源配置:
yum 安裝php7.1
[root@nginx-server ~]#rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm [root@nginx-server ~]#rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
[root@nginx-server ~]#yum install php71w-xsl php71w php71w-ldap php71w-cli php71w-common php71w-devel php71w-gd php71w-pdo php71w-mysql php71w-mbstring php71w-bcmath php71w-mcrypt -y [root@nginx-server ~]#yum install -y php71w-fpm
[root@nginx-server ~]#systemctl start php-fpm [root@nginx-server ~]#systemctl enable php-fpm
編輯nginx的配置文件:
server {
listen 80;
server_name localhost;
location ~ .php$ {
root /home/nginx/html; #指定網(wǎng)站目錄
fastcgi_pass 127.0.0.1:9000; #指定訪問(wèn)地址
fastcgi_index index.php; #指定默認(rèn)文件
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #站點(diǎn)根目錄,取決于root配
置項(xiàng)
include fastcgi_params; #包含nginx常量定義
}
}
nginx 防盜鏈
兩個(gè)網(wǎng)站 A 和 B, A網(wǎng)站引用了B網(wǎng)站上的圖片,這種行為就叫做盜鏈。 防盜鏈,就是要防止A引用B的圖片。
36/87
防盜鏈部署
1、nginx 防止網(wǎng)站資源被盜用模塊 ngx_http_referer_module
HTTP Referer是Header的一部分,當(dāng)瀏覽器向Web服務(wù)器發(fā)送請(qǐng)求的時(shí)候,一般會(huì)帶上Referer,告訴服務(wù)器我是從哪個(gè)頁(yè)面鏈接過(guò)來(lái)的,服務(wù)器借此可以獲得一些信息用于處理,例如防止未經(jīng)允許的網(wǎng)站盜鏈
圖片、文件等。因此HTTP Referer頭信息是可以通過(guò)程序來(lái)偽裝生成的,所以通過(guò)Referer信息防盜鏈并非100%可靠,但是,它能夠限制大部分的盜鏈情況.
[root@nginx-server ~]# vim /etc/nginx/nginx.conf
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
3.實(shí)戰(zhàn)演練
準(zhǔn)備兩臺(tái)機(jī)器,一張圖片配置nginx配置文件,并上傳圖片
[root@nginx-server html]# vim /etc/nginx/conf.d/nginx.conf server {
listen 80; server_name localhost;
location ~ .*.(gif|jpg|png|jpeg)$ { root /usr/share/nginx/html;
valid_referers none blocked *.qf.com 192.168.1.10; if ($invalid_referer) {
return 403;
}
}
}
?none : 允許沒(méi)有http_refer的請(qǐng)求訪問(wèn)資源;
?blocked : 允許不是http://開(kāi)頭的,不帶協(xié)議的請(qǐng)求訪問(wèn)資源---被防火墻過(guò)濾掉的;
?server_names : 只允許指定ip/域名來(lái)的請(qǐng)求訪問(wèn)資源(白名單);
重載nginx服務(wù)
[root@nginx-server ~]# nginx -s reload -c /etc/nginx/nginx.conf
qf.com ----192.168.1.11 制作localhost本地解析。配置nginx訪問(wèn)頁(yè)面創(chuàng)建頁(yè)面
[root@nginx-server nginx]# vim index.html <html>
<head>
<meta charset="utf-8"> <title>qf.com</title>
</head>
<body style="background-color:red;">
<img src="https://cache.yisu.com/upload/information/20200217/33/1966.jpg"/> </body>
</html>
測(cè)試不帶http_refer:
[root@nginx-server nginx]# curl -I "https://cache.yisu.com/upload/information/20200217/33/1966.jpg" HTTP/1.1 200 OK
Server: nginx/1.16.0
Date: Thu, 27 Jun 2019 16:21:13 GMT
Content-Type: image/png
37/87
Content-Length: 235283
Last-Modified: Thu, 27 Jun 2019 11:27:11 GMT
Connection: keep-alive
ETag: "5d14a80f-39713"
Accept-Ranges: bytes
測(cè)試帶非法http_refer:
[root@nginx-server nginx]# curl -e http://www.baidu.com -I "http:/192.168.1.10/test.jpg" HTTP/1.1 403 Forbidden
Server: nginx/1.16.0
Date: Thu, 27 Jun 2019 16:22:32 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
測(cè)試帶合法的http_refer:
[root@nginx-server nginx]# curl -e http://192.168.1.10 -I "https://cache.yisu.com/upload/information/20200217/33/1966.jpg" HTTP/1.1 200 OK
Server: nginx/1.16.0
Date: Thu, 27 Jun 2019 16:23:21 GMT
Content-Type: image/jpeg
Content-Length: 27961
Last-Modified: Thu, 27 Jun 2019 12:28:51 GMT
Connection: keep-alive
ETag: "5d14b683-6d39"
Accept-Ranges: bytes
如果用戶(hù)直接在瀏覽器輸入你的圖片地址,那么圖片顯示正常,因?yàn)樗蟦one這個(gè)規(guī)則。
nginx的rewrite
Rewirte
1、什么是Rewrite
Rewrite對(duì)稱(chēng)URL Rewrite,即URL重寫(xiě),就是把傳入Web的請(qǐng)求重定向到其他URL的過(guò)程。
? URL Rewrite最常見(jiàn)的應(yīng)用是URL偽靜態(tài)化,是將動(dòng)態(tài)頁(yè)面顯示為靜態(tài)頁(yè)面方式的一種技術(shù)。比如http:// www.123.com/news/index.php?id=123 使用URLRewrite 轉(zhuǎn)換后可以顯示為 https://cache.yisu.com/upload/information/20200217/33/1992.jpg)
$request_uri 當(dāng)前請(qǐng)求的文件路徑名(不帶網(wǎng)站的主目錄/images/a.jpg)
$query_string 與$args相同;
$scheme 用的協(xié)議,比如http或者是https
$server_protocol 請(qǐng)求的協(xié)議版本,"HTTP/1.0"或"HTTP/1.1";
$server_addr 服務(wù)器地址,如果沒(méi)有用listen指明服務(wù)器地址,使用這個(gè)變量將發(fā)起一次系統(tǒng)調(diào)用以
取得地址(造成資源浪費(fèi));
$server_name 請(qǐng)求到達(dá)的服務(wù)器名;
$document_uri 與$uri一樣,URI地址;
39/87
$server_port 請(qǐng)求到達(dá)的服務(wù)器端口號(hào);
Rewrite flag
rewrite 指令根據(jù)表達(dá)式來(lái)重定向URI,或者修改字符串??梢詰?yīng)用于server,location, if環(huán)境下每行rewrite指令最后跟一個(gè)flag標(biāo)記,支持的flag標(biāo)記有:
last 相當(dāng)于Apache里的[L]標(biāo)記,表示完成rewrite。默認(rèn)為last。
break 本條規(guī)則匹配完成后,終止匹配,不再匹配后面的規(guī)則
redirect 返回302臨時(shí)重定向,瀏覽器地址會(huì)顯示跳轉(zhuǎn)后的URL地址
permanent 返回301永久重定向,瀏覽器地址會(huì)顯示跳轉(zhuǎn)后URL地址
Rewrite匹配參考示例:
本地解析host文件
#http://www.testpm.com/a/1.html ==> http://www.testpm.com/b/2.html location /a {
root /html;
index 1.html index.htm; rewrite .* /b/2.html permanent;
}
location /b { root /html;
index 2.html index.htm;
}
例2:
root /var/www/html; index 1.html index.hml;
rewrite ^/2019/(.*)$ /2018/$1 permanent;
}
location /2018/a {
root /var/www/html;
index 1.html index.htl;
}
例3:
root /html;
if ($host ~* testpm.com ) {
rewrite .* http://jd.com permanent;
}
40/87
}
例4:
root /html;
if ( $host ~* testpm.com ){
rewrite .* http://jd.com$request_uri permanent;
}
}
例5: 在訪問(wèn)目錄后添加/ (如果目錄后已有/,則不加/)
#http://www.tianyun.com/a/b/c
#$1: /a/b
#$2: c
#http://$host$1$2/
location /a/b/c {
root /usr/share/nginx/html; index index.html index.hml; if (-d $request_filename) {
rewrite ^(.*)([^/])$ http://$host$1$2/ permanent;
}
}
例6:
root /usr/share/nginx/html;
rewrite ^/login/(.*).html$ http://$host/reg/login.html?user=$1;
}
location /reg {
root /usr/share/nginx/html; index login.html;
}
例7:
#http://www.tianyun.com/qf/11-22-33/1.html ==> http://www.tianyun.com/qf/11/22/33/1.html location /qf {
rewrite ^/qf/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /qf/$1/$2/$3$4 permanent;
}
location /qf/11/22/33 { root /html;
index 1.html;
}
41/87
set
set 指令是用于定義一個(gè)變量,并且賦值
應(yīng)用環(huán)境: server,location,if
應(yīng)用示例:例8:
#http://alice.testpm.com ==> http://www.testpm.com/alice #http://jack.testpm.com ==> http://www.testpm.com/jack
[root@nginx-server conf.d]# cd /usr/share/nginx/html/ [root@nginx-server html]# mkdir jack alice [root@nginx-server html]# echo "jack.." >> jack/index.html [root@nginx-server html]# echo "alice.." >> alice/index.html
a. DNS實(shí)現(xiàn)泛解析
10.0.105.202 alice.testpm.com
10.0.105.202 jack.testpm.com
編輯配置文件:
server {
listen 80;
server_name www.testpm.com;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
if ( $host ~* ^www.testpm.com$) { break;
}
if ( $host ~ "^(.).testpm.com$" ) { set $user $1;
rewrite .* http://www.testpm.com/$user permanent;
}
}
location /jack {
root /usr/share/nginx/html; index index.html index.hml;
}
location /alice {
root /usr/share/nginx/html; index index.html index.hml;
}
}
return
42/87
return 指令用于返回狀態(tài)碼給客戶(hù)端 server,location,if
應(yīng)用示例:
例9:如果訪問(wèn)的.sh結(jié)尾的文件則返回403操作拒絕錯(cuò)誤 server {
listen 80;
server_name www.testpm.cn;
#access_log /var/log/nginx/http_access.log main;
location / {
root /usr/share/nginx/html; index index.html index.htm;
}
location ~* .sh$ { return 403;
}
}
例10:80 ======> 443 :80轉(zhuǎn)443端口 server {
listen 80;
server_name www.testpm.cn;
access_log /var/log/nginx/http_access.log main; return 301 https://www.testpm.cn$request_uri;
}
server {
listen 443 ssl;
server_name www.testpm.cn;
access_log /var/log/nginx/https_access.log main;
#ssl on;
ssl_certificate /etc/nginx/cert/2447549_www.testpm.cn.pem; ssl_certificate_key /etc/nginx/cert/2447549_www.testpm.cn.key; ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/html; index index.html index.htm;
}
}
[root@nginx-server ~]# curl -I http://www.testpm.cn HTTP/1.1 301 Moved Permanently
Server: nginx/1.16.0
Date: Wed, 03 Jul 2019 13:52:30 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://www.testpm.cn/
43/87
last、break
[root@localhost test]# cat /etc/nginx/conf.d/last_break.conf server {
listen 80; server_name localhost;
access_log /var/log/nginx/last.access.log main;
location / {
root /usr/share/nginx/html; index index.html index.htm;
}
location /break/ {
root /usr/share/nginx/html; rewrite .* /test/break.html break;
}
location /last/ {
root /usr/share/nginx/html; rewrite .* /test/last.html last;
}
location /test/ {
root /usr/share/nginx/html; rewrite .* /test/test.html break;
}
}
[root@localhost conf.d]# cd /usr/share/nginx/html/ [root@localhost html]# mkdir test
[root@localhost html]# echo "last" > test/last.html [root@localhost html]# echo "break" > test/break.html [root@localhost html]# echo "test" > test/test.html
http://10.0.105.196/break/break.html
http://10.0.105.196/last/last.html
注意:
?last 標(biāo)記在本條 rewrite 規(guī)則執(zhí)行完后,會(huì)對(duì)其所在的 server { … } 標(biāo)簽重新發(fā)起請(qǐng)求;
?break 標(biāo)記則在本條規(guī)則匹配完成后,停止匹配,不再做后續(xù)的匹配;
?使用 alias 指令時(shí),必須使用 last;
?使用 proxy_pass 指令時(shí),則必須使用break。
44/87
https ( rewrite )
server {
listen 80;
server_name *.vip9999.top vip9999.top;
if ($host ~* "^www.vip9999.top$|^vip9999.top$" ) { return 301 https://www.vip9999.top$request_uri;
}
if ($host ~ "^(.).vip9999.top$" ) { set $user $1;
return 301 https://www.vip9999.top/$user;
}
}
server {
listen 443 ssl;
server_name www.vip9999.top;
location / {
root /usr/share/nginx/html;
} index index.php index.html;
#pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ .php$ {
root /usr/share/nginx/html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
ssl on;
ssl_certificate cert/214025315060640.pem; ssl_certificate_key cert/214025315060640.key; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on;
}
nginx的localtion
Nginx 的 HTTP 配置主要包括三個(gè)區(qū)塊,結(jié)構(gòu)如下:
http { # 這個(gè)是協(xié)議級(jí)別
include mime.types;
45/87
default_type application/octet-stream; keepalive_timeout 65;
gzip on; server { # 這個(gè)是服務(wù)器級(jí)別
listen 80; server_name localhost;
location / { # 這個(gè)是請(qǐng)求級(jí)別 root html;
index index.html index.htm;
}
}
}
1、location 區(qū)段
?location 是在 server 塊中配置,根據(jù)不同的 URI 使用不同的配置,來(lái)處理不同的請(qǐng)求。
?location 是有順序的,會(huì)被第一個(gè)匹配的location 處理。
基本語(yǔ)法如下: location [=|~|~*|^~|@] pattern{……}
2、location 前綴含義
=表示精確匹配,優(yōu)先級(jí)也是最高的
^~ 表示uri以某個(gè)常規(guī)字符串開(kāi)頭,理解為匹配url路徑即可 ~ 表示區(qū)分大小寫(xiě)的正則匹配 ~ 表示不區(qū)分大小寫(xiě)的正則匹配 !~ 表示區(qū)分大小寫(xiě)不匹配的正則 !~ 表示不區(qū)分大小寫(xiě)不匹配的正則 / 通用匹配,任何請(qǐng)求都會(huì)匹配到
@內(nèi)部服務(wù)跳轉(zhuǎn)
3、location 配置示例本地解析域名host
1)、沒(méi)有修飾符 表示:必須以指定模式開(kāi)始
server {
listen 80; server_name qf.com;
location /abc {
root /home/www/nginx;
index 2.html;
}
那么,如下是對(duì)的: http://qf.com/abc http://qf.com/abc?p1 http://qf.com/abc/
如下是錯(cuò)的 http://qf.com/abcde
2)、=表示:必須與指定的模式精確匹配 server {
listen 80;
server_name www.testpm.cn;
access_log /var/log/nginx/http_access.log main;
location / {
root /usr/share/nginx/html; index index.html index.htm;
}
46/87
location = /abc {
root /usr/share/nginx/html; index index.html index.htm;
}
}
那么,如下是對(duì)的: http://qf.com/abc http://qf.com/abc?p1 http://qf.com/abc/
http://qf.com/abcde
3)、~ 表示:指定的正則表達(dá)式要區(qū)分大小寫(xiě) server {
server_name qf.com; location ~ ^/abc$ {
……
}
}
那么,如下是對(duì)的: http://qf.com/abc http://qf.com/abc?p1=11&p2=22 http://qf.com/ABC http://qf.com/abc/ http://qf.com/abcde
4)、~ 表示:指定的正則表達(dá)式不區(qū)分大小寫(xiě) server {
server_name qf.com; location ~ ^/abc$ {
……
}
}
那么,如下是對(duì)的: http://qf.com/abc http://qf..com/ABC http://qf..com/abc?p1=11&p2=22
如下是錯(cuò)的: http://qf..com/abc/ http://qf..com/abcde
5)、^~ :類(lèi)似于無(wú)修飾符的行為,也是以指定模式開(kāi)始,不同的是,如果模式匹配,那么就停止搜索其他模式了6)、@ :定義命名 location 區(qū)段,這些區(qū)段客戶(hù)段不能訪問(wèn),只可以由內(nèi)部產(chǎn)生的請(qǐng)求來(lái)訪問(wèn),如try_files
或error_page等
查找順序和優(yōu)先級(jí)1:帶有“=“的精確匹配優(yōu)先2:沒(méi)有修飾符的精確匹配
3:正則表達(dá)式按照他們?cè)谂渲梦募卸x的順序
4:帶有“^~”修飾符的,開(kāi)頭匹配
5:帶有“~” 或“~*” 修飾符的,如果正則表達(dá)式與URI匹配
6:沒(méi)有修飾符的,如果指定字符串與URI開(kāi)頭匹配
= 大于 ^~ 大于 ~|~|!~|!~ 大于 /
多個(gè)location配置的情況下匹配順序?yàn)椋菏紫绕ヅ?=,其次匹配^~, 其次是按正則匹配,最后是交給 / 通用匹配。當(dāng)有匹配成功時(shí)候,停止匹配,按當(dāng)前匹配規(guī)則處理請(qǐng)求。
(1)=:表示完全匹配;
(2)^~:匹配URI的前綴,并且后面的正則表達(dá)式不再匹配,如果一個(gè)URI同時(shí)滿足兩個(gè)規(guī)則的話,匹配最長(zhǎng)的規(guī)則;
47/87
(3)~:匹配正則表達(dá)式,大小寫(xiě)敏感;
(4)~*:匹配正則表達(dá)式,大小寫(xiě)不敏感;優(yōu)先級(jí):(1)> (2) > (3) = (4)
localtion匹配段
location 區(qū)段匹配示例
location = / {
}
location / {
[ configuration B ]
}
location ^~ /images/ {
[ configuration C ]
}
location ~* .(gif|jpg|jpeg)$ {
}
各請(qǐng)求的處理如下例:
/ → configuration A /documents/document.html → configuration B /images/1.gif → configuration C /documents/1.jpg → configuration D
root 、alias 指令區(qū)別
root 、alias 指令區(qū)別
location /img/ {
alias /var/www/image/;
}
#若按照上述配置的話,則訪問(wèn)/img/目錄里面的文件時(shí),ningx會(huì)自動(dòng)去/var/www/image/目錄找文件 location /img/ {
root /var/www/image;
}
#若按照這種配置的話,則訪問(wèn)/img/目錄下的文件時(shí),nginx會(huì)去/var/www/image/img/目錄下找文件。
? alias 是一個(gè)目錄別名的定義,
48/87
?root 則是最上層目錄的定義。
?還有一個(gè)重要的區(qū)別是alias后面必須要用“/”結(jié)束,否則會(huì)找不到文件的,而root則可有可無(wú)
nginx 日志配置
nginx 日志介紹
nginx 有一個(gè)非常靈活的日志記錄模式,每個(gè)級(jí)別的配置可以有各自獨(dú)立的訪問(wèn)日志, 所需日志模塊
ngx_http_log_module 的支持,日志格式通過(guò) log_format 命令來(lái)定義,日志對(duì)于統(tǒng)計(jì)和排錯(cuò)是非常有利的,下面總結(jié)了 nginx 日志相關(guān)的配置 包括 access_log、log_format、open_log_file_cache、rewrite_log、error_log。
總結(jié):
Nginx中通過(guò)access_log和error_log指令配置訪問(wèn)日志和錯(cuò)誤日志,通過(guò)log_format我們可以自定義日志格式。如果日志文件路徑中使用了變量,我們可以通過(guò)open_log_file_cache 指令來(lái)設(shè)置緩存,提升性能。其他的根據(jù)自己的使用場(chǎng)景定義。詳細(xì)的日志配置信息可以參考Nginx官方文檔
access.log
#關(guān)閉訪問(wèn)日志 access_log off;
?path 指定日志的存放位置。
?format 指定日志的格式。默認(rèn)使用預(yù)定義的combined。
?buffer 用來(lái)指定日志寫(xiě)入時(shí)的緩存大小。默認(rèn)是64k。
?gzip 日志寫(xiě)入前先進(jìn)行壓縮。壓縮率可以指定,從1到9數(shù)值越大壓縮比越高,同時(shí)壓縮的速度也越慢。默認(rèn)是1。
?flush 設(shè)置緩存的有效時(shí)間。如果超過(guò)flush指定的時(shí)間,緩存中的內(nèi)容將被清空。
?if 條件判斷。如果指定的條件計(jì)算為0或空字符串,那么該請(qǐng)求不會(huì)寫(xiě)入日志。
作用域:
可以應(yīng)用access_log指令的作用域分別有http,server,location,limit_except。也就是說(shuō),在這幾個(gè)作用域外使用該指令,Nginx會(huì)報(bào)錯(cuò)。
access_log /var/logs/nginx-access.log
該例子指定日志的寫(xiě)入路徑為/var/logs/nginx-access.log,日志格式使用默認(rèn)的combined。 access_log /var/logs/nginx-access.log buffer=32k gzip flush=1m
49/87
該例子指定日志的寫(xiě)入路徑為/var/logs/nginx-access.log,日志格式使用默認(rèn)的combined,指定日志的緩存大小為 32k,日志寫(xiě)入前啟用 gzip 進(jìn)行壓縮,壓縮比使用默認(rèn)值 1,緩存數(shù)據(jù)有效時(shí)間為1分鐘。
3、log_format 指令
Nginx 預(yù)定義了名為 combined 日志格式,如果沒(méi)有明確指定日志格式默認(rèn)使用該格式:
log_format combined '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"';
如果不想使用Nginx預(yù)定義的格式,可以通過(guò)log_format指令來(lái)自定義。語(yǔ)法:
log_format name [escape=default|json] string ...;
?name 格式名稱(chēng)。在 access_log 指令中引用。
?escape 設(shè)置變量中的字符編碼方式是json還是default,默認(rèn)是default。
?string 要定義的日志格式內(nèi)容。該參數(shù)可以有多個(gè)。參數(shù)中可以使用Nginx變量。
自定義日志格式的使用: access_log /var/logs/nginx-access.log main
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
使用log_format指令定義了一個(gè)main的格式,并在access_log指令中引用了它。假如客戶(hù)端有發(fā)起請(qǐng)求:https://qf.com/,我們看一下我截取的一個(gè)請(qǐng)求的日志記錄:
10.0.105.207 - - [01/Jul/2019:10:44:36 +0800 ] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "-"
我們看到最終的日志記錄中$remote_user、$http_referer、$http_x_forwarded_for都對(duì)應(yīng)了一個(gè)-,這是因?yàn)檫@幾個(gè)變量為空。
error.log
錯(cuò)誤日志在Nginx中是通過(guò)error_log指令實(shí)現(xiàn)的。該指令記錄服務(wù)器和請(qǐng)求處理過(guò)程中的錯(cuò)誤信息。
語(yǔ)法
配置錯(cuò)誤日志文件的路徑和日志級(jí)別
error_log file [level]; Default:
error_log logs/error.log error;
file 參數(shù)指定日志的寫(xiě)入位置。
level 參數(shù)指定日志的級(jí)別。level可以是debug, info, notice, warn, error, crit, alert,emerg中的任意值???br/>以看到其取值范圍是按緊急程度從低到高排列的。只有日志的錯(cuò)誤級(jí)別等于或高于level指定的值才會(huì)寫(xiě)入錯(cuò)誤日志中。默認(rèn)值是error。
基本用法:
error_log /var/logs/nginx/nginx-error.log
配置段:main, http, mail, stream, server, location作用域。
例子中指定了錯(cuò)誤日志的路徑為:/var/logs/nginx/nginx-error.log,日志級(jí)別使用默認(rèn)的 error。
50/87
open_log_file_cache
open_log_file_cache 指令
每一條日志記錄的寫(xiě)入都是先打開(kāi)文件再寫(xiě)入記錄,然后關(guān)閉日志文件。如果你的日志文件路徑中使用了變量,如 access_log /var/logs/$host/nginx-access.log,為提高性能,可以使用open_log_file_cache指令設(shè)置日志文件描述符的緩存。
語(yǔ)法:
open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
默認(rèn)值:
open_log_file_cache off;
?max 設(shè)置緩存中最多容納的文件描述符數(shù)量,如果被占滿,采用LRU算法將描述符關(guān)閉。
?inactive 設(shè)置緩存存活時(shí)間,默認(rèn)是10s。
?min_uses 在inactive時(shí)間段內(nèi),日志文件最少使用幾次,該日志文件描述符記入緩存,默認(rèn)是1次。
?valid:設(shè)置多久對(duì)日志文件名進(jìn)行檢查,看是否發(fā)生變化,默認(rèn)是60s。
?off:不使用緩存。默認(rèn)為off。
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2; 配置段:http、server、location作用域中。
例子中,設(shè)置緩存最多緩存1000個(gè)日志文件描述符,20s內(nèi)如果緩存中的日志文件描述符至少被被訪問(wèn)2次,才不會(huì)被緩存關(guān)閉。每隔1分鐘檢查緩存中的文件描述符的文件名是否還存在。
rewrite.log
rewrite_log 指令
由ngx_http_rewrite_module模塊提供的。用來(lái)記錄重寫(xiě)日志的。對(duì)于調(diào)試重寫(xiě)規(guī)則建議開(kāi)啟,啟用時(shí)將在error log中記錄notice級(jí)別的重寫(xiě)日志。
基本語(yǔ)法: rewrite_log on | off;
默認(rèn)值: rewrite_log off;
配置段: http, server, location, if作用域。
nginx的日志輪轉(zhuǎn)
[root@192 ~]# rpm -ql nginx |grep log /etc/logrotate.d/nginx
51/87
/var/log/nginx
[root@192 ~]# vim /etc/logrotate.d/nginx
/var/log/nginx/*.log { #指定需要輪轉(zhuǎn)處理的日志文件
daily #日志文件輪轉(zhuǎn)周期,可用值為: daily/weekly/yearly
missingok # 忽略錯(cuò)誤信息
rotate 7 # 輪轉(zhuǎn)次數(shù),即最多存儲(chǔ)7個(gè)歸檔日志,會(huì)刪除最久的歸檔日志
minsize 5M #限制條件,大于5M的日志文件才進(jìn)行分割,否則不操作
dateext # 以當(dāng)前日期作為命名格式
compress # 輪循結(jié)束后,已歸檔日志使用gzip進(jìn)行壓縮
delaycompress # 與compress共用,最近的一次歸檔不要壓縮
notifempty # 日志文件為空,輪循不會(huì)繼續(xù)執(zhí)行
create 640 nginx nginx #新日志文件的權(quán)限
sharedscripts #有多個(gè)日志需要輪詢(xún)時(shí),只執(zhí)行一次腳本
postrotate # 將日志文件轉(zhuǎn)儲(chǔ)后執(zhí)行的命令。以endscript結(jié)尾,命令需要單獨(dú)成行
if [ -f /var/run/nginx.pid ]; then #判斷nginx的PID。# 默認(rèn)logrotate會(huì)以root身份運(yùn)行 kill -USR1 cat /var/run/nginx.pid
fi endscript
}
執(zhí)行命令:
[root@192 nginx]# /usr/sbin/logrotate -f /etc/logrotate.conf
創(chuàng)建計(jì)劃任務(wù):
[root@192 nginx]# crontab -e
59 23 * /usr/sbin/logrotate -f /etc/logrotate.conf
企業(yè)實(shí)戰(zhàn)(面試)
nginx access log 分析
nginx 的 access log 中可以記錄很多有價(jià)值的信息,通過(guò)分析 access log,可以收集到很多指標(biāo)1.制作nginx的日志切割,每天凌晨切割并壓縮。
PV:PV(訪問(wèn)量): 即Page View, 即頁(yè)面瀏覽量或點(diǎn)擊量,用戶(hù)每次刷新即被計(jì)算一次。
UV:UV(獨(dú)立訪客):即Unique Visitor,訪問(wèn)您網(wǎng)站的一臺(tái)電腦客戶(hù)端為一個(gè)訪客。00:00-24:00內(nèi)相同的客戶(hù)端只被計(jì)算一次。
面試:
1.根據(jù)訪問(wèn)IP統(tǒng)計(jì)UV awk '{print $1}' access.log|sort | uniq -c |wc -l 2.統(tǒng)計(jì)訪問(wèn)URL統(tǒng)計(jì)PV
awk '{print $7}' access.log|wc -l 3.查詢(xún)?cè)L問(wèn)最頻繁的URL
awk '{print $7}' access.log|sort | uniq -c |sort -n -k 1 -r|more 4.查詢(xún)?cè)L問(wèn)最頻繁的IP awk '{print $1}' access.log|sort | uniq -c |sort -n -k 1 -r|more 5.查詢(xún)?cè)L問(wèn)最頻繁的前10的IP
awk '{print $1}' access.log|sort | uniq -c |sort -n -k 1 -r|head -n 10
nginx 的平滑升級(jí)(了解)
1、為什么要對(duì) nginx 平滑升級(jí)
隨著 nginx 越來(lái)越流行,并且 nginx 的優(yōu)勢(shì)也越來(lái)越明顯,nginx 的版本迭代也來(lái)時(shí)加速模式,1.9.0版本的nginx更新了許多新功能,例如 stream 四層代理功能,伴隨著 nginx 的廣泛應(yīng)用,版本升級(jí)必然越來(lái)越快,線上業(yè)務(wù)不能停,此時(shí) nginx 的升級(jí)就是運(yùn)維的工作了。
52/87
nginx 方便地幫助我們實(shí)現(xiàn)了平滑升級(jí)。其原理簡(jiǎn)單概括,就是:(1)在不停掉老進(jìn)程的情況下,啟動(dòng)新進(jìn)程。
(2)老進(jìn)程負(fù)責(zé)處理仍然沒(méi)有處理完的請(qǐng)求,但不再接受處理請(qǐng)求。(3)新進(jìn)程接受新請(qǐng)求。
(4)老進(jìn)程處理完所有請(qǐng)求,關(guān)閉所有連接后,停止。 這樣就很方便地實(shí)現(xiàn)了平滑升級(jí)。一般有兩種情況下需要升級(jí) nginx,一種是確實(shí)要升級(jí) nginx 的版本,另一種是要為 nginx 添加新的模塊。
2、nginx 平滑升級(jí)原理多進(jìn)程模式下的請(qǐng)求分配方式
nginx 默認(rèn)工作在多進(jìn)程模式下,即主進(jìn)程(master process)啟動(dòng)后完成配置加載和端口綁定等動(dòng)作,fork出指定數(shù)量的工作進(jìn)程(worker process),這些子進(jìn)程會(huì)持有監(jiān)聽(tīng)端口的文件描述符(fd),并通
過(guò)在該描述符上添加監(jiān)聽(tīng)事件來(lái)接受連接(accept)。信號(hào)的接收和處理
nginx 主進(jìn)程在啟動(dòng)完成后會(huì)進(jìn)入等待狀態(tài),負(fù)責(zé)響應(yīng)各類(lèi)系統(tǒng)消息,如SIGCHLD、SIGHUP、SIGUSR2等。
Nginx信號(hào)簡(jiǎn)介:主進(jìn)程支持的信號(hào)
?TERM, INT: 立刻退出
?QUIT: 等待工作進(jìn)程結(jié)束后再退出
?KILL: 強(qiáng)制終止進(jìn)程
?HUP: 重新加載配置文件,使用新的配置啟動(dòng)工作進(jìn)程,并逐步關(guān)閉舊進(jìn)程。
?USR1: 重新打開(kāi)日志文件
?USR2: 啟動(dòng)新的主進(jìn)程,實(shí)現(xiàn)熱升級(jí)
?WINCH: 逐步關(guān)閉工作進(jìn)程
工作進(jìn)程支持的信號(hào)
?TERM, INT: 立刻退出
?QUIT: 等待請(qǐng)求處理結(jié)束后再退出
?USR1: 重新打開(kāi)日志文件
nginx 平滑升級(jí)實(shí)戰(zhàn)1
1、查看現(xiàn)有的 nginx 編譯參數(shù)
[root@nginx-server ~]# cd /usr/local/nginx/sbin/nginx -V
2、按照原來(lái)的編譯參數(shù)安裝 nginx 的方法進(jìn)行安裝,只需要到 make,千萬(wàn)不要 make install 。如果make install 會(huì)將原來(lái)的配置文件覆蓋
53/87
[root@nginx-server ~]# cd /usr/local/nginx-1.16.0/
[root@nginx-server nginx-1.16.0]# ./configure --prefix=/usr/local/nginx --group=nginx --user=nginx --sbin-path=/ usr/local/nginx/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/tmp/nginx/client_body --http-proxy-temp-path=/ tmp/nginx/proxy --http-fastcgi-temp-path=/tmp/nginx/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/ nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre --with-http_realip_module --with-stream --with-http_image_filter_module
[root@nginx-server nginx-1.16.0]# make
3、備份原 nginx 二進(jìn)制文件備份二進(jìn)制文件和 nginx 的配置文件(期間nginx不會(huì)停止服務(wù))
[root@nginx-server nginx-1.16.0]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_$(date +%F)
4、復(fù)制新的nginx二進(jìn)制文件,進(jìn)入新的nginx源碼包
[root@nginx-server nginx-1.16.0]# cp /usr/local/nginx-1.16.0/objs/nginx /usr/local/nginx/sbin/
5、測(cè)試新版本的nginx是否正常
[root@nginx-server nginx-1.16.0]# /usr/local/nginx/sbin/nginx -t
6、給nginx發(fā)送平滑遷移信號(hào)(若不清楚pid路徑,請(qǐng)查看nginx配置文件)
[root@nginx-server ~]# kill -USR2 cat /var/run/nginx.pid
(老版本進(jìn)稱(chēng)號(hào))
7、查看nginx pid,會(huì)出現(xiàn)一個(gè)nginx.pid.oldbin [root@nginx-server ~]# ll /var/run/nginx.pid* -rw-r--r-- 1 root root 5 Jul 1 11:29 /var/run/nginx.pid
-rw-r--r-- 1 root root 5 Jul 1 09:54 /var/run/nginx.pid.oldbin
8、從容關(guān)閉舊的Nginx進(jìn)程
[root@nginx-server ~]# kill -WINCH cat /var/run/nginx.pid.oldbin
9、此時(shí)不重載配置啟動(dòng)舊的工作進(jìn)程
[root@nginx-server ~]# kill -HUP cat /var/run/nginx.pid.oldbin
10、結(jié)束工作進(jìn)程,完成此次升級(jí)
[root@nginx-server ~]# kill -QUIT cat /var/run/nginx.pid.oldbin
11、驗(yàn)證Nginx是否升級(jí)成功
[root@nginx-server ~]# /usr/local/nginx/sbin/nginx -V
nginx 平滑升級(jí)實(shí)戰(zhàn)2
1、安裝配置 nginx
[root@localhost ~]# yum install -y gcc gcc-c++ pcre-devel openssl-devel zlib-devel [root@localhost ~]# tar xzf nginx-1.6.3.tar.gz -C /usr/local/
[root@localhost ~]# cd /usr/local/nginx-1.6.3
54/87
[root@localhost nginx-1.6.3]# ./configure -- prefix=/usr/local/nginx --user=nginx --group=nginx --with-
http_stub_status_module
[root@localhost nginx-1.6.3]# make && make install
[root@localhost nginx-1.6.3]# useradd -M -s /sbin/nologin nginx
[root@localhost nginx-1.6.3]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost nginx-1.6.3]# /usr/local/nginx/sbin/nginx
[root@localhost nginx-1.6.3]# netstat -lntp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 13989/nginx: master
2、查看版本和模塊
[root@localhost nginx-1.6.3]# /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.6.3
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module [root@localhost nginx-1.6.3]# echo "nginx1.6" > /usr/local/nginx/html/index.html
[root@localhost nginx-1.6.3]# yum install -y elinks
3、訪問(wèn)驗(yàn)證
[root@localhost nginx-1.6.3]# elinks 10.0.105.189
4、升級(jí)nginx:將 nginx 版本進(jìn)行升級(jí) 并在不影響業(yè)務(wù)的情況下添加 SSL 和 pcre 模塊
[root@localhost ~]# tar xzf nginx-1.12.2.tar.gz -C /usr/local/ [root@localhost ~]# cd /usr/local/nginx-1.12.2/
[root@localhost nginx-1.12.2]# ./configure --prefix=/usr/local/nginx --user=nginx --group=ngiinx --with-http_stub_status_module --with-http_ssl_module --with-pcre
[root@localhost nginx-1.12.2]# make [root@localhost nginx-1.12.2]# cd
[root@localhost ~]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_lod [root@localhost ~]# cp /usr/local/nginx-1.12.2/objs/nginx /usr/local/nginx/sbin/ [root@localhost ~]# mv /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.bak [root@localhost ~]# kill -USR2 cat /usr/local/nginx/logs/nginx.pid
[root@localhost ~]# ls /usr/local/nginx/logs/
access.log error.log nginx.pid
[root@localhost ~]# ps aux | grep nginx
root 13989 0.0 0.0 24860 952 ? Ss 13:55 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 13990 0.0 0.1 25284 1720 ? S 13:55 0:00 nginx: worker process
root 16525 0.0 0.0 112708 976 pts/2 S+ 14:09 0:00 grep --color=auto nginx
nginx錯(cuò)誤界面配置
nginx錯(cuò)誤頁(yè)面包括404 403 500 502 503 504等頁(yè)面,只需要在server中增加以下配置即可:
#error_page 404 403 500 502 503 504 /404.html; location = /404.html {
root /usr/local/nginx/html;
}
注意:
/usr/local/nginx/html/ 路徑下必須有404.html這個(gè)文件?。。?/p>
404.html上如果引用其他文件的png或css就會(huì)有問(wèn)題,顯示不出來(lái),因?yàn)槠渌募脑L問(wèn)也要做配置; 為了簡(jiǎn)單,可以將css嵌入文件中,圖片用base編碼嵌入;如下:
55/87
[root@localhost html]# vim 404.html <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" /> <title>404</title>
<style>
.layout-table{display:table;height:100%;width:100%;vertical-align: middle;margin-top:150px}
.layout-table-cell{display: table-cell;vertical-align: middle;text-align:center}
.layout-tip{font-size:28px;color:#373737;margin: 0 auto;margin-top:16px;border-bottom: 1px solid #eee;padding-bottom: 20px;width: 360px;}
#tips{font-size:18px;color:#666666;margin-top:16px;} </style>
</head>
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
<div class="layui-body"> <div class="layout-table">
<div class="layout-table-cell"> <img src="data:image/
png;base64,iVBORw0KGgoAAAANSUhEUgAAAV4AAACMCAYAAAA0qsGKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFn
eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh7cmVTek5UY3prYzlkIj8
+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwI
+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4Qz6opAAAU5klEQVR42uxd3XXjthKe
+Oy7dCsQU4GUAnLEfc7DKhWI20CsrcDcCiynAcsVhH7I81InBaxUQagKIlXga9wML2Ga4B9ACiC/7xyeXeuHpDD4PswMBuA
f0PLAH1j+nosXg//9fCkY1bju6fXI3k9DtK/MZoUsAl//fJ7ufACQE9CK0R2xf/ONM4142OZe33/
ekR8JGhywGqPFwA6xIqPdQ/XWvJx/3ocX48dH+eK73kQaqBL2JzjFV7QS0cHwtD
+vdsNi9kfPYluHnMW4ITF1yv5bMCfC2A68HdswtslILz9IWQRu9dMJ5jChIX/7xIB3vJ7j3zvPswI/kJ49XFQvC7ItkC/
NpZSEKJ1x2JnI9bcF8Lc62d+7Sf+/zcmuwezgr8QXrOGWzARv7NoAO3TChGnFGYO3O+EB4dDAWnT1x7o31yx
+HsDE4O/EN7mSEuP8ghqjKhAOXxu208O3vucSRsWvCfE9lf+/z0PLFOYG/xtC5urGroK6
+IS0RA4Ema02yBkz9EELpTV4iYV9vD48Nnr0U1r3FFW5iZXP0T8+o4HlpjJjkEa/
IXwtjScxx5PmWEBNXakX6lwoazcS0fM0kUYgWTTpkjTCqvcvRz43DGfO+a/
Ib7gL1INFYgKXlvlRASohymLjo7oitDxM2UlZ7oiJr6/ZQEWk2NPLc8zk4RVxpnP/cTedUwoOwN/
ByS8fgfnPFJx8XwgiQC8l/qiG2t4lQJf2VvpiiwHtq0Q4H2L7wth/aYQ1kAS30eIL/
gLj7c8JC4LUyLwpRfRPbIYhjWus2IPVlyvrKg
+YfuFVFydIITgC6c0muKxQnzTz6AUEfx1XniXCFOsJkBb0d1TdV7U52v8Q/+Wpd3W6A8iNSAmvcTk2HcW4pDeVh9s
+dwmxXfDAwnx4ADxBX8rYevkmtdRmJIgzWBEdNuWiz1VhOQLFsdlge0its9Z4Rmnk2pLSYjvWBi3kned1uZGLQaPR76
+LABnejvhFvH5zyPuI+AvhLd0NFwgzdAIopOvNYhTtvhAvHcv/
X2hbOlu0tAbWvG9igEiXSARUFalkPDfMTUvP9sVeOxn6XwzykrPILzgr1Ophi46bVQyWiLNUI0Fe3xtcGGbnktIJYtuOukWUrua
+07GdpJUN
+AcVBOveSqvPXQwb466jwmh5xnxUEXiHNUAtTTY9iVSG6a8kO6aSbiVA94Wt/5HOn6YKdJJZfWopvpBCHB/7/3Yi9XvDXUe
+6nZBKJ8GeJPENCvpCExR5tWfKctmzkaYcwF8Hhdd0eLZThM4rifQJ9FWZYtDp1KqUgfCI7iViBdRfFUBAb2tvfbb/g0b/
mhZ42On5bmlcJWbgL4RXORoKo03g7VZio5FiuJS07TYnzn3n52TxjTQHmBkVV2uElNULj6mPgb
+OCq9J72BP1VvIIb9bDI/0dhvblojeUrLPtYgTsLc04XtIqP2+Dnf0fkJJTjksaTx7PIO/8HiVSwxT4j/RuAvdq9IEpj2V/
HmDK//GFWWLM3S9p53itdPIvF7w10HhNbGfaoqTwnCbCsMC/3ZunR3HVIQIpNTFE10/
N5dQtopN4EBZRUJTLBWiE0opiWDg/
Qb8dVR4TY6WZaFuatgYGtuJtxtVtL2Ja3SFneF2k73ecOD9Bvx1VHhN5cHKSlAm8HY79XYvCuGVQ8Q92TsTrZMzrOP1DjnX
+nWUjKpWMtOkWhEOG7sMcoxrntZk0iUa6QeXVRpRVOAz5YZngr4PCa9ITKDLKgton5XXrWV3BlPTzkHEN+9o
+E23a6z1Lg82ShvmYePB35MKrMoqOxxWRuUkD28mj+ztVaYZ0Uu2Z7J+JjjW/
H1SIyWagfQf8dVB4fUPnCRUjnrw8NW54vmWNTjeE1Um6gqB6NItL3q4J4V3T+9VscgojoOEB/
HVQeBfUfoVUfrRMKgSlScghDFJnEYE4/3dyuyZYeKW6a
+zjGqSMHWmPveb3i8Q19dQmNKxJNvDXUeE15QGoRsvUcJcGYcqiRUjjcjrChBAcKoT3RO6sq
+8i3RB1EJqDvw7y92ZApFeNlm3WdS
+o3dMJxk6eWNGWE8e83bJBpC7m9H4STU43DEl4wV8HhddUmBJWvH6pabgxiq6JNAMpiLNwMM1gQnhVghQNLN0A/
joqvCY8rQdSb6Yhb5Z8HoLROoBv4Bz7kjY1KWZ9Iemobw8t3QD
+Oiq8up3vUmO0LBtRZSOPUXRNCe9hYMJbNpg0STcUPZvtYrDdwV8H
+Xtt4TURppStcqm7IYsw6uNIRdeU53WuEN6jg+1y7qhtY/53Rm6XIYK/
jgqvbt1oWd6nzmiZPsTxjsYLUztKxYr2nRgM3fuGCQ/
56/87
dr2grl71e8LclPjjuaW00Rst0O8AZjRumPK7zwNIMpgYLv0LQXfZ4wV8HPd5A09NS7ddZZ7QUr32H6BolfpGweoZFzEXhndH7
J3VNaNlo6UF038HEVn4HCG/jwc3ldAP466jwBprf35QYzaZHy7hAoL7OP2Zb+BWi7lq6AfwdofA+KDysac6gIXS1N
+Gtmji7ONxGewPnKPJo4x4HQPAXwvu/3FDbpHhVsfUE3q62J9YGVTW8h6G384TeL6Q4Oyq84K+jwrvR/
K6qbOlWMu6GAFsEByj2euXBaOnQ7wB/HRReT6OTiVngneK9be7/Z/C8V4+3yjtx2R4Hg30/j1Mu1LYd4K
+jwqszkgUloc9S6shjeDaabUgqhMblVIMpEfAq2s2Fygbw10Hh2XmQYllCXjZUCG9XWwxcOPdQ2tqlvgr
+Oiq8wmhtcn5VCfk00b8nux8bbiOwcu+6wiuLkW/5/YO/
jgrvRsPgVQl53TAIALpONbgO8NdB4Q1aelfiUeCqp9LuaoQyQD+INd
+3Gab6VdGkVJILu232dsFfR4W3TYhStsJlXiOUAdToOrSdookrkeQ8QJuFF/x1THh9aleCEpJ6O7i7XIiCcNA
+LNAEgxmgwV8HhbfNaCYS7dsaIQom1ACX4Dl4z+Cvg8LbZrS8lIQ2+RAlAJcBh5XXdk8P/HVUeMOW36kTomwJ
+zEAbsP2rSHBXweFt81oWTdEORIm1IBhwbZ9LcBfR4W3acOWhR5bersBMlIMAGCXtwv
+WiC8bUbLQBF6iHPJhdZfCTW7AGCbtwv+WiC8TUdLsf9mUaH1NPf6HikGALDO2wV/
LRDepqOl2JFIVWi9oyz3hSoGALDP2wV/
LRHeXcPPi23hispqhDE/5f5OYDIA6BTgr4PCK0a0Jmu6VfkeUXpynwtldjAXAHQK8NdB4c3vrVkFVb4nnxc6EnYe6wIxmsAqn
ah7fDlgN8BfR4V31+CzXxTGWOWMj7yQO+HtkLeANLmU91wgYDYA/HVQeFdUv/
xEGGOr6NyykZAXGkd46wJMDio2en/gr4PC2yQhrzLGlN7X
+6lKVACz6KuNsSm6PbYAfwcgvCHVKz8pS7ILo81z4Rc8sX5gygPzegzXYQtzAH8dFF7RwLc1PxsoOpYwvFxk/
ZmQjHfRy/Is8eC6gGfoPHsFh74F8NdB4U3DizoQyfhIYUw5Gf9ASMYPycsaCgG9nq7T50AF/joqvHVDlLJk/Db3OSTj
+4epkHBRg+ho6/J26XOgAn8dFN66IcqRijfFEJ0tpiwZr/oc4I7wVgmryzneRYdtfY12AX8dFN6pIuwoMppf02g
+zHBV7DsMx48DaB9TT4Y4aL5vaoAEfx0U3l2Njlh4BvRE6hUwQH8wQXhV2HquEGbbYTJFUtTPlxXvmwb466Dw5rd5KwtlD
zVha2FhlNjKBryWg+oexkDMJ76Mh7dM3jPVWIetcCBv46KLx180IqCKM9wmhWC+/FwHn8Hr1H1zzeQ8VAFXc8eIC/
luFDjc9EDUJFkbN6KXlf5Je+D6DdXhq8J7ydhDvrgdvTthAtrhmGNvV4xXnvHPZ4uxRe+dxJh78B/
LWQv1Ue746aP20UeIsZt+Etew7/sCAFlglvF6kG1z3eaYft24fwgr+W8vemIsRYo907wZKNmJAd5TiRod9UJjgLR+3Uh/
B2kWoAfy3m702Jd/KI9u1lNP0mjZ4eXaf0KiEze/MWieuppkc81DTDXhEdyLWwXdw7+Gsxf286DrGAenikrHZSeJ
+HK3jCJrxeXyHqAvORCm9c0U5dTFSBv5bz9wZtZg22Eik9Hkm3PV5/15FYxRXCPHThjSqEN0bXHx9/
Ibz2QISeGx41hfFE6c4t9bfj08FAusFXnNe0mPUBE4PEReHRQnhHzt+bkvDohwEeHw01ctk1/
sPXEYfYn7TJXggrSaxScq5J/URX29INswJxdVF4p4ZSI0Xt6VFW3nWibioawF/L
+QuP1zzO3PFjHu38Bsab5wTrs5QG6CNvZyK1kfcUE8oWaLiSajB1n0gzgL+F/IXw2gfZK9yx0UUYE/
Rw7YT0dysLFB5Y6hF7IxHek0J4VxBe8BfC2z1CalYPOlV4oX2lG3S93nmBuMYK4bEVJu5Rlbb5VOMzwMD5C
+HtHk091UQhWn2tQIpIf5JtVSJCtqcbFmRmN7VtRbscCbt7jZa/dZYMvwzo+HYFwzUh8aXAcNcgZ6j5/
U1BZzxJHt90QEQrwp6KJ81WOW51DfDXUv7e1OiETxj0KhFLnUOXKDZgp+n1zgo828iRdIOJewsVIei65zQD
+Gspf29qGg/lKHreT93RMlSEvtdAaID0qk5p64MRfQNphiMVT5qtanjEXYkv
+GsZf5Hj7R4bqt7vNt3n9FxiuH3P963r9QrvzpP+PlC2L8Gc7KzpNZFmCGukX3agxbj5C+HtHgdu/KcCA1749QWp1
+wHPYampoUoL0Jbi71ej/R389qTunZ3Ltkcwjty/kJ4+0HCBpjmQqcpv64KO0V4urwiWUXI/
GzQ642kzpt/79oIOzxHAG8X/
IXwuoGFZKwtXa/0qE6oVZWySHHOeb2hJW1twtt9puLcbv7cW3Rt8BfC279Xtavh7flM4gmHMtcUqETz
+kt6O7EkOuFJ8np9C+yiK4YXUqdO5LZ7ov4m1QCL+fsBbdl76C4M9zdl+cBDzjsKKCu2fiA7cqFbKWxq6/V6POqf
+Tf9IZ37mhNtgiSfDBAyqeHthqAA+AvhvY7hPBaagMXsvsB7emZBii269xWLy6TFdyfcSVPvNmJPQIjSnH/
rNQaYKennXPclHvMW3i74C+G1Bweyt5ZVhTN3tLarh6YscgH/veEOLIT3lttk1/NvEtfTqdu9kHrBRd6ThrcL/
v4fyPECTUf8LxrfX0vCm24YfbpSymFjIMWwIvWkp
+ztPsDbBSC8gA62pLcM9TEnviv2HCcs7H2Ib1AQIjbFl5JQMqS3dbvwdgEIL2BEuHTqex
+ltEJaoH6UxHfV8b3rPoH3idR53UUuDN0QdiEDILyAQQHTeTT5mrLJioSynf6F
+P7RkZcYGhLdoOT9HWUTkHvCggkAwgsYRJqj1RHfJWUTFen5vvJ7d2TuMfcei/
yd5nmeK0R3m0sxrNBNAAivufxhWcH9mMiWiqVO2kF4h/
eULcsUXumP7C0KEfvGotlGgKd8vr9JfyP5pwrbivducxEBUgzg7+iFd0P6Eyop8o9tjnKh6mJE7ZpOkOnu
+zrjNEC6wEII5k+UbULyrUHYni7XTAx4uXXSC4vcvT0QHusD/pbgh6eX93v//vznb0MzmmjMdQfnlQkpX
+PCxktGRo6A9HOoeewpywWTQnyn3N4L9ownBq//pcJDmnJKZCbdr08A
+JvDX7/8PhrhnTJp5x1e40jZXpyxFNLKr48tHIzIzHPLrokTkzJu0L/GanPwt6Hw3gxcAA4dG434/
DF3khW93ex7jOFmWh724PBveObfANEFfzvBUIU39VT68rpk4wWUbaO4pHGUE/n0Ni+W5mk/Uv9PztD1cj9S
+Yq0ItG91PgOAP4OWnhD+jfPOOn5unPKdirypdfX5N6+DE2RbggS5F6PuS0
+k/4j47sWXHGPHlVvTLQo8HTF9xLoJfg7RuFNd5q6u+I9TCTifpZevyczz/
OyOSyMmDBFE1E7FqfPlnnAsuDW8Wx8pBfAXwjv
+9BvbcG9pMYTZJTznI807DIz0THF4od0pzFPIcBCqH7itrlc4T7T52R9bCC4qSf2TfLEniG64O+YhTct+5hbdE/
pstcDva1vjQcuvkKcfmVBK9s6L31vKonwscP7OvI1fqUsjxfX/
G6afpA9MXEu5HTB39YYSx2vDaP5mMJTj1MPc04tbEj9FNaicH5B2YbT0wakPHK7HpjMBz7atnXI9z6RvOWAsDgC/
G3Rp8ZUx2uT8RKJwEcax+q2LWXLaJ/InZ26Vnzv8qx6uk8DvFzwtxV/x1LHaxPSPQ3SnKYYPXcj
+N1pSZmYxFpT9uDMqcWCG3OYOZO83F+RWgB/TfIXwtsfDvR2ZnRN43jUd8xpg6/
sMYhc6T9kz54WUx4gEhbcpSS4XylLmwDgrzH+Qnj7hSCw/OicWxp2mZkM4en
+SNlkhei43ymbaPN6FtuA7SEGgfuch6sKbggvF+iCv0PK8YoGeHTUoB/JricKd41U1PLlQ0fu3LHh9phyqJgeRZN1J/
ZgdhBb8LcL/g55cs1V411YEA4jI5vHNguoeHnokbLqhITqrQ7z
+JB3LJuUtHvEYhsTAP52yF9UNQA2Qgjkio8uazrTbSajEQ50wBUhC
+8HNAdgCdKa25D/9ql9Pe9FEtWY3tb0AsDVUejxAgAAAN0BVQ0AAAAQXgAAAAgvAAAAAOEFAABwF/8VYAAXRwSpGfHzm
57/87
class="layout-img"> <p class="layout-tip">哎呀,找不到該頁(yè)面啦!</p>
<p id="tips">請(qǐng)檢查您的網(wǎng)絡(luò)連接是否正常或者輸入的網(wǎng)址是否正確</p> </div>
</div>
</div>
</div>
</body>
</html>
nginx流量控制
流量限制 (rate-limiting),是Nginx中一個(gè)非常實(shí)用,卻經(jīng)常被錯(cuò)誤理解和錯(cuò)誤配置的功能。我們可以用來(lái)限制用戶(hù)在給定時(shí)間內(nèi)HTTP請(qǐng)求的數(shù)量。請(qǐng)求,可以是一個(gè)簡(jiǎn)單網(wǎng)站首頁(yè)的GET請(qǐng)求,也可以是登錄表單的 POST 請(qǐng)求。流量限制可以用作安全目的,比如可以減慢暴力密碼破解的速率。通過(guò)將傳入請(qǐng)求的速
率限制為真實(shí)用戶(hù)的典型值,并標(biāo)識(shí)目標(biāo)URL地址(通過(guò)日志),還可以用來(lái)抵御 DDOS ***。更常見(jiàn)的情況,該功能被用來(lái)保護(hù)上游應(yīng)用服務(wù)器不被同時(shí)太多用戶(hù)請(qǐng)求所壓垮。
1、Nginx如何限流
Nginx的”流量限制”使用漏桶算法(leaky bucket algorithm),該算法在通訊和分組交換計(jì)算機(jī)網(wǎng)絡(luò)中廣泛使用,用以處理帶寬有限時(shí)的突發(fā)情況。就好比,一個(gè)桶口在倒水,桶底在漏水的水桶。如果桶口倒水的速率大于桶底的漏水速率,桶里面的水將會(huì)溢出;同樣,在請(qǐng)求處理方面,水代表來(lái)自客戶(hù)端的請(qǐng)求,水
桶代表根據(jù)”先進(jìn)先出調(diào)度算法”(FIFO)等待被處理的請(qǐng)求隊(duì)列,桶底漏出的水代表離開(kāi)緩沖區(qū)被服務(wù)器處理的請(qǐng)求,桶口溢出的水代表被丟棄和不被處理的請(qǐng)求。
2、配置基本的限流
“流量限制”配置兩個(gè)主要的指令,limit_req_zone和limit_req,如下所示: limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
limit_req_zone指令設(shè)置流量限制和共享內(nèi)存區(qū)域的參數(shù),但實(shí)際上并不限制請(qǐng)求速率。所以需要通過(guò)添加limit_req指令,將流量限制應(yīng)用在特定的location或者server塊。在上面示例中,我們對(duì)/login/請(qǐng)求進(jìn)行流量限制。現(xiàn)在每個(gè)IP地址被限制為每秒只能請(qǐng)求10次/login/,更準(zhǔn)確地說(shuō),在前一個(gè)請(qǐng)求的100毫秒內(nèi)不能請(qǐng)求該URL。
upstream myweb {
server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=1;
}
server {
listen 80; server_name localhost;
location /login {
limit_req zone=mylimit; proxy_pass http://myweb;
proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
10.0.105.196配置(真實(shí)的WEB服務(wù)器): server {
listen 80; server_name localhost; location /login {
root /usr/share/nginx/html; index index.html index.html;
}
58/87
}
limit_req_zone指令定義了流量限制相關(guān)的參數(shù),而limit_req指令在出現(xiàn)的上下文中啟用流量限制(示例中,對(duì)于”/login/”的所有請(qǐng)求)。
limit_req_zone指令通常在HTTP塊中定義,使其可在多個(gè)上下文中使用,它需要以下三個(gè)參數(shù):
? Key - 定義應(yīng)用限制的請(qǐng)求特性。示例中的 Nginx 變量$binary_remote_addr,保存客戶(hù)端IP地址的二進(jìn)制形
式。這意味著,我們可以將每個(gè)不同的IP地址限制到,通過(guò)第三個(gè)參數(shù)設(shè)置的請(qǐng)求速率。(使用該變量是因?yàn)楸茸址问降目蛻?hù)端IP地址$remote_addr,占用更少的空間)
? Zone - 定義用于存儲(chǔ)每個(gè)IP地址狀態(tài)以及被限制請(qǐng)求URL訪問(wèn)頻率的共享內(nèi)存區(qū)域。保存在內(nèi)存共享區(qū)域的信息,意味著可以在Nginx的worker進(jìn)程之間共享。定義分為兩個(gè)部分:通過(guò)zone=keyword標(biāo)識(shí)區(qū)域的名
字,以及冒號(hào)后面跟區(qū)域大小。16000個(gè)IP地址的狀態(tài)信息,大約需要1MB,所以示例中區(qū)域可以存儲(chǔ)
160000個(gè)IP地址。
? Rate - 定義最大請(qǐng)求速率。在示例中,速率不能超過(guò)每秒10個(gè)請(qǐng)求。Nginx實(shí)際上以毫秒的粒度來(lái)跟蹤請(qǐng)
求,所以速率限制相當(dāng)于每100毫秒1個(gè)請(qǐng)求。因?yàn)椴辉试S”突發(fā)情況”(見(jiàn)下一章節(jié)),這意味著在前一個(gè)請(qǐng)求100毫秒內(nèi)到達(dá)的請(qǐng)求將被拒絕。(1秒(s)=1000毫秒(ms))
處理突發(fā)
如果我們?cè)?00毫秒內(nèi)接收到2個(gè)請(qǐng)求,怎么辦?對(duì)于第二個(gè)請(qǐng)求,Nginx將給客戶(hù)端返回狀態(tài)碼503。這可能并不是我們想要的結(jié)果,因?yàn)閼?yīng)用本質(zhì)上趨向于突發(fā)性。相反地,我們希望緩沖任何超額的請(qǐng)求,然后及時(shí)地處理它們。我們更新下配置,在limit_req中使用burst參數(shù):
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s; upstream myweb {
server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=1;
}
server {
listen 80; server_name localhost;
location /login {
limit_req zone=mylimit burst=20; proxy_pass http://myweb; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
burst參數(shù)定義了超出zone指定速率的情況下(示例中的mylimit區(qū)域,速率限制在每秒10個(gè)請(qǐng)求,或每100毫秒一個(gè)請(qǐng)求),客戶(hù)端還能發(fā)起多少請(qǐng)求。上一個(gè)請(qǐng)求100毫秒內(nèi)到達(dá)的請(qǐng)求將會(huì)被放入隊(duì)列,我們將隊(duì)列大小設(shè)置為20。
59/87
這意味著,如果從一個(gè)給定IP地址發(fā)送21個(gè)請(qǐng)求,Nginx會(huì)立即將第一個(gè)請(qǐng)求發(fā)送到上游服務(wù)器群,然
后將余下20個(gè)請(qǐng)求放在隊(duì)列中。然后每100毫秒轉(zhuǎn)發(fā)一個(gè)排隊(duì)的請(qǐng)求,只有當(dāng)傳入請(qǐng)求使隊(duì)列中排隊(duì)的請(qǐng)求數(shù)超過(guò)20時(shí),Nginx才會(huì)向客戶(hù)端返回503。
nginx流量限制(高級(jí))
通過(guò)將基本的“流量限制”與其他Nginx功能配合使用,我們可以實(shí)現(xiàn)更細(xì)粒度的流量限制。
1、白名單
下面這個(gè)例子將展示,如何對(duì)任何不在白名單內(nèi)的請(qǐng)求強(qiáng)制執(zhí)行“流量限制”: http {
include /etc/nginx/mime.types; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
geo $limit {
default 1;
10.0.0.0/24 0;
192.168.0.0/24 0;
}
map $limit $limit_key { 0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=req_zone:10m rate=5r/s;
server {
listen 80; server_name localhost; location / {
limit_req zone=req_zone burst=10 nodelay; root /usr/share/nginx/html;
index index.html index.hml;
}
}
include /etc/nginx/conf.d/*.conf;
}
這個(gè)例子同時(shí)使用了geo和map指令。geo塊將給在白名單中的IP地址對(duì)應(yīng)的$limit變量分配一個(gè)值0,給其它不在白名單中的分配一個(gè)值1。然后我們使用一個(gè)映射將這些值轉(zhuǎn)為key,如下:
?如果$limit變量的值是0,$limit_key變量將被賦值為空字符串
?如果$limit變量的值是1,$limit_key變量將被賦值為客戶(hù)端二進(jìn)制形式的IP地址
兩個(gè)指令配合使用,白名單內(nèi)IP地址的$limit_key變量被賦值為空字符串,不在白名單內(nèi)的被賦值為客戶(hù)端的IP地址。當(dāng)limit_req_zone后的第一個(gè)參數(shù)是空字符串時(shí),不會(huì)應(yīng)用“流量限制”,所以白名單內(nèi)的IP地
址(10.0.0.0/24和192.168.0.0/24 網(wǎng)段內(nèi))不會(huì)被限制。其它所有IP地址都會(huì)被限制到每秒5個(gè)請(qǐng)求。limit_req
指令將限制應(yīng)用到/的location塊,允許在配置的限制上最多超過(guò)10個(gè)數(shù)據(jù)包的突發(fā),并且不會(huì)延遲轉(zhuǎn)發(fā)。
60/87
流量控制相關(guān)功能
1、配置日志記錄
默認(rèn)情況下,Nginx會(huì)在日志中記錄由于流量限制而延遲或丟棄的請(qǐng)求,如下所示:
2019/02/13 04:20:00 [error] 120315#0: *32086 limiting requests, excess: 1.000 by zone "mylimit", client:
192.168.1.2, server: nginx.com, request: "GET / HTTP/1.0", host: "nginx.com"
日志條目中包含的字段:
?limiting requests - 表明日志條目記錄的是被“流量限制”請(qǐng)求
?excess - 每毫秒超過(guò)對(duì)應(yīng)“流量限制”配置的請(qǐng)求數(shù)量
?zone - 定義實(shí)施“流量限制”的區(qū)域
?client - 發(fā)起請(qǐng)求的客戶(hù)端IP地址
?server - 服務(wù)器IP地址或主機(jī)名
?request - 客戶(hù)端發(fā)起的實(shí)際HTTP請(qǐng)求
?host - HTTP報(bào)頭中host的值
默認(rèn)情況下,Nginx以error級(jí)別來(lái)記錄被拒絕的請(qǐng)求,如上面示例中的[error]所示(Ngin以較低級(jí)別記錄延時(shí)請(qǐng)求,一般是info級(jí)別)。如要更改Nginx的日志記錄級(jí)別,需要使用limit_req_log_level指令。這里,我
們將被拒絕請(qǐng)求的日志記錄級(jí)別設(shè)置為warn:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s; upstream myweb {
server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=1;
}
server {
listen 80; server_name localhost;
location /login {
limit_req zone=mylimit burst=20 nodelay; limit_req_log_level warn;
proxy_pass http://myweb; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
2、發(fā)送到客戶(hù)端的錯(cuò)誤代碼
一般情況下,客戶(hù)端超過(guò)配置的流量限制時(shí),Nginx響應(yīng)狀態(tài)碼為503(Service Temporarily Unavailable)??梢允褂胠imit_req_status指令來(lái)設(shè)置為其它狀態(tài)碼(例如下面的404狀態(tài)碼): limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
upstream myweb {
server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=1;
}
server {
listen 80; server_name localhost;
location /login {
limit_req zone=mylimit burst=20 nodelay; limit_req_log_level warn; limit_req_status 404;
proxy_pass http://myweb; proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
61/87
}
}
nginx訪問(wèn)控制
1、nginx 訪問(wèn)控制模塊(1)基于IP的訪問(wèn)控制:http_access_module
(2)基于用戶(hù)的信任登錄:http_auth_basic_module
基于IP的訪問(wèn)控制
2、基于IP的訪問(wèn)控制
1)、配置語(yǔ)法
Syntax:allow address | CIDR | unix: | all; default:默認(rèn)無(wú)Context:http,server,location,limit_except
Syntax:deny address | CIDR | unix: | all; default:默認(rèn)無(wú)Context:http,server,location,limit_except
3、配置測(cè)試
修改/etc/nginx/conf.d/access_mod.conf內(nèi)容如下: server {
listen 80; server_name localhost; location ~ ^/admin {
root /home/www/html; index index.html index.hml; deny 192.168.1.8;
allow all;
}
}
#需要注意:
如果先允許訪問(wèn),在定義拒絕訪問(wèn)。那么拒絕訪問(wèn)不生效。
虛擬機(jī)宿主機(jī)IP為192.168.1.8,虛擬機(jī)IP為192.168.1.11,故這里禁止宿主機(jī)訪問(wèn),允許其他所有IP訪
62/87
問(wèn)。 宿主機(jī)訪問(wèn)http://192.168.1.11/admin,顯示403 Forbidden。 當(dāng)然也可以反向配置,同時(shí)也可以使用IP
網(wǎng)段的配置方式,如allow 192.168.1.0/24;,表示滿足此網(wǎng)段的IP都可以訪問(wèn)。
4、指定location拒絕所有請(qǐng)求
如果你想拒絕某個(gè)指定URL地址的所有請(qǐng)求,而不是僅僅對(duì)其限速,只需要在location塊中配置deny all指令:
server {
listen 80; server_name localhost; location /foo.html {
root /home/www/html; deny all;
}
}
基于用戶(hù)的信任登錄
1、配置語(yǔ)法
Syntax:auth_basic string | off;
default:auth_basic off;
Context:http,server,location,limit_except
Syntax:auth_basic_user_file file; default:默認(rèn)無(wú)Context:http,server,location,limit_except
file:存儲(chǔ)用戶(hù)名密碼信息的文件。
2、配置示例
配置auth_mod.conf,內(nèi)容如下: server {
listen 80; server_name localhost; location ~ ^/admin {
root /home/www/html; index index.html index.hml;
auth_basic "Auth access test!"; auth_basic_user_file /etc/nginx/auth.conf;
}
}
auth_basic不為off,開(kāi)啟登錄驗(yàn)證功能,auth_basic_user_file加載賬號(hào)密碼文件。
3、建立口令文件
[root@192 ~]# yum install -y httpd-tools
#htpasswd 是開(kāi)源 http 服務(wù)器 apache httpd 的一個(gè)命令工具,用于生成 http 基本認(rèn)證的密碼文件 [root@192 ~]# htpasswd -cm /etc/nginx/auth_conf user10
[root@192 ~]# htpasswd -m /etc/nginx/auth_conf user20 [root@192 ~]# cat /etc/nginx/auth_conf user10:$apr1$MOa9UVqF$RlYRMk7eprViEpNtDV0n40 user20:$apr1$biHJhW03$xboNUJgHME6yDd17gkQNb0
4、訪問(wèn)測(cè)試
63/87
5、局限性
(1)用戶(hù)信息依賴(lài)文件方式(2)操作管理機(jī)械,效率低下
6、解決方法
(1)Nginx結(jié)合LUA實(shí)現(xiàn)高效驗(yàn)證(2)Nginx和LDAP打通,利用nginx-auth-ldap模塊
(3)Nginx只做中間代理,具體認(rèn)證交給應(yīng)用。
nginx變量(了解)
nginx變量簡(jiǎn)介:
?所有的 Nginx變量在 Nginx 配置文件中引用時(shí)都須帶上 $ 前綴
?在 Nginx 配置中,變量只能存放一種類(lèi)型的值,有且也只存在一種類(lèi)型,那就是字符串類(lèi)型
?nginx可以使用變量簡(jiǎn)化配置與提高配置的靈活性,所有的變量值都可以通過(guò)這種方式引用:
64/87
nginx 變量的定義和使用:nginx中的變量分為兩種,自定義變量與內(nèi)置預(yù)定義變量
1、自定義變量
可以在sever,http,location等標(biāo)簽中使用set命令(非唯一)聲明變量,語(yǔ)法如下 set $變量名 變量值注意:
?nginx 中的變量必須都以$開(kāi)頭
?nginx 的配置文件中所有使用的變量都必須是聲明過(guò)的,否則 nginx 會(huì)無(wú)法啟動(dòng)并打印相關(guān)異常日志
nginx安裝echo模塊
一:安裝部署查看已經(jīng)安裝的nginx的版本
[root@192 ~]# nginx -V
上傳或者下載一個(gè)相同版本的nginx包 [root@192 ~]# ls
anaconda-ks.cfg nginx-1.16.0.tar.gz
下載echo模塊的安裝包
[root@192 ~]# wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz [root@192 ~]# ls
anaconda-ks.cfg nginx-1.16.0.tar.gz v0.61.tar.gz
解壓到相同路徑下:
[root@192 ~]# tar xzf nginx-1.16.0.tar.gz -C /usr/local/ [root@192 ~]# tar xzf v0.61.tar.gz -C /usr/local/
安裝編譯工具
[root@192 ~]# cd /usr/local/
[root@192 local]# yum -y install pcre pcre-devel openssl openssl-devel gcc gcc-c++ zlib zlib-devel
添加模塊:
[root@192 local]# cd nginx-1.16.0/
添加上原來(lái)已經(jīng)有的參數(shù)和新添加的模塊:
[root@192 nginx-1.16.0]# ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/ nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/ log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/ var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/ var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/ cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module -- with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=/usr/local/echo-nginx-module-0.61
[root@192 nginx-1.16.0]# make -j2 #編譯,不要make install 否則會(huì)覆蓋原來(lái)的文件 [root@192 nginx-1.16.0]# mv /usr/sbin/nginx /usr/sbin/nginx_bak #將原來(lái)的nignx備份 [root@192 nginx-1.16.0]# cp objs/nginx /usr/sbin/ 拷貝nignx
[root@192 nginx-1.16.0]# systemctl restart nginx #啟動(dòng)
65/87
[root@192 nginx-1.16.0]# nginx -V 查看模塊是否添加成功 nginx version: nginx/1.16.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules -- conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/ access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/ cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/ cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/ cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module -- with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add-module=/usr/local/echo-nginx-module-0.61
二:使用配置 $foo=hello
[root@192 ~]# cd /etc/nginx/conf.d/ [root@192 conf.d]# vim echo.conf server {
listen 80;
server_name localhost; location /test {
set $foo hello; echo "foo: $foo";
}
}
[root@192 conf.d]# nginx -s reload [root@192 conf.d]# curl localhost/test foo: hello
使用大括號(hào)插值
在“變量插值”的上下文中,還有一種特殊情況,即當(dāng)引用的變量名之后緊跟著變量名的構(gòu)成字符時(shí)(比如后跟字母、數(shù)字以及下劃線),我們就需要使用特別的記法來(lái)消除歧義,例如:
server {
listen 80;
server_name localhost; location /test-brace {
set $first "hello "; echo "${first}world";
}
}
輸出
[root@192 conf.d]# nginx -s reload [root@192 conf.d]# curl localhost/test-brace hello world
66/87
這里,我們?cè)?echo 配置指令的參數(shù)值中引用變量 first 的時(shí)候,后面緊跟著 world 這個(gè)單詞,所以如果直接寫(xiě)作 "firstworld" 則 Nginx “變量插值”計(jì)算引擎會(huì)將之識(shí)別為引用了變量 firstworld. 為了解決這個(gè)難題,Nginx 的字符串記法支持使用花括號(hào)在 之后把變量名圍起來(lái),比如這里的 ${first}。
內(nèi)置預(yù)定義變量
內(nèi)置預(yù)定義變量即無(wú)需聲明就可以使用的變量,通常包括一個(gè)http請(qǐng)求或響應(yīng)中一部分內(nèi)容的值,以下為一些常用的內(nèi)置預(yù)定義變量
67/87
$arg_PARAMETER GET請(qǐng)求中變量名PARAMETER參數(shù)的值。
$args 這個(gè)變量等于GET請(qǐng)求中的參數(shù)。例如,foo=123&bar=blahblah;這個(gè)變量只
可以被修改
$binary_remote_addr 二進(jìn)制碼形式的客戶(hù)端地址。
$body_bytes_sent 傳送頁(yè)面的字節(jié)數(shù)
$content_length 請(qǐng)求頭中的Content-length字段。
$content_type 請(qǐng)求頭中的Content-Type字段。
$cookie_COOKIE cookie COOKIE的值。
$document_root 當(dāng)前請(qǐng)求在root指令中指定的值。
$document_uri 與$uri相同。
$host 請(qǐng)求中的主機(jī)頭(Host)字段,如果請(qǐng)求中的主機(jī)頭不可用或者空,則為處理
請(qǐng)求的server名稱(chēng)(處理請(qǐng)求的server的server_name指令的值)。值為小寫(xiě),不
包含端口。
$hostname 機(jī)器名使用 gethostname系統(tǒng)調(diào)用的值
$httpHEADER HTTP請(qǐng)求頭中的內(nèi)容,HEADER為HTTP請(qǐng)求中的內(nèi)容轉(zhuǎn)為小寫(xiě),-變?yōu)?/em>(破折
號(hào)變?yōu)橄聞澗€),例如:$http_user_agent(Uaer-Agent的值);
$sent_httpHEADER HTTP響應(yīng)頭中的內(nèi)容,HEADER為HTTP響應(yīng)中的內(nèi)容轉(zhuǎn)為小寫(xiě),-變?yōu)?/em>(破折
號(hào)變?yōu)橄聞澗€),例如: $sent_http_cache_control, $sent_http_content_type…;
$is_args 如果$args設(shè)置,值為"?",否則為""。
$limit_rate 這個(gè)變量可以限制連接速率。
$nginx_version 當(dāng)前運(yùn)行的nginx版本號(hào)。
$query_string 與$args相同。
$remote_addr 客戶(hù)端的IP地址。
$remote_port 客戶(hù)端的端口。
$remote_user 已經(jīng)經(jīng)過(guò)Auth Basic Module驗(yàn)證的用戶(hù)名。
$request_filename 當(dāng)前連接請(qǐng)求的文件路徑,由root或alias指令與URI請(qǐng)求生成。
$request_body 這個(gè)變量(0.7.58+)包含請(qǐng)求的主要信息。在使用proxy_pass或fastcgi_pass
指令的location中比較有意義。
$request_body_file 客戶(hù)端請(qǐng)求主體信息的臨時(shí)文件名。
$request_completion 如果請(qǐng)求成功,設(shè)為"OK";如果請(qǐng)求未完成或者不是一系列請(qǐng)求中最后一部
分則設(shè)為空。
$request_method 這個(gè)變量是客戶(hù)端請(qǐng)求的動(dòng)作,通常為GET或POST。包括0.8.20及之前的版
本中,這個(gè)變量總為main request中的動(dòng)作,如果當(dāng)前請(qǐng)求是一個(gè)子請(qǐng)求,并
不使用這個(gè)當(dāng)前請(qǐng)求的動(dòng)作。
$request_uri 這個(gè)變量等于包含一些客戶(hù)端請(qǐng)求參數(shù)的原始URI,它無(wú)法修改,請(qǐng)查看$uri
更改或重寫(xiě)URI。
$scheme 所用的協(xié)議,比如http或者是https,比如rewrite ^(.+)$ $scheme://
example.com$1 redirect;
$server_addr 服務(wù)器地址,在完成一次系統(tǒng)調(diào)用后可以確定這個(gè)值,如果要繞開(kāi)系統(tǒng)調(diào)
用,則必須在listen中指定地址并且使用bind參數(shù)。
$server_name 服務(wù)器名稱(chēng)。
$server_port 請(qǐng)求到達(dá)服務(wù)器的端口號(hào)。
$server_protocol 請(qǐng)求使用的協(xié)議,通常是HTTP/1.0或HTTP/1.1。
變量名 定義
68/87
$uri 請(qǐng)求中的當(dāng)前URI(不帶請(qǐng)求參數(shù),參數(shù)位于args),不同于瀏覽器傳遞
的args),不同于瀏覽器傳遞的args),不同于瀏覽器傳遞的request_uri
的值,它可以通過(guò)內(nèi)部重定向,或者使用index指令進(jìn)行修改。不包括協(xié)議和主機(jī)名,例如/foo/bar.html
變量名 定義
uri vs request_uri
由 ngx_http_core 模塊提供的內(nèi)建變量 uri,可以用來(lái)獲取當(dāng)前請(qǐng)求的 URI(不含請(qǐng)求參數(shù)), 而 request_uri 則用來(lái)獲取請(qǐng)求最原始的 URI (包含請(qǐng)求參數(shù))。
server {
listen 80;
server_name localhost; location /test-uri {
echo "uri = $uri";
echo "request_uri = $request_uri";
}
}
輸出:
[root@192 conf.d]# nginx -s reload [root@192 conf.d]# curl localhost/test-uri uri = /test-uri
request_uri = /test-uri
[root@192 conf.d]# curl "localhost/test-uri?a=3&b=4" uri = /test-uri
request_uri = /test-uri?a=3&b=4
[root@192 conf.d]# curl "localhost/test-uri/hello%20world?a=3&b=4" uri = /test-uri/hello world
request_uri = /test-uri/hello%20world?a=3&b=4
arg_XXX
另一個(gè)特別常用的內(nèi)建變量其實(shí)并不是單獨(dú)一個(gè)變量,而是有無(wú)限多變種的一群變量,即名字以 arg_ 開(kāi)頭的所有變量,我們估且稱(chēng)之為 arg_XXX 變量群。
一個(gè)例子是 arg_name,這個(gè)變量的值是當(dāng)前請(qǐng)求中名為 name 的參數(shù)的值,而且還是未解碼的原始形式的值。
server {
listen 80;
server_name localhost; location /test-arg {
echo "name: $arg_name";
echo "class: $arg_class";
69/87
}
}
輸出:
[root@192 conf.d]# nginx -s reload [root@192 conf.d]# curl localhost/test-arg name:
class:
[root@192 conf.d]# curl "localhost/test-arg?name=Tom&class=3" name: Tom
class: 3
[root@192 conf.d]# curl "localhost/test-arg?name=hello%20world&class=9" name: hello%20world
class: 9
$arg_XXX 不區(qū)分大小寫(xiě)
其實(shí) $arg_name 不僅可以匹配 name 參數(shù),也可以匹配 NAME 參數(shù),抑或是 Name,Nginx 會(huì)在匹配參數(shù)名之前,自動(dòng)把原始請(qǐng)求中的參數(shù)名調(diào)整為全部小寫(xiě)的形式。
[root@192 conf.d]# curl "localhost/test-arg?NAME=Marry" name: Marry
class:
[root@192 conf.d]# curl "localhost/test-arg?Name=Jimmy&class=DSfef" name: Jimmy
class: DSfef
nginx 監(jiān)控
1、nginx的基礎(chǔ)監(jiān)控
?進(jìn)程監(jiān)控
?端口監(jiān)控
注意: 這兩個(gè)是必須要加在zabbix監(jiān)控,加觸發(fā)器有問(wèn)題及時(shí)告警。 web 服務(wù)器 nginx 以其高性能與抗并發(fā)能力越來(lái)越多的被用戶(hù)使用
nginx 提供了 ngx_http_stub_status_module,ngx_http_reqstat_module模塊,這個(gè)模塊提供了基本的監(jiān)控功能
2、監(jiān)控的主要指標(biāo)
1)、基本活躍指標(biāo)Accepts(接受)、Handled(已處理)、Requests(請(qǐng)求數(shù))是一直在增加的計(jì)數(shù)器。
Active(活躍)、Waiting(等待)、Reading(讀)、Writing(寫(xiě))隨著請(qǐng)求量而增減。
70/87
名稱(chēng) 描述 指標(biāo)類(lèi)型
Accepts(接受) NGINX 所接受的客戶(hù)端連接數(shù) 資源: 功能
Handled(已處理) 成功的客戶(hù)端連接數(shù) 資源: 功能
Dropped(已丟棄,計(jì)算得出) 丟棄的連接數(shù)(接受 - 已處理) 工作:錯(cuò)誤*
Requests(請(qǐng)求數(shù)) 客戶(hù)端請(qǐng)求數(shù) 工作:吞吐量
2)、每秒請(qǐng)求數(shù) -- QPS 通過(guò)持續(xù)的 QPS 監(jiān)控,可以立刻發(fā)現(xiàn)是否被惡意***或?qū)Ψ?wù)的可用性進(jìn)行評(píng)估。雖然當(dāng)問(wèn)題發(fā)生
時(shí),通過(guò) QPS 不能定位到確切問(wèn)題的位置,但是他卻可以在第一時(shí)間提醒你環(huán)境可能出問(wèn)題了。
3)、請(qǐng)求處理時(shí)間請(qǐng)求處理時(shí)間也可以被記錄在 access log 中,通過(guò)分析 access log,統(tǒng)計(jì)請(qǐng)求的平均響應(yīng)時(shí)間,通過(guò)持
續(xù)觀察,可以發(fā)現(xiàn)上游服務(wù)器的問(wèn)題
3、指標(biāo)的收集通過(guò)在編譯時(shí)加入 nginx 的 ngx_http_stub_status_module 模塊我們可以實(shí)時(shí)監(jiān)控以下基本的指標(biāo):
1)、nginx Stub Status 監(jiān)控模塊安裝
先使用命令查看是否已經(jīng)安裝這個(gè)模塊:
[root@localhost ~]# nginx -V
如果沒(méi)有此模塊,需要重新安裝,編譯命令如下:
./configure –with-http_stub_status_module 具體的使用方法是在執(zhí)行 ./configure 時(shí),指定 --with-http_stub_status_module,然后通過(guò)配置: server {
listen 80; server_name localhost; location /nginx-status {
stub_status on;
access_log on;
}
}
nginx 狀態(tài)查看
配置完成后在瀏覽器中輸入http://10.0.105.207/nginx-status 查看(或者用 curl localhost/ nginx_status),顯示信息如下:
Active connections: 2
server accepts handled requests 26 26 48
Reading: 0 Writing: 1 Waiting: 1
Active connections:2 #當(dāng)前nginx處理請(qǐng)求的數(shù)目(活躍的連接數(shù))
server accepts handled requests 26 26 48
nginx總共處理了26個(gè)連接,成功創(chuàng)建26次握手,也就是成功的連接數(shù)connection. 總共處理了48個(gè)請(qǐng)求
失敗連接=(總連接數(shù)-成功連接數(shù))(相等表示中間沒(méi)有失敗的), Reading : nginx讀取到客戶(hù)端的Header信息數(shù)。請(qǐng)求頭 -----速度快。 Writing :nginx返回給客戶(hù)端的Header信息數(shù)。響應(yīng)頭
Waiting :開(kāi)啟keep-alive的情況下,意思就是Nginx說(shuō)已經(jīng)處理完正在等候下一次請(qǐng)求指令的駐留連接。
#可以nginx有多少的長(zhǎng)連接。相當(dāng)于空閑的??梢园殉瑫r(shí)時(shí)間改的短一點(diǎn)。 ---------監(jiān)控的對(duì)象通常,一個(gè)連接在同一時(shí)間只接受一個(gè)請(qǐng)求。在這種情況下,Active 連接的數(shù)目 == Waiting 的連接 + Reading 請(qǐng)求 + Writing
71/87
HTTPS
https簡(jiǎn)介
HTTPS(全稱(chēng):HyperText Transfer Protocol over Secure Socket Layer),其實(shí) HTTPS 并不是一個(gè)新鮮協(xié)議,Google 很早就開(kāi)始啟用了,初衷是為了保證數(shù)據(jù)安全。 近些年,Google、Baidu、Facebook 等這樣的互
聯(lián)網(wǎng)巨頭,不謀而合地開(kāi)始大力推行 HTTPS, 國(guó)內(nèi)外的大型互聯(lián)網(wǎng)公司很多也都已經(jīng)啟用了全站 HTTPS,這也是未來(lái)互聯(lián)網(wǎng)發(fā)展的趨勢(shì)。
一、加密算法
1:對(duì)稱(chēng)加密 : A要給B發(fā)送數(shù)據(jù)
1,A做一個(gè)對(duì)稱(chēng)密鑰 2,使用密鑰給文件加密 3,發(fā)送加密以后的文件和鑰匙 4,B拿鑰匙解密加密和解密都是使用的同一個(gè)密鑰。
2:非對(duì)稱(chēng)加密 ---- 公鑰加密,私鑰解密 :A要給B發(fā)送數(shù)據(jù)
1.B做一對(duì)非對(duì)稱(chēng)的密鑰
2.發(fā)送公鑰給A
3.A拿公鑰對(duì)數(shù)據(jù)進(jìn)行加密
4.發(fā)送加密后的數(shù)據(jù)給B
5.B拿私鑰解密
3.哈希算法
將任意長(zhǎng)度的信息轉(zhuǎn)換為較短的固定長(zhǎng)度的值,通常其長(zhǎng)度要比信息小得多。
例如:MD5、SHA-1、SHA-2、SHA-256 等
4.數(shù)字簽名
簽名就是在信息的后面再加上一段內(nèi)容(信息經(jīng)過(guò)hash后的值),可以證明信息沒(méi)有被修改過(guò)。hash值一般都會(huì)加密后(也就是簽名)再和信息一起發(fā)送,以保證這個(gè)hash值不被修改。
72/87
二:HTTPS 協(xié)議介紹
? HTTP 協(xié)議(HyperText Transfer Protocol,超文本傳輸協(xié)議):是客戶(hù)端瀏覽器或其他程序與Web服務(wù)器之
間的應(yīng)用層通信協(xié)議 。
? HTTPS 協(xié)議(HyperText Transfer Protocol over Secure Socket Layer):可以理解為HTTP+SSL/TLS, 即
HTTP 下加入 SSL 層,HTTPS 的安全基礎(chǔ)是 SSL,因此加密的詳細(xì)內(nèi)容就需要 SSL,用于安全的 HTTP 數(shù)據(jù)傳輸。
HTTPS 相比 HTTP 多了一層 SSL/TLS
SSL/TLS :SSL(Secure Sockets Layer 安全套接層),及其繼任者傳輸層安全(Transport Layer Security,TLS)是為網(wǎng)絡(luò)通信提供安全及數(shù)據(jù)完整性的一種安全協(xié)議。TLS與SSL在傳輸層為數(shù)據(jù)通訊進(jìn)行加密提供安
全支持。
SSL協(xié)議可分為兩層:
SSL握手協(xié)議(SSL Handshake Protocol):它建立在SSL記錄協(xié)議之上,用于在實(shí)際的數(shù)據(jù)傳輸開(kāi)始前,通訊雙方進(jìn)行身份認(rèn)證、協(xié)商加密算法、交換加密密鑰等。相當(dāng)于連接
SSL記錄協(xié)議(SSL Record Protocol):它建立在可靠的傳輸協(xié)議(如TCP)之上,為高層協(xié)議提供數(shù)據(jù)封裝、壓縮、加密等基本功能的支持。 相當(dāng)于通信
SSL協(xié)議提供的服務(wù)主要有:ssl:身份認(rèn)證和數(shù)據(jù)加密。保證數(shù)據(jù)完整性1)認(rèn)證用戶(hù)和服務(wù)器,確保數(shù)據(jù)發(fā)送到正確的客戶(hù)機(jī)和服務(wù)器;2)加密數(shù)據(jù)以防止數(shù)據(jù)中途被竊??;3)維護(hù)數(shù)據(jù)的完整性,確保數(shù)據(jù)在傳輸過(guò)程中不被改變。
https工作原理
HTTP請(qǐng)求過(guò)程中,客戶(hù)端與服務(wù)器之間沒(méi)有任何身份確認(rèn)的過(guò)程,數(shù)據(jù)全部明文傳輸,“裸奔”在互聯(lián)網(wǎng)上,所以很容易遭到***的***。
客戶(hù)端發(fā)出的請(qǐng)求很容易被***截獲,如果此時(shí)***冒充服務(wù)器,則其可返回任意信息給客戶(hù)端,而不被客戶(hù)端察覺(jué)。
HTTP 傳輸面臨的風(fēng)險(xiǎn)有:
73/87
?竊聽(tīng)風(fēng)險(xiǎn):***可以獲知通信內(nèi)容。
?篡改風(fēng)險(xiǎn):***可以修改通信內(nèi)容。
?冒充風(fēng)險(xiǎn):***可以冒充他人身份參與通信。
那有沒(méi)有一種方式既可以安全的獲取公鑰,又能防止***冒充呢? 那就需要用到終極武器了:SSL 證書(shū)(申購(gòu))
?證書(shū):.crt, .pem
?私鑰:.key
?證書(shū)請(qǐng)求文件:.csr
服務(wù)器發(fā)送了一個(gè)SSL證書(shū)給客戶(hù)端,SSL 證書(shū)中包含的具體內(nèi)容有:(1)證書(shū)的發(fā)布機(jī)構(gòu)CA
(2)證書(shū)的有效期(3)公鑰(4)證書(shū)所有者
(5)簽名 ----- 簽名就可以理解為是鈔票里面的一個(gè)防偽標(biāo)簽。
客戶(hù)端在接受到服務(wù)端發(fā)來(lái)的SSL證書(shū)時(shí),會(huì)對(duì)證書(shū)的真?zhèn)芜M(jìn)行校驗(yàn),以瀏覽器為例說(shuō)明如下:(1)首先瀏覽器讀取證書(shū)中的證書(shū)所有者、有效期等信息進(jìn)行一一校驗(yàn)
(2)瀏覽器開(kāi)始查找操作系統(tǒng)中已內(nèi)置的受信任的證書(shū)發(fā)布機(jī)構(gòu)CA,與服務(wù)器發(fā)來(lái)的證書(shū)中的頒發(fā)者CA比對(duì),用于校驗(yàn)證書(shū)是否為合法機(jī)構(gòu)頒發(fā)
(3)如果找不到,瀏覽器就會(huì)報(bào)錯(cuò),說(shuō)明服務(wù)器發(fā)來(lái)的證書(shū)是不可信任的。
(4)如果找到,那么瀏覽器就會(huì)從操作系統(tǒng)中取出 頒發(fā)者CA 的公鑰,然后對(duì)服務(wù)器發(fā)來(lái)的證書(shū)里面的簽名進(jìn)行解密
(5)瀏覽器使用相同的hash算法計(jì)算出服務(wù)器發(fā)來(lái)的證書(shū)的hash值,將這個(gè)計(jì)算的hash值與證書(shū)中簽名做對(duì)比
(6)對(duì)比結(jié)果一致,則證明服務(wù)器發(fā)來(lái)的證書(shū)合法,沒(méi)有被冒充
(7)此時(shí)瀏覽器就可以讀取證書(shū)中的公鑰,用于后續(xù)加密了
(8)client與web協(xié)商對(duì)稱(chēng)加密算法,client生成對(duì)稱(chēng)加密密鑰并使用web公鑰加密,發(fā)送給web服務(wù)器,web服務(wù)器使用web私鑰解密
(9)使用對(duì)稱(chēng)加密密鑰傳輸數(shù)據(jù),并校驗(yàn)數(shù)據(jù)的完整性
所以通過(guò)發(fā)送SSL證書(shū)的形式,既解決了公鑰獲取問(wèn)題,又解決了***冒充問(wèn)題,一箭雙雕,HTTPS加密過(guò)程也就此形成
相比HTTP,HTTPS 傳輸更加安全(1) 所有信息都是加密傳播,***無(wú)法竊聽(tīng)。
(2) 具有校驗(yàn)機(jī)制,一旦被篡改,通信雙方會(huì)立刻發(fā)現(xiàn)。(3) 配備身份證書(shū),防止身份被冒充。
HTTPS 缺點(diǎn):
1.SSL 證書(shū)費(fèi)用很高,以及其在服務(wù)器上的部署、更新維護(hù)非常繁瑣
2.HTTPS 降低用戶(hù)訪問(wèn)速度(多次握手)
3.網(wǎng)站改用HTTPS 以后,由HTTP 跳轉(zhuǎn)到 HTTPS 的方式增加了用戶(hù)訪問(wèn)耗時(shí)(多數(shù)網(wǎng)站采用302跳轉(zhuǎn))
4.HTTPS 涉及到的安全算法會(huì)消耗 CPU 資源,需要增加大量機(jī)器(https訪問(wèn)過(guò)程需要加解密)
74/87
#國(guó)家;match表示申請(qǐng)者的申請(qǐng)信息必須與此一致
#州、省
#組織名、公司名
75/87
= match = match
= match
構(gòu)建私有的 CA 機(jī)構(gòu)
CA中心申請(qǐng)證書(shū)的流程:過(guò)程:
1。web服務(wù)器,生成一對(duì)非對(duì)稱(chēng)加密密鑰(web公鑰,web私鑰)
2。web服務(wù)器使用 web私鑰 生成 web服務(wù)器的證書(shū)請(qǐng)求,并將證書(shū)請(qǐng)求發(fā)給CA服務(wù)器3。CA服務(wù)器使用 CA的私鑰 對(duì) web 服務(wù)器的證書(shū)請(qǐng)求 進(jìn)行數(shù)字簽名得到 web服務(wù)器的數(shù)字證書(shū),并將web服務(wù)器的數(shù)字證書(shū)頒發(fā)給web服務(wù)器。
4。client訪問(wèn)web服務(wù)器,請(qǐng)求https連接,下載web數(shù)字證書(shū)
5。client下載 CA數(shù)字證書(shū)(CA身份信息+CA公鑰,由上一級(jí)CA頒發(fā),也可自簽名頒發(fā)),驗(yàn)證 web數(shù)字證書(shū)(CA數(shù)字證書(shū)中有CA公鑰,web數(shù)字證書(shū)是使用CA私鑰簽名的)
1、CA 介紹
CA(Certificate Authority)證書(shū)頒發(fā)機(jī)構(gòu)主要負(fù)責(zé)證書(shū)的頒發(fā)、管理以及歸檔和吊銷(xiāo)。證書(shū)內(nèi)包含了擁
有證書(shū)者的姓名、地址、電子郵件帳號(hào)、公鑰、證書(shū)有效期、發(fā)放證書(shū)的CA、CA的數(shù)字簽名等信息。證書(shū)主要有三大功能:加密、簽名、身份驗(yàn)證。
2、構(gòu)建私有 CA 檢查安裝 openssl,如果未安裝
[root@https-ca ~]# rpm -qa openssl
[root@https-ca ~]# yum install openssl openssl-devel
查看配置文件
openssl 配置/etc/pki/tls/openssl.cnf有關(guān)CA的配置。如果服務(wù)器為證書(shū)簽署者的身份那么就會(huì)用到此配
置文件,此配置文件對(duì)于證書(shū)申請(qǐng)者是無(wú)作用的。
[root@https-ca ~]# vim /etc/pki/tls/openssl.cnf
####################################################################
[ ca ]
default_ca = CA_default # 默認(rèn)的CA配置;CA_default指向下面配置塊
####################################################################
[ CA_default ]
dir = /etc/pki/CA # CA的默認(rèn)工作目錄
certs = $dir/certs # 認(rèn)證證書(shū)的目錄
crl_dir = $dir/crl # 證書(shū)吊銷(xiāo)列表的路徑
database = $dir/index.txt # 數(shù)據(jù)庫(kù)的索引文件
new_certs_dir = $dir/newcerts # 新頒發(fā)證書(shū)的默認(rèn)路徑
certificate = $dir/cacert.pem # 此服務(wù)認(rèn)證證書(shū),如果此服務(wù)器為根CA那么這里為自頒發(fā)證書(shū)
serial = $dir/serial # 下一個(gè)證書(shū)的證書(shū)編號(hào)
crlnumber = $dir/crlnumber # 下一個(gè)吊銷(xiāo)的證書(shū)編號(hào)
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# CA的私鑰
RANDFILE = $dir/private/.rand # 隨機(jī)數(shù)文件
x509_extensions = usr_cert # The extentions to add to the cert
name_opt = ca_default # 命名方式,以ca_default定義為準(zhǔn)
cert_opt = ca_default # 證書(shū)參數(shù),以ca_default定義為準(zhǔn)
default_days = 365 # 證書(shū)默認(rèn)有效期
default_crl_days= 30 # CRl的有效期
default_md = sha256 # 加密算法
preserve = no # keep passed DN ordering
policy = policy_match #policy_match策略生效
organizationalUnitName = optional #部門(mén)名稱(chēng);optional表示申請(qǐng)者可以的信息與此可以不一致
commonName = supplied
emailAddress = optional
#For the 'anything' policy
#At this point in time, you must list all acceptable 'object'
#types.
[ policy_anything ] #由于定義了policy_match策略生效,所以此策略暫未生效
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
3、根證書(shū)服務(wù)器目錄
根CA服務(wù)器:因?yàn)橹挥?CA 服務(wù)器的角色,所以用到的目錄只有/etc/pki/CA網(wǎng)站服務(wù)器:只是證書(shū)申請(qǐng)者的角色,所以用到的目錄只有/etc/pki/tls
4、創(chuàng)建所需要的文件
[root@https-ca ~]# cd /etc/pki/CA/ [root@https-ca CA]# ls
certs crl newcerts private
[root@https-ca CA]# touch index.txt #創(chuàng)建生成證書(shū)索引數(shù)據(jù)庫(kù)文件 [root@https-ca CA]# ls
certs crl index.txt newcerts private
[root@https-ca CA]# echo 01 > serial #指定第一個(gè)頒發(fā)證書(shū)的序列號(hào) [root@https-ca CA]# ls
certs crl index.txt newcerts private serial [root@https-ca CA]#
5、創(chuàng)建密鑰
在根CA服務(wù)器上創(chuàng)建密鑰,密鑰的位置必須為/etc/pki/CA/private/cakey.pem,這個(gè)是openssl.cnf中中指定的路徑,只要與配置文件中指定的匹配即可。
[root@https-ca CA]# (umask 066; openssl genrsa -out private/cakey.pem 2048) Generating RSA private key, 2048 bit long modulus
...........+++
...............+++
e is 65537 (0x10001)
6、生成自簽名證書(shū)
根CA自簽名證書(shū),根CA是最頂級(jí)的認(rèn)證機(jī)構(gòu),沒(méi)有人能夠認(rèn)證他,所以只能自己認(rèn)證自己生成自簽名證書(shū)。
[root@https-ca CA]# openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -days 7300 -out /etc/pki/CA/ cacert.pem -days 7300
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank
For some fields there will be a default value, If you enter '.', the field will be left blank.
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BEIJING Locality Name (eg, city) [Default City]:BEIJING
Organization Name (eg, company) [Default Company Ltd]:CA Organizational Unit Name (eg, section) []:OPT
Common Name (eg, your name or your server's hostname) []:ca.qf.com Email Address []:
[root@https-ca CA]# ls
cacert.pem certs crl index.txt newcerts private serial
76/87
-new: 生成新證書(shū)簽署請(qǐng)求
-x509: 專(zhuān)用于CA生成自簽證書(shū)
-key: 生成請(qǐng)求時(shí)用到的私鑰文件 -days n: 證書(shū)的有效期限
-out /PATH/TO/SOMECERTFILE: 證書(shū)的保存路徑
7、下載安裝證書(shū)/etc/pki/CA/cacert.pem就是生成的自簽名證書(shū)文件,使用 SZ/xftp工具將他導(dǎo)出到窗口機(jī)器中。然后雙
擊安裝此證書(shū)到受信任的根證書(shū)頒發(fā)機(jī)構(gòu). [root@https-ca CA]# yum install -y lrzsz [root@https-ca CA]# sz cacert.pem
8、客戶(hù)端CA 證書(shū)申請(qǐng)及簽名安裝 openssl
[root@nginx-server ~]# yum install openssl openssl-devel
客戶(hù)端生成私鑰文件
[root@nginx-server ~]# (umask 066; openssl genrsa -out /etc/pki/tls/private/www.qf.com.key 2048) Generating RSA private key, 2048 bit long modulus
..............................+++
..........+++
e is 65537 (0x10001)
[root@nginx-server ~]# cd /etc/pki/tls/private/ [root@nginx-server private]# ls www.qf.com.key
[root@nginx-server private]#
客戶(hù)端用私鑰加密生成證書(shū)請(qǐng)求
[root@nginx-server private]# ls ../ cert.pem certs misc openssl.cnf private
[root@nginx-server private]# openssl req -new -key /etc/pki/tls/private/www.qf.com.key -days 365 -out /etc/pki/ tls/www.qf.com.csr
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank
For some fields there will be a default value, If you enter '.', the field will be left blank.
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BEIJING Locality Name (eg, city) [Default City]:BEIJING
Organization Name (eg, company) [Default Company Ltd]:QF Organizational Unit Name (eg, section) []:OPT
Common Name (eg, your name or your server's hostname) []:www.qf.com Email Address []:
Please enter the following 'extra' attributes to be sent with your certificate request
A challenge password []:
An optional company name []: [root@nginx-server private]# ls ../
cert.pem certs misc openssl.cnf private www.qf.com.csr [root@nginx-server private]#
CSR(Certificate Signing Request)包含了公鑰和名字信息。通常以.csr為后綴,是網(wǎng)站向CA發(fā)起認(rèn)證請(qǐng)求的文件,是中間文件。
最后把生成的請(qǐng)求文件(/etc/pki/tls/www.qf.com.csr)傳輸給CA ,這里我使用scp命令,通過(guò)ssh協(xié)議,將該文件傳輸?shù)紺A下的/etc/pki/CA/private/目錄 [root@nginx-server private]# cd ../
[root@nginx-server tls]# scp www.qf.com.csr 10.0.105.181:/etc/pki/CA/private
77/87
root@10.0.105.181's password:
www.qf.com.csr 100% 997 331.9KB/s 00:00
9.CA 簽署證書(shū)
[root@https-ca ~]# openssl ca -in /etc/pki/CA/private/www.qf.com.csr -out /etc/pki/CA/certs/www.qf.com.crt - days 365
Using configuration from /etc/pki/tls/openssl.cnf Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: Jul 3 10:12:23 2019 GMT
Not After : Jul 2 10:12:23 2020 GMT
Subject:
countryName = CN
stateOrProvinceName = BEIJING
organizationName = QF
organizationalUnitName = OPT
commonName = www.qf.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
E3:AC:1A:55:2B:28:B9:80:DC:9C:C2:13:70:53:27:AD:3D:44:8F:D3
X509v3 Authority Key Identifier:
keyid:5D:2A:81:B2:E7:8D:D8:88:E5:7B:94:CA:75:65:9C:82:2B:A9:B2:3C
Certificate is to be certified until Jul 2 10:12:23 2020 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries
Data Base Updated
=========================================================
注意:可能遇到的問(wèn)題
[root@https-ca private]# cd
[root@https-ca ~]# openssl ca -in /etc/pki/CA/private/www.qf.com.csr -out /etc/pki/CA/certs/www.qf.com.ctr - days 365
Using configuration from /etc/pki/tls/openssl.cnf Check that the request matches the signature Signature ok
The organizationName field needed to be the same in the CA certificate (CA) and the request (QF)
因?yàn)槟J(rèn)使用/etc/pki/tls/openssl.cnf,里面要求其一致,修改organizationName=supplied修改 /etc/pki/tls/openssl.cnf
[root@https-ca ~]# vim /etc/pki/tls/openssl.cnf
policy = policy_match
82
83 # For the CA policy
84 [ policy_match ]
85 countryName = match
86 stateOrProvinceName = match
87 organizationName = supplied
88 organizationalUnitName = optional
89 commonName = supplied
90 emailAddress = optional
=========================================================
78/87
查看生成的證書(shū)的信息
[root@https-ca ~]# openssl x509 -in /etc/pki/CA/certs/www.qf.com.crt -noout -subject subject= /C=CN/ST=BEIJING/O=QF/OU=OPT/CN=www.qf.com
將生成的證書(shū)發(fā)放給請(qǐng)求客戶(hù)端
[root@https-ca ~]# cd /etc/pki/CA/certs/
[root@https-ca certs]# scp www.qf.com.ctr 10.0.105.199:/etc/pki/CA/certs/
root@10.0.105.199's password:
www.qf.com.ctr 100% 4422 998.3KB/s 00:00
10.測(cè)試:
nginx-client(充當(dāng)服務(wù)端): [root@localhost ~]# cd /etc/pki/ [root@localhost pki]# ls
CA ca-trust java nssdb nss-legacy rpm-gpg rsyslog tls [root@localhost pki]# cd CA/
[root@localhost CA]# ls certs crl newcerts private [root@localhost CA]# cd certs/ [root@localhost certs]# ls www.qf.com.crt [root@localhost certs]# pwd /etc/pki/CA/certs [root@localhost certs]# ls www.qf.com.ctr [root@localhost certs]# pwd /etc/pki/CA/certs
[root@localhost certs]# find / -name .key /etc/pki/tls/private/www.qf.com.key /usr/share/doc/openssh-7.4p1/PROTOCOL.key [root@localhost certs]# find / -name .ctr
還是在這臺(tái)機(jī)器安裝nginx并且配置證書(shū): root@localhost conf.d]# pwd /etc/nginx/conf.d
[root@localhost conf.d]# vim nginx.conf server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/pki/CA/certs/www.qf.com.crt; #指定證書(shū)路徑
ssl_certificate_key /etc/pki/tls/private/www.qf.com.key; #指定私鑰路徑 ssl_session_timeout 5m; #配置用于SSL會(huì)話的緩存
ssl_protocols SSLv2 SSLv3 TLSv1; #指定使用的協(xié)議
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; # //密碼指定為OpenSSL支持的格式
ssl_prefer_server_ciphers on; #設(shè)置協(xié)商加密算法時(shí),優(yōu)先使用服務(wù)端的加密,而不是客戶(hù)端瀏覽器
的。
location / {
root /usr/share/nginx/html; index index.html index.htm;
}
}
保存重啟
[root@localhost conf.d]# nginx -t [root@localhost conf.d]# nginx -s reload
瀏覽器測(cè)試訪問(wèn):
79/87
CA吊銷(xiāo)證書(shū)
1、知道客戶(hù)端吊銷(xiāo)的證書(shū)的serial [root@https-ca ~]# openssl x509 -in /etc/pki/tls/cert.pem -noout -serial -subject serial=5EC3B7A6437FA4E0
subject= /CN=ACCVRAIZ1/OU=PKIACCV/O=ACCV/C=ES
2、吊銷(xiāo)證書(shū)
先根據(jù)客戶(hù)提交的serial與subject信息,對(duì)比檢驗(yàn)是否與index.txt文件中的信息一致;然后
[root@https-ca ~]# openssl ca -revoke /etc/pki/CA/newcerts/01.pem
3、生成吊銷(xiāo)證書(shū)的編號(hào)第一次吊銷(xiāo)一個(gè)證書(shū)時(shí)才需要執(zhí)行
[root@https-ca ~]# echo 01 > /etc/pki/CA/crlnumber
80/87
4、更新證書(shū)吊銷(xiāo)列表
[root@https-ca ~]# openssl ca -gencrl -out thisca.crl
5、查看證書(shū)吊銷(xiāo)列表
[root@https-ca ~]# openssl crl -in /root/thisca.crl -noout -text
nginx的https部署實(shí)戰(zhàn)
1.申請(qǐng)證書(shū)與認(rèn)證
2.證書(shū)下載與配置
3.問(wèn)題分析與總結(jié)
1、證書(shū)申請(qǐng)(具體上課操作演示)
2、域名驗(yàn)證(具體上課操作演示)
3、證書(shū)下載與配置(具體上課操作演示)
[root@xiaoxuan conf.d]# cat /etc/nginx/conf.d/nginx_ssl.conf server {
listen 443 ssl;
server_name www.testpm.cn;
access_log /var/log/nginx/https_access.log main;
#ssl on;
ssl_certificate /etc/nginx/cert/2447549_www.testpm.cn.pem; ssl_certificate_key /etc/nginx/cert/2447549_www.testpm.cn.key; ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/html; index index.html index.htm;
}
}
性能優(yōu)化
當(dāng)我需要進(jìn)行性能優(yōu)化時(shí),說(shuō)明我們服務(wù)器無(wú)法滿足日益增長(zhǎng)的業(yè)務(wù)。性能優(yōu)化是一個(gè)比較大的課題,需要從以下幾個(gè)方面進(jìn)行探討
?當(dāng)前系統(tǒng)結(jié)構(gòu)瓶頸
?了解業(yè)務(wù)模式
?性能與安全
1、當(dāng)前系統(tǒng)結(jié)構(gòu)瓶頸
首先需要了解的是當(dāng)前系統(tǒng)瓶頸,用的是什么,跑的是什么業(yè)務(wù)。里面的服務(wù)是什么樣子,每個(gè)服務(wù)最大支持多少并發(fā)。比如針對(duì)nginx而言,我們處理靜態(tài)資源效率最高的瓶頸是多大?
可以通過(guò)查看當(dāng)前cpu負(fù)荷,內(nèi)存使用率,進(jìn)程使用率來(lái)做簡(jiǎn)單判斷。還可以通過(guò)操作系統(tǒng)的一些工
81/87
具來(lái)判斷當(dāng)前系統(tǒng)性能瓶頸,如分析對(duì)應(yīng)的日志,查看請(qǐng)求數(shù)量。也可以通過(guò)nginx http_stub_status_module模塊來(lái)查看對(duì)應(yīng)的連接數(shù),總握手次數(shù),總請(qǐng)求數(shù)。也可以對(duì)線上進(jìn)行壓力測(cè)試,來(lái)了解當(dāng)前的系統(tǒng)能性能,并發(fā)數(shù),做好性能評(píng)估。
2、了解業(yè)務(wù)模式
雖然我們是在做性能優(yōu)化,但還是要熟悉業(yè)務(wù),最終目的都是為業(yè)務(wù)服務(wù)的。我們要了解每一個(gè)接口業(yè)務(wù)類(lèi)型是什么樣的業(yè)務(wù),比如電子商務(wù)搶購(gòu)模式,這種情況平時(shí)流量會(huì)很小,但是到了搶購(gòu)時(shí)間,流量一下子就會(huì)猛漲。也要了解系統(tǒng)層級(jí)結(jié)構(gòu),每一層在中間層做的是代理還是動(dòng)靜分離,還是后臺(tái)進(jìn)行直接服務(wù)。需要我們對(duì)業(yè)務(wù)接入層和系統(tǒng)層次要有一個(gè)梳理
3、性能與安全
性能與安全也是一個(gè)需要考慮的因素,往往大家注重性能忽略安全或注重安全又忽略性能。比如說(shuō)我們?cè)谠O(shè)計(jì)防火墻時(shí),如果規(guī)則過(guò)于全面肯定會(huì)對(duì)性能方面有影響。如果對(duì)性能過(guò)于注重在安全方面肯定會(huì)留下很大隱患。所以大家要評(píng)估好兩者的關(guān)系,把握好兩者的孰重孰輕,以及整體的相關(guān)性。權(quán)衡好對(duì)應(yīng)的點(diǎn)。
4、系統(tǒng)與nginx性能優(yōu)化
大家對(duì)相關(guān)的系統(tǒng)瓶頸及現(xiàn)狀有了一定的了解之后,就可以根據(jù)影響性能方面做一個(gè)全體的評(píng)估和優(yōu)
化。
?網(wǎng)絡(luò)(網(wǎng)絡(luò)流量、是否有丟包,網(wǎng)絡(luò)的穩(wěn)定性都會(huì)影響用戶(hù)請(qǐng)求)
?系統(tǒng)(系統(tǒng)負(fù)載、飽和、內(nèi)存使用率、系統(tǒng)的穩(wěn)定性、硬件磁盤(pán)是否有損壞)
?服務(wù)(連接優(yōu)化、內(nèi)核性能優(yōu)化、http服務(wù)請(qǐng)求優(yōu)化都可以在nginx中根據(jù)業(yè)務(wù)來(lái)進(jìn)行設(shè)置)
?程序(接口性能、處理請(qǐng)求速度、每個(gè)程序的執(zhí)行效率)
?數(shù)據(jù)庫(kù)、底層服務(wù)上面列舉出來(lái)每一級(jí)都會(huì)有關(guān)聯(lián),也會(huì)影響整體性能,這里主要關(guān)注的是nginx服務(wù)這一層。
文件句柄
1、文件句柄
在linux/unix操作系統(tǒng)中一切皆文件,我們的設(shè)備是文件,文件是文件,文件夾也是文件。當(dāng)我們用戶(hù)每發(fā)起一次請(qǐng)求,就會(huì)產(chǎn)生一個(gè)文件句柄。文件句柄可以簡(jiǎn)單的理解為文件句柄就是一個(gè)索引。文件句柄
就會(huì)隨著請(qǐng)求量的增多,進(jìn)程調(diào)用頻繁增加,那么產(chǎn)生的文件句柄也就會(huì)越多。
系統(tǒng)默認(rèn)對(duì)文件句柄是有限制的,不可能會(huì)讓一個(gè)進(jìn)程無(wú)限制的調(diào)用句柄。因?yàn)橄到y(tǒng)資源是有限的,所以我們需要限制每一個(gè)服務(wù)能夠使用多大的文件句柄。操作系統(tǒng)默認(rèn)使用的文件句柄是1024個(gè)句柄。
2、設(shè)置方式
?系統(tǒng)全局性修改
?用戶(hù)局部性修改
?進(jìn)程局部性修改
3、系統(tǒng)全局性修該和用戶(hù)局部性修改
[root@nginx-server ~]# vim /etc/security/limits.conf
# soft core 0
# hard rss 10000
#@student hard nproc 20
#@faculty soft nproc 20
#@faculty hard nproc 50
#ftp hard nproc 0
#@student - maxlogins 4
#root只是針對(duì)root這個(gè)用戶(hù)來(lái)限制,soft只是發(fā)提醒,操作系統(tǒng)不會(huì)強(qiáng)制限制,一般的站點(diǎn)設(shè)置為一萬(wàn)左右就ok了 root soft nofile 65535
root hard nofile 65535
*soft nofile 25535
*hard nofile 25535
注意:
82/87
可以看到root和,root代表是root用戶(hù),代表的是所有用戶(hù),后面的數(shù)字就是文件句柄大小。大家可以根據(jù)個(gè)人業(yè)務(wù)來(lái)進(jìn)行設(shè)置。
4、進(jìn)程局部性修改:worker_rlimit_nofile 是在進(jìn)程上面進(jìn)行限制。 [root@nginx-server ~]# vim /etc/nginx/nginx.conf
user nginx; worker_processes 1;
error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid;
worker_rlimit_nofile 65535; #進(jìn)程限制
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types; default_type application/octet-stream;
log_format main '$http_user_agent' '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" ' '"$args" "$request_uri"';
access_log /var/log/nginx/access.log main;
sendfile on; #tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
cpu的親和配置
cpu的親和能夠使nginx對(duì)于不同的work工作進(jìn)程綁定到不同的cpu上面去。就能夠減少在work間不斷
切換cpu,把進(jìn)程通常不會(huì)在處理器之間頻繁遷移,進(jìn)程遷移的頻率小,來(lái)減少性能損耗。 https://nginx.org/en/docs/ngx_core_module.html#worker_cpu_affinity
查看物理cpu
[root@nginx-server ~]# cat /proc/cpuinfo | grep "physical id" | sort|uniq | wc -l
查看cpu核心數(shù)
83/87
[root@nginx-server ~]# cat /proc/cpuinfo|grep "cpu cores"|uniq
查看cpu使用率
[root@nginx-server ~]#top 回車(chē)后按 1
worker_processes
[root@nginx-server ~]# vim /etc/nginx/nginx.conf 將剛才查看到自己cpu * cpu核心就是worker_processes
worker_processes 2; #根據(jù)自己cpu核心數(shù)配置/這里也可以設(shè)置為auto
cpu
通過(guò)下面命令查看nginx進(jìn)程配置在哪個(gè)核上
[root@nginx-server ~]# ps -eo pid,args,psr |grep [n]ginx
3004 nginx: master process /usr/ 3
3005 nginx: worker process 3
在nginx 1.9版本之后,就幫我們自動(dòng)綁定了cpu; worker_cpu_affinity auto;
通用配置優(yōu)化
#將nginx進(jìn)程設(shè)置為普通用戶(hù),為了安全考慮 user nginx;
#當(dāng)前啟動(dòng)的worker進(jìn)程,官方建議是與系統(tǒng)核心數(shù)一致 worker_processes 2;
#方式一,就是自動(dòng)分配綁定 worker_cpu_affinity auto;
#日志配置成warn error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid;
#針對(duì) nginx 句柄的文件限制 worker_rlimit_nofile 35535;
#事件模型 events {
#使用epoll內(nèi)核模型 user epoll;
#每一個(gè)進(jìn)程可以處理多少個(gè)連接,如果是多核可以將連接數(shù)調(diào)高 worker_processes * 1024 worker_connections 10240;
}
http {
include /etc/nginx/mime.types;
84/87
default_type application/octet-stream;
charset utf-8; #設(shè)置字符集
#設(shè)置日志輸出格式,根據(jù)自己的情況設(shè)置 log_format main '$http_user_agent' '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '"$args" "$request_uri"';
access_log /var/log/nginx/access.log main;
sendfile on; #對(duì)靜態(tài)資源的處理比較有效 #tcp_nopush on; #如果做靜態(tài)資源服務(wù)器可以打開(kāi) #tcp_nodeny on; #當(dāng)nginx做動(dòng)態(tài)的服務(wù)時(shí)可以選擇打開(kāi)
keepalive_timeout 65;
########
#Gzip module
gzip on; #文件壓縮默認(rèn)可以打開(kāi) gzip_disable "MSIE [1-6]."; #對(duì)于有些瀏覽器不能識(shí)別壓縮,需要過(guò)濾如ie6 gzip_http_version 1.1;
include /etc/nginx/conf.d/*.conf;
}
壓力測(cè)試
ab壓力測(cè)試
ab是Apache超文本傳輸協(xié)議(HTTP)的性能測(cè)試工具。其設(shè)計(jì)意圖是描繪當(dāng)前所安裝的Apache的執(zhí)行性能,主要是顯示你安裝的Apache每秒可以處理多少個(gè)請(qǐng)求。
[root@nginx-server ~]# yum install httpd-tools [root@nginx-server ~]# ab -n 2000 -c 2 http://127.0.0.1/
-n 總的請(qǐng)求數(shù) -c 并發(fā)數(shù)
-k 是否開(kāi)啟長(zhǎng)連接
參數(shù)解釋
85/87
-n:即requests,用于指定壓力測(cè)試總共的執(zhí)行次數(shù)
-c:即concurrency,用于指定的并發(fā)數(shù)
-t:即timelimit,等待響應(yīng)的最大時(shí)間(單位:秒) -b:即windowsize,TCP發(fā)送/接收的緩沖大小(單位:字節(jié)) -p:即postfile,發(fā)送POST請(qǐng)求時(shí)需要上傳的文件,此外還必須設(shè)置-T參數(shù)-u:即putfile,發(fā)送PUT請(qǐng)求時(shí)需要上傳的文件,此外還必須設(shè)置-T參數(shù)
-T:即content-type,用于設(shè)置Content-Type請(qǐng)求頭信息,例如:application/x-www-form-urlencoded,默認(rèn)值為text/plain -v:即verbosity,指定打印幫助信息的冗余級(jí)別-w:以HTML表格形式打印結(jié)果
-i:使用HEAD請(qǐng)求代替GET請(qǐng)求
-x:插入字符串作為table標(biāo)簽的屬性-y:插入字符串作為tr標(biāo)簽的屬性-z:插入字符串作為td標(biāo)簽的屬性
-C:添加cookie信息,例如:"Apache=1234"(可以重復(fù)該參數(shù)選項(xiàng)以添加多個(gè))
-H:添加任意的請(qǐng)求頭,例如:"Accept-Encoding: gzip",請(qǐng)求頭將會(huì)添加在現(xiàn)有的多個(gè)請(qǐng)求頭之后(可以重復(fù)該參數(shù)選項(xiàng)以添加多個(gè))
-A:添加一個(gè)基本的網(wǎng)絡(luò)認(rèn)證信息,用戶(hù)名和密碼之間用英文冒號(hào)隔開(kāi)
-P:添加一個(gè)基本的代理認(rèn)證信息,用戶(hù)名和密碼之間用英文冒號(hào)隔開(kāi)
-X:指定使用的和端口號(hào),例如:"126.10.10.3:88"
-V:打印版本號(hào)并退出
-k:使用HTTP的KeepAlive特性
-d:不顯示百分比
-S:不顯示預(yù)估和警告信息-g:輸出結(jié)果信息到gnuplot格式的文件中
-e:輸出結(jié)果信息到CSV格式的文件中
-r:指定接收到錯(cuò)誤信息時(shí)不退出程序-H:顯示用法信息,其實(shí)就是ab -help
內(nèi)容解釋
Server Software: nginx/1.10.2 (服務(wù)器軟件名稱(chēng)及版本信息)
Server Hostname: 192.168.1.106(服務(wù)器主機(jī)名)
Server Port: 80 (服務(wù)器端口)
Document Path: /index1.html. (供測(cè)試的URL路徑)
Document Length: 3721 bytes (供測(cè)試的URL返回的文檔大小)
Concurrency Level: 1000 (并發(fā)數(shù))
Time taken for tests: 2.327 seconds (壓力測(cè)試消耗的總時(shí)間)
Complete requests: 5000 (的總次數(shù))
Failed requests: 688 (失敗的請(qǐng)求數(shù))
Write errors: 0 (網(wǎng)絡(luò)連接寫(xiě)入錯(cuò)誤數(shù))
Total transferred: 17402975 bytes (傳輸?shù)目倲?shù)據(jù)量)
HTML transferred: 16275725 bytes (HTML文檔的總數(shù)據(jù)量)
Requests per second: 2148.98 [#/sec] (mean) (平均每秒的請(qǐng)求數(shù)) 這個(gè)是非常重要的參數(shù)數(shù)值,服務(wù)器的吞吐量
Time per request: 465.338 [ms] (mean) (所有并發(fā)用戶(hù)(這里是1000)都請(qǐng)求一次的平均時(shí)間)
Time request: 0.247 [ms] (mean, across all concurrent requests) (單個(gè)用戶(hù)請(qǐng)求一次的平均時(shí)間)
Transfer rate: 7304.41 [Kbytes/sec] received 每秒獲取的數(shù)據(jù)長(zhǎng)度 (傳輸速率,單位:KB/s)
...
Percentage of the requests served within a certain time (ms)
50% 347 ## 50%的請(qǐng)求在347ms內(nèi)返回
66% 401 ## 60%的請(qǐng)求在401ms內(nèi)返回
75% 431
80% 516
90% 600
95% 846
98% 1571
86/87
99% 1593
100% 1619 (longest request)
87/87
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。