中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

HTTP協議是什么,HTTP協議有多少種請求方式

發布時間:2020-05-29 18:54:27 來源:億速云 閱讀:5746 作者:鴿子 欄目:云計算

HTTP

HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用于從萬維網(WWW:World Wide Web )服務器傳輸超文本到本地瀏覽器的傳送協議。HTTP是一個基于TCP/IP通信協議
來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。

http工作原理

1、HTTP 工作原理
HTTP協議工作于客戶端-服務端架構上。瀏覽器作為HTTP客戶端通過URL向HTTP服務端即WEB服務器發送所有請求。
Web服務器有:Nginx,Apache服務器,IIS服務器(Internet Information Services)等。
Web服務器根據接收到的請求后,向客戶端發送響應信息。
HTTP默認端口號為80,但是你也可以改為8080或者其他端口。HTTP三點注意事項:
-HTTP是無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,并收到客戶的應答后,即斷開連接。采用這種方式可以節省傳輸時間。
-HTTP是媒體獨立的:這意味著,只要客戶端和服務器知道如何處理的數據內容,任何類型的數據都可以通過HTTP發送。客戶端以及服務器指定使用適合的MIME-type內容類型。

-HTTP是無狀態:HTTP協議是無狀態協議。無狀態是指協議對于事務處理沒有記憶能力。缺少狀態意味著如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。

2.HTTP協議通信流程

1/87

http消息結構

消息結構:

HTTP是基于客戶端/服務端(C/S)的架構模型,通過一個可靠的鏈接來交換信息,是一個無狀態的請求/響應協議。
一個HTTP"客戶端"是一個應用程序(Web瀏覽器或其他任何客戶端),通過連接到服務器達到向服務
器發送一個或多個HTTP的請求的目的。
一個HTTP"服務器"同樣也是一個應用程序(通常是一個Web服務,如Apache Web服務器或IIS服務器等),通過接收客戶端的請求并向客戶端發送HTTP響應數據。
HTTP使用統一資源標識符(Uniform Resource Identifiers, URI)來傳輸數據和建立連接。

客戶端請求

客戶端發送一個HTTP請求到服務器的請求消息包括以下格式:請求行(request line)、請求頭部(header)、空行和請求數據四個部分組成,下圖給出了請求報文的一般格式。

服務器響應消息

HTTP響應也由四個部分組成,分別是:狀態行、消息報頭、空行和響應正文。

2/87

下面實例是一點典型的使用GET來傳遞數據的實例:客戶端請求:

Connected to www.testpm.cn (47.244.247.240) port 80 (#0)

GET /hello.txt HTTP/1.1  # 請求方式與版本協議。

User-Agent: curl/7.29.0  #用什么客戶端訪問
Host: www.testpm.cn #主機名,域名。主機和端口號,
Accept: / #匹配什么文件類型,“*” 是通用匹配。匹配所有類型

服務端響應:
< HTTP/1.1 200 OK   #請求返回的狀態碼
<Server: nginx/1.16.0 #請求的服務和版本號
<Date: Thu, 04 Jul 2019 08:19:40 GMT

<Content-Type: text/plain #文本類型,有html,plain:普通文本
<Content-Length: 12

<Last-Modified: Thu, 04 Jul 2019 08:13:25 GMT

<Connection: keep-alive #是否支持長連接

<ETag: "5d1db525-c" #標識,每次訪問如果與最開始的一樣返回304否則校驗不一致返回200
<Accept-Ranges: bytes

HTTP 請求方法

根據HTTP標準,HTTP請求可以使用多種請求方法。
HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

3/87

HTTP 響應頭信息

HTTP請求頭提供了關于請求,響應或者其他的發送實體的信息。在本章節中我們將具體來介紹HTTP響應頭信息。

4/87

應答頭 說明

Allow   服務器支持哪些請求方法(如GET、POST等)。
Content-Encoding    文檔的編碼(Encode)方法。只有在解碼之后才可以得到Content-Type頭指
定的內容類型。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載時間。
Java的GZIPOutputStream可以很方便地進行gzip壓縮,但只有Unix上的
Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet應該通過查看
Accept-Encoding頭(即request.getHeader("Accept-Encoding"))檢查瀏覽器是
否支持gzip,為支持gzip的瀏覽器返回經gzip壓縮的HTML頁面,為其他瀏覽器
返回普通頁面。

Content-Length  表示內容長度。只有當瀏覽器使用持久HTTP連接時才需要這個數據。如果你
想要利用持久連接的優勢,可以把輸出文檔寫入 ByteArrayOutputStream,完
成后查看其大小,然后把該值放入Content-Length頭,最后通過
byteArrayStream.writeTo(response.getOutputStream()發送內容。
Content-Type    表示后面的文檔屬于什么MIME類型。Servlet默認為text/plain,但通常需要顯
式地指定為text/html。由于經常要設置Content-Type,因此
HttpServletResponse提供了一個專用的方法setContentType。
Date    當前的GMT時間。你可以用setDateHeader來設置這個頭以避免轉換時間格式
的麻煩。

Expires 應該在什么時候認為文檔已經過期,從而不再緩存它?
Last-Modified   文檔的最后改動時間。客戶可以通過If-Modified-Since請求頭提供一個日期,
該請求將被視為一個條件GET,只有改動時間遲于指定時間的文檔才會返
回,否則返回一個304(Not Modified)狀態。Last-Modified也可用
setDateHeader方法來設置。
Location    表示客戶應當到哪里去提取文檔。Location通常不是直接設置的,而是通過
HttpServletResponse的sendRedirect方法,該方法同時設置狀態代碼為302。
Refresh 表示瀏覽器應該在多少時間之后刷新文檔,以秒計。除了刷新當前文檔之
外,你還可以通過setHeader("Refresh", "5; URL=http://host/path")讓瀏覽器讀
取指定的頁面。 注意這種功能通常是通過設置HTML頁面HEAD區的<META
HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">實現,這是因
為,自動刷新或重定向對于那些不能使用CGI或Servlet的HTML編寫者十分重
要。但是,對于Servlet來說,直接設置Refresh頭更加方便。 注意Refresh的
意義是"N秒之后刷新本頁面或訪問指定頁面",而不是"每隔N秒刷新本頁面或
訪問指定頁面"。因此,連續刷新要求每次都發送一個Refresh頭,而發送204
狀態代碼則可以阻止瀏覽器繼續刷新,不管是使用Refresh頭還是<META
HTTP-EQUIV="Refresh" ...>。 注意Refresh頭不屬于HTTP 1.1正式規范的一
部分,而是一個擴展,但Netscape和IE都支持它。
Server  服務器名字。Servlet一般不設置這個值,而是由Web服務器自己設置。
Set-Cookie  設置和頁面關聯的Cookie。Servlet不應使用response.setHeader("Set-
Cookie", ...),而是應使用HttpServletResponse提供的專用方法addCookie。參
見下文有關Cookie設置的討論。
WWW-Authenticate    客戶應該在Authorization頭中提供什么類型的授權信息?在包含401
(Unauthorized)狀態行的應答中這個頭是必需的。例如,
response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")。
注意Servlet一般不進行這方面的處理,而是讓Web服務器的專門機制來控制
受密碼保護頁面的訪問(例如.htaccess)。

HTTP 狀態碼

當瀏覽者訪問一個網頁時,瀏覽者的瀏覽器會向網頁所在服務器發出請求。當瀏覽器接收并顯示網頁前,此網頁所在的服務器會返回一個包含HTTP狀態碼的信息頭(server header)用以響應瀏覽器的請求。
HTTP狀態碼的英文為HTTP Status Code。

下面是常見的HTTP狀態碼:

5/87

?200 - 請求成功

?301 - 資源(網頁等)被永久轉移到其它URL

?404 - 請求的資源(網頁等)不存在

?500 - 內部服務器錯誤

HTTP狀態碼分類

HTTP狀態碼由三個十進制數字組成,第一個十進制數字定義了狀態碼的類型,后兩個數字沒有分類的作用。HTTP狀態碼共分為5種類型:

HTTP狀態碼列表:

6/87

100 Continue    繼續。客戶端應繼續其請求
101 Switching Protocols 切換協議。服務器根據客戶端的請求切換協議。只能切換到更高級的協
例如,切換到HTTP的新版本協議

200 OK  請求成功。一般用于GET與POST請求
201 Created 已創建。成功請求并創建了新的資源
202 Accepted    已接受。已經接受請求,但未處理完成
203 Non-Authoritative Information   非授權信息。請求成功。但返回的meta信息不在原始的服務器,而是一

204 No Content  無內容。服務器成功處理,但未返回內容。在未更新網頁的情況下,可
瀏覽器繼續顯示當前文檔

205 Reset Content   重置內容。服務器處理成功,用戶終端(例如:瀏覽器)應重置文檔視
可通過此返回碼清除瀏覽器的表單域

206 Partial Content 部分內容。服務器成功處理了部分GET請求

300 Multiple Choices    多種選擇。請求的資源可包括多個位置,相應可返回一個資源特征與地
列表用于用戶終端(例如:瀏覽器)選擇

301 Moved Permanently   永久移動。請求的資源已被永久的移動到新URI,返回信息會包括新的U
瀏覽器會自動定向到新URI。今后任何新的請求都應使用新的URI代替
302 Found   臨時移動。與301類似。但資源只是臨時被移動。客戶端應繼續使用原有
303 See Other   查看其它地址。與301類似。使用GET和POST請求查看
304 Not Modified    未修改。所請求的資源未修改,服務器返回此狀態碼時,不會返回任何
源。客戶端通常會緩存訪問過的資源,通過提供一個頭信息指出客戶端
只返回在指定日期之后修改的資源

305 Use Proxy   使用代理。所請求的資源必須通過代理訪問
306 Unused  已經被廢棄的HTTP狀態碼
307 Temporary Redirect  臨時重定向。與302類似。使用GET請求重定向

400 Bad Request 客戶端請求的語法錯誤,服務器無法理解
401 Unauthorized    請求要求用戶的身份認證
402 Payment Required    保留,將來使用
403 Forbidden   服務器理解請求客戶端的請求,但是拒絕執行此請求
404 Not Found   服務器無法根據客戶端的請求找到資源(網頁)。通過此代碼,網站設
員可設置"您所請求的資源無法找到"的個性頁面
405 Method Not Allowed  客戶端請求中的方法被禁止
406 Not Acceptable  服務器無法根據客戶端請求的內容特性完成請求
407 Proxy Authentication Required   請求要求代理的身份認證,與401類似,但請求者應當使用代理進行授權
408 Request Time-out    服務器等待客戶端發送的請求時間過長,超時
409 Conflict    服務器完成客戶端的PUT請求是可能返回此代碼,服務器處理請求時發生
沖突

410 Gone    客戶端請求的資源已經不存在。410不同于404,如果資源以前有現在被
刪除了可使用410代碼,網站設計人員可通過301代碼指定資源的新位置
411 Length Required 服務器無法處理客戶端發送的不帶Content-Length的請求信息
412 Precondition Failed 客戶端請求信息的先決條件錯誤
狀態碼 狀態碼英文名稱 中文描述

7/87

413 Request Entity Too Large    由于請求的實體過大,服務器無法處理,因此拒絕請求。為防止客
端的連續請求,服務器可能會關閉連接。如果只是服務器暫時無法
理,則會包含一個Retry-After的響應信息
414 Request-URI Too Large   請求的URI過長(URI通常為網址),服務器無法處理
415 Unsupported Media Type  服務器無法處理請求附帶的媒體格式
416 Requested range not satisfiable 客戶端請求的范圍無效
417 Expectation Failed  服務器無法滿足Expect的請求頭信息

500 Internal Server Error   服務器內部錯誤,無法完成請求
501 Not Implemented 服務器不支持請求的功能,無法完成請求
502 Bad Gateway 作為網關或者代理工作的服務器嘗試執行請求時,從遠程服務器接收到
個無效的響應

503 Service Unavailable 由于超載或系統維護,服務器暫時的無法處理客戶端的請求。延時的長
包含在服務器的Retry-After頭信息中
504 Gateway Time-out    充當網關或代理的服務器,未及時從遠端服務器獲取請求
505 HTTP Version not supported  服務器不支持請求的HTTP協議的版本,無法完成處理
狀態碼 狀態碼英文名稱 中文描述

apache虛擬主機

創建apache虛擬主機

1.安裝apache服務 yum -y install httpd httpd-tools httpd-devel mod_ssl (支持https認證) systemctl start httpd

systemctl enable httpd 2.創建虛擬主機的配置文件 /etc/httpd/conf.d/ 下創建.conf的虛擬主機配置文件 (主配置文件在/etc/httpd/ conf/httpd.conf)

分類:

基于 端口

基于ip

基于域名

第一種:基于域名的虛擬主機 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.創建網站發布目錄和網站

mkdir /web1 /web2

8/87

注意:一般的公司都是基于域名創建虛擬主機基于ip創建的虛擬主機,其他的相同,ip不同
基于端口創建的虛擬主機,其他的相同,端口不同

Nginx

簡介

Nginx (engine x) 是一個高性能的 HTTP 和 反向代理 服務,也是一個IMAP/POP3/SMTP服務。Nginx是由伊戈爾·賽索耶夫為俄羅斯訪問量第二的Rambler.ru站點(俄文:Рамблер)開發的,第一個公開版本0.1.0發布于
2004年10月4日。其將源代碼以類BSD許可證的形式發布,因它的穩定性、豐富的功能集、示例配置文件和低系統資源的消耗而聞名。2011年6月1日,nginx 1.0.4發布。

Nginx是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,并在一個BSD-like 協議下發行。其特點是占有內存少,并發能力強,事實上nginx的并發能力確實在同類型的網頁服務器中表現較好,中國大陸使用nginx網站用戶有:百度、京東、新浪、網易、騰訊、淘寶等。

在高連接并發的情況下,Nginx是Apache服務器不錯的替代品。

創始人伊戈爾·賽索耶夫

9/87

nginx功能

Nginx 是一個高性能的 Web 和反向代理服務器, 它具有有很多非常優越的特性:

單機環境下參考服務器配置。 并發連接數在7000+ -8000左右。 集群模式20000+
作為 Web 服務器:相比 Apache,Nginx 使用更少的資源,支持更多的并發連接,體現更高的效率,這
點使 Nginx 尤其受到虛擬主機提供商的歡迎。能夠支持高達 50,000 個并發連接數的響應,感謝 Nginx 為我們選擇了 epoll and kqueue 作為開發模型.
作為負載均衡服務器:Nginx 既可以在內部直接支持 Rails 和 PHP,也可以支持作為 HTTP代理服務器對外進行服務。Nginx 用 C 編寫, 不論是系統資源開銷還是 CPU 使用效率都比 Perlbal 要好的多。
作為郵件代理服務器: Nginx 同時也是一個非常優秀的郵件代理服務器(最早開發這個產品的目的之
一也是作為郵件代理服務器),Last.fm 描述了成功并且美妙的使用經驗。
Nginx 安裝非常的簡單,配置文件 非常簡潔(還能夠支持perl語法),Bugs非常少的服務器: Nginx 啟
動特別容易,并且幾乎可以做到7*24不間斷運行,即使運行數個月也不需要重新啟動。你還能夠在 不間斷服務的情況下進行軟件版本的升級。

異步,非阻塞

$ pstree |grep nginx

|-+= 81666 root nginx: master process nginx

| |--- 82500 nobody nginx: worker process

| --- 82501 nobody nginx: worker process

1個master進程,2個work進程

10/87

注意:Input/Output====I/O

每進來一個request,會有一個worker進程去處理。但不是全程的處理,處理到什么程度呢?處理到可能發生阻塞的地方,比如向上游(后端)服務器轉發request,并等待請求返回。那么,這個處理的worker不會這么一直等著,他會在發送完請求后,注冊一個事件:“如果upstream返回了,告訴我一聲,我再接著干”。于是他就休息去了。這就是異步。此時,如果再有request 進來,他就可以很快再按這種方式處理。這就是非阻塞和IO多路復用。而一旦上游服務器返回了,就會觸發這個事件,worker才會來接手,這個request才會接著往下走。這就是異步回調。

客戶(發送方)向收款員(接收方)付款(發送請求)后在等待收款員找零的過程中,還可以做其他

事情,比如打電話、聊天等;而收款員在等待收款機處理交易(IO操作)的過程中還可以幫助客戶將商品打包,當收款機產生結果后,收款員給客戶結賬(響應請求)。在四種方式中,這種方式是發送方和接收方通信效率最高的一種。

同步與異步的重點在消息通知的方式上,也就是調用結果通知的方式。

同步:當一個同步調用發出去后,調用者要一直等待調用結果的通知后,才能進行后續的執行。異步:當一個異步調用發出去后,調用者不能立即得到調用結果的返回。

同步取快遞:小明收到快遞將送達的短信,在樓下一直等到快遞送達。

異步取快遞:小明收到快遞將送達的短信,快遞到樓下后,小明再下樓去取。異步取快遞,小明知道快遞到達樓下有兩種方式:
1、不停的電話問快遞小哥到了沒有,即主動輪詢;
2、快遞小哥到樓下后,打電話通知小明,然后小明下樓取快遞,即回調通知。

阻塞與非阻塞在于進/線程等待消息時候的行為,也就是在等待消息的時候,當前進/線程是掛起還是非掛起狀態。

-阻塞阻塞調用在發出去后,在消息返回之前,當前進/線程會被掛起,直到有消息返回,當前進/線程才會被激活

-非阻塞非阻塞調用在發出去后,不會阻塞當前進/線程,而會立即返回。

阻塞取快遞:小明收到快遞即將送達的信息后,什么事都不做,一直專門等快遞。
非阻塞取快遞:小明收到快遞即將送達的信息后,等快遞的時候,還一邊敲代碼、一邊刷微信。

總結: 異步非阻塞:小明收到信息后,邊刷著微博,邊等快遞員通知他取快遞。

I/O多路復用 epoll()
epoll能更高效的檢查大量fd,UNIX中提供了類似功能的kqueue調用。epoll可以理解為event poll,不同于忙輪詢和無差別輪詢,當連接有I/O流事件產生的時候,epoll就會去告
訴進程哪個連接有I/O流事件產生,然后進程就去處理這個事件。此時我們對這些流的操作都是有意義的。(復雜度降低到了O(k),k為產生I/O事件的流的個數,也有認為O(1)的)

小明家樓下有一個收發室,每次有快遞到了,就先代收并做了標記;然后通知小明去取送給小明的快遞。

nginx 的內部技術架構

Nginx服務器,以其處理網絡請求的高并發、高性能及高效率,獲得了行業界的廣泛認可,近年已穩居web服務器部署排名第二的位置,并被廣泛用于反向代理和負載均衡。

Nginx是如何實現這些目標的呢?答案就是其獨特的內部技術架構設計。看懂下面這張圖,就明白了
Nginx的內部技術架構。

簡要說明幾點:
1)nginx啟動時,會生成兩種類型的進程,一個是主進程(Master),一個(windows版本的目前只有一

11/87

個)或多個工作進程(Worker)。主進程并不處理網絡請求,主要負責調度工作進程,也就是圖示的三

項:加載配置、啟動工作進程及非停升級。所以,nginx啟動以后,查看操作系統的進程列表,我們就能看到至少有兩個nginx進程。
2)服務器實際處理網絡請求及響應的是工作進程(worker),在類unix系統上,nginx可以配置多個worker,而每個worker進程都可以同時處理數以千計的網絡請求。
3)模塊化設計。nginx的worker,包括核心和功能性模塊,核心模塊負責維持一個運行循環(run-loop),執行網絡請求處理的不同階段的模塊功能,如網絡讀寫、存儲讀寫、內容傳輸、外出過濾,以及將請求發往上游服務器等。而其代碼的模塊化設計,也使得我們可以根據需要對功能模塊進行適當的選擇和修改,編譯成具有特定功能的服務器。
4)事件驅動、異步及非阻塞,可以說是nginx得以獲得高并發、高性能的關鍵因素,同時也得益于對
Linux、Solaris及類BSD等操作系統內核中事件通知及I/O性能增強功能的采用,如kqueue、epoll及event ports。5)代理(proxy)設計,可以說是nginx深入骨髓的設計,無論是對于HTTP,還是對于FastCGI、

memcache、Redis等的網絡請求或響應,本質上都采用了代理機制。所以,nginx天生就是高性能的代理服務器

nginx安裝部署

nginx部署-Yum安裝

訪問nginx的官方網站:http://www.nginx.org/ Nginx版本類型 Mainline version: 主線版,即開發版
Stable version: 最新穩定版,生產環境上建議使用的版本
Legacy versions:    遺留的老版本的穩定版

Yum安裝nginx

配置Yum源的官網: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.
安裝說明

在新計算機上首次安裝nginx之前,需要設置nginx軟件包存儲庫。 之后,您可以從存儲庫安裝和更新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

這里我們用穩定版本 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 關閉防火墻和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
啟動并設置開機啟動
[root@nginx-server ~]# systemctl start nginx [root@nginx-server ~]# systemctl enable nginx

nginx編譯安裝

1、安裝編譯環境

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、創建用戶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

編譯參數

查看 nginx 安裝的模塊

[root@localhost ~]#/usr/local/nginx/sbin/nginx -V

模塊參數具體功能

--with-cc-opt='-g -O2 -fPIE -fstack-protector //設置額外的參數將被添加到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//指定訪問日志
--error-log-path=/var/log/nginx/error.log   //指定錯誤日志
--lock-path=/var/lock/nginx.lock    //指定lock文件
--pid-path=/run/nginx.pid   //指定pid文件

--http-client-body-temp-path=/var/lib/nginx/body    //設定http客戶端請求臨時文件路徑
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi //設定http fastcgi臨時文件路徑
--http-proxy-temp-path=/var/lib/nginx/proxy //設定http代理臨時文件路徑
--http-scgi-temp-path=/var/lib/nginx/scgi   //設定http scgi臨時文件路徑
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi //設定http uwsgi臨時文件路徑
--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自上次啟動以來的狀態
--with-http_realip_module   //允許從請求標頭更改客戶端的IP地址值,默認為關
--with-http_auth_request_module //實現基于一個子請求的結果的客戶端授權。如果該子請求返回的
2xx響應代碼,所述接入是允許的。如果它返回401或403中,訪問被拒絕與相應的錯誤代碼。由子請求返回的任何其他響應代碼被認為是一個錯誤。
--with-http_addition_module //作為一個輸出過濾器,支持不完全緩沖,分部分響應請求
--with-http_dav_module  //增加PUT,DELETE,MKCOL:創建集合,COPY和MOVE方法 默認關閉,需
編譯開啟
--with-http_geoip_module    //使用預編譯的MaxMind數據庫解析客戶端IP地址,得到變量值
--with-http_gunzip_module   //它為不支持“gzip”編碼方法的客戶端解壓具有“Content-Encoding:
gzip”頭的響應。
--with-http_gzip_static_module  //在線實時壓縮輸出數據流
--with-http_image_filter_module //傳輸JPEG/GIF/PNG 圖片的一個過濾器)(默認為不啟用。gd庫要用
到)
--with-http_spdy_module //SPDY可以縮短網頁的加載時間
--with-http_sub_module  //允許用一些其他文本替換nginx響應中的一些文本
--with-http_xslt_module //過濾轉換XML請求
--with-mail //啟用POP3/IMAP4/SMTP代理模塊支持
--with-mail_ssl_module  //啟用ngx_mail_ssl_module支持啟用外部模塊支持

14/87

nginx部署

nginx.conf的組成:nginx.conf一共由三部分組成,分別為:全局塊、events塊、http塊。在http塊中又包含http全局塊、多個server塊。每個server塊中又包含server全局塊以及多個location塊。在統一配置塊中嵌套的配置快,各個之間不存在次序關系。

全局參數設置

worker_processes 4; #設置nginx啟動進程的數量,一般設置成與邏輯cpu數量相同 error_log logs/error.log; #指定錯誤日志 worker_rlimit_nofile 102400; #設置一個nginx進程能打開的最大文件數 pid /var/run/nginx.pid;

events {
worker_connections 1024; #設置一個進程的最大并發連接數

}

http 服務相關設置 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 /var/log/nginx/access.log main;  #設置訪問日志的位置和格式
sendfile    on; #是否調用sendfile函數輸出文件,一般設置為on,若nginx是用來進行磁盤IO負載應用
時,可以設置為off,降低系統負載
gzip    on; #是否開啟gzip壓縮,將注釋去掉開啟
keepalive_timeout 65;   #設置長連接的超時時間

#虛擬服務器的相關設置 server {

listen    80;#設置監聽的端口
server_name localhost;  #設置綁定的主機名、域名或ip地址
charset koi8-r; # 設置編碼字符
location / {
root /var/www/nginx;    #設置服務器默認網站的根目錄位置,需要手動創建
index index.html index.htm; #設置默認打開的文檔
}
error_page 500 502 503 504 /50x.html; #設置錯誤信息返回頁面

location = /50x.html {
root html;  #這里的絕對位置是/usr/local/nginx/html

}

}

}

檢測nginx配置文件是否正確
[root@localhost ~]# /usr/local/nginx/sbin/nginx -t [root@localhost ~]# mkdir -p /tmp/nginx

啟動nginx服務
[root@localhost ~]# /usr/local/nginx/sbin/nginx

通過 nginx 命令控制 nginx 服務

nginx -c /path/nginx.conf   # 以特定目錄下的配置文件啟動nginx:
nginx -s reload # 修改配置后重新加載生效
nginx -s reopen # 重新打開日志文件
nginx -s stop   # 快速停止nginx
nginx -s quit   # 完整有序的停止nginx
nginx -t    # 測試當前配置文件是否正確
nginx -t -c /path/to/nginx.conf # 測試特定的nginx配置文件是否正確

15/87

注意:
nginx -s reload 命令加載修改后的配置文件,命令下達后發生如下事件

1.Nginx的master進程檢查配置文件的正確性,若是錯誤則返回錯誤信息,nginx繼續采用原配置文件進行工作(因為worker未受到影響)
2.Nginx啟動新的worker進程,采用新的配置文件
3.Nginx將新的請求分配新的worker進程
4.Nginx等待以前的worker進程的全部請求已經都返回后,關閉相關worker進程

5.重復上面過程,知道全部舊的worker進程都被關閉掉

實現nginx開機自啟

[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() {

make required directories

user=nginx -V 2&gt;&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' - options=$nginx -V 2&gt;&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

echo "creating" $value

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

添加權限

chmod +x /etc/init.d/nginx
重新加載系統啟動文件
systemctl daemon-reload

啟動并設置開機自啟 systemctl start nginx

[root@localhost ~]# /sbin/chkconfig nginx on ---開機啟動

nginx自帶變量

nginx 日志文件分為 log_format 和 access_log 兩部分 log_format 定義記錄的格式,其語法格式為 access_log 樣式名稱 樣式詳情

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虛擬主機

什么是虛擬主機?

虛擬主機是一種特殊的軟硬件技術,它可以將網絡上的每一臺計算機分成多個虛擬主機,每個虛擬主

機可以獨立對外提供www服務,這樣就可以實現一臺主機對外提供多個web服務,每個虛擬主機之間是獨立的,互不影響。

nginx可以實現虛擬主機的配置,nginx支持三種類型的虛擬主機配置。1、基于域名的虛擬主機 (server_name來區分虛擬主機——應用:外部網站)2、基于ip的虛擬主機, (一塊主機綁定多個ip地址)
3、基于端口的虛擬主機 (端口來區分虛擬主機——應用:公司內部網站,外部網站的管理后臺)

19/87

基于域名

1、 基于域名的虛擬主機

[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 的虛擬機,創建 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

如果 yum 安裝的執行

[root@nginx]# nginx -s reload
4.客戶端配置路由映射
10.0.105.199 web.testpm.com 10.0.105.199 web.1000phone.com 5. 測試訪問瀏覽器輸入: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、配置通過ip區分的虛擬機

[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、 測試訪問瀏覽器輸入:http://10.0.105.199
瀏覽器輸入:http://10.0.105.201
5、補充
[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
測試訪問:
瀏覽器輸入:http://web.testpm.com/
瀏覽器輸入:http://web.1000phone.com:8080

錯誤解決

一. 問題描述: 配置完 nginx 兩個虛擬機后,客戶端能夠訪問原始的server ,新增加的 server 虛擬機 不能夠訪問,報錯如下頁面

解決過程:

  1. 查看報錯日志(找到錯誤日志)

[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.檢查權限
[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
說明:發現目錄權限沒有問題

3.檢查nginx啟動進程 [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
說明:發現nginx的work process是 nobody 的4.修改 nginx.conf 文件

23/87

打開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進程

nginx Proxy 代理

1、代理原理反向代理產生的背景:

在計算機世界里,由于單個服務器的處理客戶端(用戶)請求能力有一個極限,當用戶的接入請求蜂擁而入時,會造成服務器忙不過來的局面,可以使用多個服務器來共同分擔成千上萬的用戶請求,這些服務器提供相同的服務,對于用戶來說,根本感覺不到任何差別。

反向代理服務的實現:

需要有一個負載均衡設備(即反向代理服務器)來分發用戶請求,將用戶請求分發到空閑的服務器上。服務器返回自己的服務到負載均衡設備。
負載均衡設備將服務器的服務返回用戶。

24/87

2、正/反向代理的區別
那么問題來了,很多人這時會問什么是反向代理?為什么叫反向代理?什么是正向代理?我們來舉例說明

? 正向代理:舉例:
貸款

正向代理的過程隱藏了真實的請求客戶端,服務器不知道真實的客戶端是誰,客戶端請求的服務都被代理服務器代替請求。我們常說的代理也就是正向代理,正向代理代理的是請求方,也就是客戶端;比如
我們要訪問youtube,可是不能訪問,只能先安裝個FQ軟件代你去訪問,通過FQ軟件才能訪問,FQ軟件就叫作正向代理。

正向代理中,proxy和client同屬一個LAN

25/87

反向代理:

反向代理的過程隱藏了真實的服務器,客戶不知道真正提供服務的人是誰,客戶端請求的服務都被代理服務器處理。反向代理代理的是響應方,也就是服務端;我們請求www.baidu.com時這www.baidu.com就是反向代理服務器,真實提供服務的服務器有很多臺,反向代理服務器會把我們的請求分轉發到真實提供
服務的各臺服務器。Nginx就是性能非常好的反向代理服務器,用來做負載均衡。訪問www.baidu.com是正向代理的過程

反向代理中,proxy和server同屬一個LAN

正向代理和反向代理對比示意圖兩者的區別在于代理的對象不一樣:
正向代理中代理的對象是客戶端,proxy和client同屬一個LAN,對server透明;反向代理中代理的對象是服務端,proxy和server同屬一個LAN,對client透明。

26/87

27/87

nginx proxy

1、代理模塊 ngx_http_proxy_module

2、代理配置

代理
Syntax: proxy_pass URL; #代理的后端服務器URL

Default:    —

Context:    location, if in location, limit_except

緩沖區

Syntax: proxy_buffering on | off;
Default:    proxy_buffering on; #緩沖開關

Context:    http, server, location

proxy_buffering開啟的情況下,nignx會把后端返回的內容先放到緩沖區當中,然后再返回給客戶端(邊收邊傳,不是全部接收完再傳給客戶端)。

Syntax: proxy_buffer_size size;
Default:    proxy_buffer_size 4k|8k;    #緩沖區大小
Context:    http, server, location  
Syntax: proxy_buffers number size;  
Default:    proxy_buffers 8 4k|8k;  #緩沖區數量
Context:    http, server, location  
Syntax: proxy_busy_buffers_size size;  
Default:    proxy_busy_buffers_size 8k|16k;#忙碌的緩沖區大小控制同時傳遞給客戶端的buffer數量
Context:    http, server, location

頭信息

Syntax: proxy_set_header field value;

Default: proxy_set_header Host $proxy_host; #設置真實客戶端地址 proxy_set_header Connection close;
Context:    http, server, location

超時

Syntax: proxy_connect_timeout time;
Default:    proxy_connect_timeout 60s;  #鏈接超時

Context:    http, server, location

Syntax: proxy_read_timeout time;

Default:    proxy_read_timeout 60s;

Context:    http, server, location

3、啟用 nginx proxy 代理

環境兩臺nginx真實服務器a、nginx-1 啟動網站(內容)(作為網站服務器)
nginx-1的ip:10.0.105.199:已經編譯安裝好,檢查nginx是否啟動是否可以訪問b、nginx-2 啟動代理程序nginx-2的ip:10.0.105.202配置nginx的yum源直接yum安裝啟動編輯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 :真實服務器的地址,可以是ip也可以是域名和url地址 proxy_redirect :如果真實服務器使用的是的真實IP:非默認端口。則改成IP:默認端口。proxy_set_header:重新定義或者添加發往后端服務器的請求頭
proxy_set_header X-Real-IP :啟用客戶端真實地址(否則日志中顯示的是代理在訪問網站) proxy_set_header X-Forwarded-For:記錄代理地址

proxy_connect_timeout::后端服務器連接的超時時間發起三次握手等候響應超時時間proxy_send_timeout:后端服務器數據回傳時間就是在規定時間之內后端服務器必須傳完所有的數據 proxy_read_timeout :nginx接收upstream(上游/真實) server數據超時, 默認60s, 如果連續的60s內沒有收到
1個字節, 連接關閉。像長連接

proxy_buffering on;開啟緩存proxy_buffer_size:proxy_buffer_size只是響應頭的緩沖區 proxy_buffers 4 128k; 內容緩沖區域大小
proxy_busy_buffers_size 256k; 從proxy_buffers劃出一部分緩沖區來專門向客戶端傳送數據的地方 proxy_max_temp_file_size 256k;超大的響應頭存儲成文件。

注意:

29/87

  1. proxy_set_header X-Real-IP
    未配置
    Nginxbackend 的日志:記錄只有192.168.107.112
    配置
    Nginxbackend 的日志,記錄的有192.168.107.16 192.168.107.107 192.168.107.112

2.proxy_pass http:// 填寫nginx-1服務器的地址。

d、 使用PC客戶端訪問nginx-2服務器地址 瀏覽器中輸入http://10.0.105.202 (也可以是nginx-2服務器的域名)成功訪問nginx-1服務器頁面

e、 觀察nginx-1服務器的日志
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 代理服務器地址 10.0.105.207 客戶機地址。

訪問成功。 記錄了客戶機的IP和代理服務器的IP

30/87

擴展1

nginx 負載均衡

隨著網站、應用訪問量的增加,一臺服務器已經不能滿足應用的需求,而需要多臺服務器集群,這時就會用到負載均衡

upstream標簽

負載均衡配置: upstream testapp {

server 10.0.105.199:8081; server 10.0.105.202:8081;

}

server {

....

location / {
proxy_pass http://testapp; #請求轉向 testapp 定義的服務器列表

}

upstream mysvr {

server http://10.0.105.199:8081; server http://10.0.105.202:8081;

}

server {

....

location / {
proxy_pass http://mysvr; #請求轉向mysvr 定義的服務器列表

}

負載均衡算法

upstream 支持4種負載均衡調度算法: A、輪詢(默認):每個請求按時間順序逐一分配到不同的后端服務器;
B、ip_hash:每個請求按訪問IP的hash結果分配,同一個IP客戶端固定訪問一個后端服務器。可以保證來自同一ip的請求被打到固定的機器上,可以解決session問題。C、url_hash:按訪問url的hash結果來分配請求,使每個url定向到同一個后端服務器。
D、fair:這是比上面兩個更加智能的負載均衡算法。按后端服務器的響應時間來分配請求,響應時間短的優先分配。Nginx本身是不支持 fair的,如果需要使用這種調度算法,必須下載Nginx的 upstream_fair模塊。

2、配置實例
1)、熱備:如果你有2臺服務器,當一臺服務器發生事故時,才啟用第二臺服務器給提供服務。服務器處理請求的順序:AAAAAA突然A掛啦,BBBBBBBBBBBBBB.....
upstream myweb {

server 172.17.14.2:8080;

31/87

server 172.17.14.3:8080 backup; #熱備

}
2)、輪詢:nginx默認就是輪詢其權重都默認為1,服務器處理請求的順序:ABABABABAB....

upstream myweb {

server 172.17.14.2:8080; server 172.17.14.3:8080;

}
3)、加權輪詢:跟據配置的權重的大小而分發給不同服務器不同數量的請求。如果不設置,則默認為1。下
面服務器的請求順序為:ABBABBABBABBABB....
upstream myweb {

server 172.17.14.2:8080 weight=1; server 172.17.14.3:8080 weight=2;

}

4、ip_hash:nginx會讓相同的客戶端ip請求相同的服務器。 upstream myweb {
server 172.17.14.2:8080; server 172.17.14.3:8080; ip_hash;

}

5)、nginx負載均衡配置狀態參數

?down,表示當前的server暫時不參與負載均衡。

?backup,預留的備份機器。當其他所有的非backup機器出現故障或者忙的時候,才會請求backup機器,因此這臺機器的壓力最輕。

?max_fails,允許請求失敗的次數,默認為1。當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤。

?fail_timeout,在經歷了max_fails次失敗后,暫停服務的時間單位秒。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+端口的負載均衡;七層就是基于URL等應用層信息的負載均衡。

所謂的四層、七層負載均衡,就是在對后臺的服務器進行負載均衡時,依據四層的信息或七層的信息來決定怎么樣轉發流量。

七層負載均衡:準備三臺機器:

一臺代理服務器兩臺WEB服務器

配置代理服務器的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

}

}

}

四層負載均衡(練習)
nginx在1.9.0的時候,增加了一個 stream 模塊,用來實現四層協議(網絡層和傳輸層)的轉發、代

理、負載均衡等。stream模塊的用法跟http的用法類似,允許我們配置一組TCP或者UDP等協議的監聽,然后通過proxy_pass來轉發我們的請求,通過upstream添加多個后端服務,實現負載均衡。

#4層tcp負載 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會話保持

nginx會話保持主要有以下幾種實現方式。

1、ip_hash ip_hash使用源地址哈希算法,將同一客戶端的請求總是發往同一個后端服務器,除非該服務器不可用。

ip_hash語法:

upstream backend { ip_hash;

server backend1.example.com; server backend2.example.com; server backend3.example.com down;

}

注意:

ip_hash簡單易用,但有如下問題:當后端服務器宕機后,session會丟失;
來自同一局域網的客戶端會被轉發到同一個后端服務器,可能導致負載失衡;

2.sticky_cookie_insert

使用sticky_cookie_insert啟用會話親緣關系,這會導致來自同一客戶端的請求被傳遞到一組服務器的同一臺服務器。與ip_hash不同之處在于,它不是基于IP來判斷客戶端的,而是基于cookie來判斷。因此可以避

34/87

免上述ip_hash中來自同一局域網的客戶端和前段代理導致負載失衡的情況。(需要引入第三方模塊才能實現 sticky)

下載地址:https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/08a395c66e42.zip

下載后進行編譯安裝語法: upstream backend {

server backend1.example.com; server backend2.example.com;

sticky_cookie_insert srv_id expires=1h domain=3evip.cn path=/;

}

expires:設置瀏覽器中保持cookie的時間domain:定義cookie的域path:為cookie定義路徑

nginx動靜分離

為了加快網站的解析速度,可以把動態頁面和靜態頁面由不同的服務器來解析,加快解析速度。降低

原來單個服務器的壓力。 在動靜分離的tomcat的時候比較明顯,因為tomcat解析靜態很慢,其實這些原理的話都很好理解,簡單來說,就是使用正則表達式匹配過濾,然后交個不同的服務器。

靜態分離部署

一:實驗環境
準備一個nginx代理 兩個http 分別處理動態和靜態。

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

#動態資源加載 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

}
#靜態資源加載

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.單獨的靜態配置 server {
listen 80;

server_name localhost;

location ~ .(html|jpg|png|js|css|gif|bmp|jpeg) { root /home/www/nginx;

}

}

3.動態資源配置:

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; #指定網站目錄
fastcgi_pass    127.0.0.1:9000; #指定訪問地址
fastcgi_index index.php;    #指定默認文件
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #站點根目錄,取決于root配
置項
include fastcgi_params; #包含nginx常量定義

}

}

nginx 防盜鏈

兩個網站 A 和 B, A網站引用了B網站上的圖片,這種行為就叫做盜鏈。 防盜鏈,就是要防止A引用B的圖片。

36/87

防盜鏈部署

1、nginx 防止網站資源被盜用模塊 ngx_http_referer_module

HTTP Referer是Header的一部分,當瀏覽器向Web服務器發送請求的時候,一般會帶上Referer,告訴服務器我是從哪個頁面鏈接過來的,服務器借此可以獲得一些信息用于處理,例如防止未經允許的網站盜鏈

圖片、文件等。因此HTTP Referer頭信息是可以通過程序來偽裝生成的,所以通過Referer信息防盜鏈并非100%可靠,但是,它能夠限制大部分的盜鏈情況.

  1. 防盜鏈配置

[root@nginx-server ~]# vim /etc/nginx/nginx.conf

日志格式添加"$http_referer"

log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';

3.實戰演練

準備兩臺機器,一張圖片配置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 : 允許沒有http_refer的請求訪問資源;

?blocked : 允許不是http://開頭的,不帶協議的請求訪問資源---被防火墻過濾掉的;
?server_names : 只允許指定ip/域名來的請求訪問資源(白名單);
重載nginx服務
[root@nginx-server ~]# nginx -s reload -c /etc/nginx/nginx.conf

qf.com ----192.168.1.11 制作localhost本地解析。配置nginx訪問頁面創建頁面

[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>

測試不帶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

測試帶非法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

測試帶合法的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

如果用戶直接在瀏覽器輸入你的圖片地址,那么圖片顯示正常,因為它符合none這個規則。

nginx的rewrite

Rewirte

1、什么是Rewrite
Rewrite對稱URL Rewrite,即URL重寫,就是把傳入Web的請求重定向到其他URL的過程。
? URL Rewrite最常見的應用是URL偽靜態化,是將動態頁面顯示為靜態頁面方式的一種技術。比如http:// www.123.com/news/index.php?id=123 使用URLRewrite 轉換后可以顯示為 https://cache.yisu.com/upload/information/20200217/33/1992.jpg)
$request_uri    當前請求的文件路徑名(不帶網站的主目錄/images/a.jpg)
$query_string   與$args相同;
$scheme 用的協議,比如http或者是https
$server_protocol    請求的協議版本,"HTTP/1.0"或"HTTP/1.1";
$server_addr    服務器地址,如果沒有用listen指明服務器地址,使用這個變量將發起一次系統調用以
取得地址(造成資源浪費);
$server_name    請求到達的服務器名;

$document_uri   與$uri一樣,URI地址;

39/87

$server_port    請求到達的服務器端口號;

Rewrite flag

rewrite 指令根據表達式來重定向URI,或者修改字符串。可以應用于server,location, if環境下每行rewrite指令最后跟一個flag標記,支持的flag標記有:

last    相當于Apache里的[L]標記,表示完成rewrite。默認為last。
break   本條規則匹配完成后,終止匹配,不再匹配后面的規則
redirect    返回302臨時重定向,瀏覽器地址會顯示跳轉后的URL地址
permanent   返回301永久重定向,瀏覽器地址會顯示跳轉后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:

http://www.testpm.com/2019/a/1.html ==> http://www.testpm.com/2018/a/1.html location /2019/a {

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:

http://www.qf.com/a/1.html ==> http://jd.com location /a {

root    /html;

if ($host ~* testpm.com ) {

rewrite .* http://jd.com permanent;

}

40/87

}

例4:

http://www.qf.com/a/1.html ==> http://jd.com/a/1.html location /a {

root /html;

if ( $host ~* testpm.com ){

rewrite .* http://jd.com$request_uri permanent;

}

}

例5: 在訪問目錄后添加/ (如果目錄后已有/,則不加/)

#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:

http://www.tianyun.com/login/tianyun.html ==> http://www.tianyun.com/reg/login.html?user=tianyun location /login {

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 指令是用于定義一個變量,并且賦值

應用環境: server,location,if

應用示例:例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實現泛解析

  • IN  A   網站IP
    或者本地解析域名host文件
    10.0.105.202 www.testpm.com

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 指令用于返回狀態碼給客戶端 server,location,if

應用示例:

例9:如果訪問的.sh結尾的文件則返回403操作拒絕錯誤 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轉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 標記在本條 rewrite 規則執行完后,會對其所在的 server { … } 標簽重新發起請求;

?break 標記則在本條規則匹配完成后,停止匹配,不再做后續的匹配;

?使用 alias 指令時,必須使用 last;

?使用 proxy_pass 指令時,則必須使用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;

}

}

Settings for a TLS enabled server.

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 配置主要包括三個區塊,結構如下:

http {  # 這個是協議級別

include mime.types;

45/87

default_type application/octet-stream; keepalive_timeout 65;

gzip on; server { # 這個是服務器級別

listen 80; server_name localhost;

location / { # 這個是請求級別 root html;
index index.html index.htm;

}

}

}

1、location 區段
?location 是在 server 塊中配置,根據不同的 URI 使用不同的配置,來處理不同的請求。
?location 是有順序的,會被第一個匹配的location 處理。

基本語法如下: location [=|~|~*|^~|@] pattern{……}

2、location 前綴含義
=表示精確匹配,優先級也是最高的
^~ 表示uri以某個常規字符串開頭,理解為匹配url路徑即可 ~ 表示區分大小寫的正則匹配 ~ 表示不區分大小寫的正則匹配 !~ 表示區分大小寫不匹配的正則 !~ 表示不區分大小寫不匹配的正則 / 通用匹配,任何請求都會匹配到

@內部服務跳轉

3、location 配置示例本地解析域名host
1)、沒有修飾符 表示:必須以指定模式開始

server {

listen 80; server_name qf.com;

location /abc {

root    /home/www/nginx;

index   2.html;

}

那么,如下是對的: http://qf.com/abc http://qf.com/abc?p1 http://qf.com/abc/

如下是錯的 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;

}

}

那么,如下是對的: http://qf.com/abc http://qf.com/abc?p1 http://qf.com/abc/

http://qf.com/abcde

3)、~ 表示:指定的正則表達式要區分大小寫 server {
server_name qf.com; location ~ ^/abc$ {

……

}

}

那么,如下是對的: 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)、~ 表示:指定的正則表達式不區分大小寫 server {
server_name qf.com; location ~
^/abc$ {

……

}

}

那么,如下是對的: http://qf.com/abc http://qf..com/ABC http://qf..com/abc?p1=11&p2=22

如下是錯的: http://qf..com/abc/ http://qf..com/abcde

5)、^~ :類似于無修飾符的行為,也是以指定模式開始,不同的是,如果模式匹配,那么就停止搜索其他模式了6)、@ :定義命名 location 區段,這些區段客戶段不能訪問,只可以由內部產生的請求來訪問,如try_files

或error_page等

查找順序和優先級1:帶有“=“的精確匹配優先2:沒有修飾符的精確匹配
3:正則表達式按照他們在配置文件中定義的順序
4:帶有“^~”修飾符的,開頭匹配
5:帶有“~” 或“~*” 修飾符的,如果正則表達式與URI匹配

6:沒有修飾符的,如果指定字符串與URI開頭匹配

= 大于 ^~ 大于 ~|~|!~|!~ 大于 /
多個location配置的情況下匹配順序為:首先匹配 =,其次匹配^~, 其次是按正則匹配,最后是交給 / 通用匹配。當有匹配成功時候,停止匹配,按當前匹配規則處理請求。

(1)=:表示完全匹配;

(2)^~:匹配URI的前綴,并且后面的正則表達式不再匹配,如果一個URI同時滿足兩個規則的話,匹配最長的規則;

47/87

(3)~:匹配正則表達式,大小寫敏感;

(4)~*:匹配正則表達式,大小寫不敏感;優先級:(1)> (2) > (3) = (4)

localtion匹配段

location 區段匹配示例

location = / {

只匹配 / 的查詢. [ configuration A ]

}

location / {

匹配任何以 / 開始的查詢,但是正則表達式與一些較長的字符串將被首先匹配。

[ configuration B ]

}

location ^~ /images/ {

匹配任何以 /images/ 開始的查詢并且停止搜索,不檢查正則表達式。

[ configuration C ]

}

location ~* .(gif|jpg|jpeg)$ {

匹配任何以gif, jpg, or jpeg結尾的文件,但是所有 /images/ 目錄的請求將在Configuration C中處理。 [ configuration D ]

}
各請求的處理如下例:
/ → configuration A /documents/document.html → configuration B /images/1.gif → configuration C /documents/1.jpg → configuration D

root 、alias 指令區別

root 、alias 指令區別

location /img/ {

alias /var/www/image/;

}

#若按照上述配置的話,則訪問/img/目錄里面的文件時,ningx會自動去/var/www/image/目錄找文件 location /img/ {
root /var/www/image;

}

#若按照這種配置的話,則訪問/img/目錄下的文件時,nginx會去/var/www/image/img/目錄下找文件。

? alias 是一個目錄別名的定義,

48/87

?root 則是最上層目錄的定義。

?還有一個重要的區別是alias后面必須要用“/”結束,否則會找不到文件的,而root則可有可無

nginx 日志配置

nginx 日志介紹
nginx 有一個非常靈活的日志記錄模式,每個級別的配置可以有各自獨立的訪問日志, 所需日志模塊
ngx_http_log_module 的支持,日志格式通過 log_format 命令來定義,日志對于統計和排錯是非常有利的,下面總結了 nginx 日志相關的配置 包括 access_log、log_format、open_log_file_cache、rewrite_log、error_log。

總結:

Nginx中通過access_log和error_log指令配置訪問日志和錯誤日志,通過log_format我們可以自定義日志格式。如果日志文件路徑中使用了變量,我們可以通過open_log_file_cache 指令來設置緩存,提升性能。其他的根據自己的使用場景定義。詳細的日志配置信息可以參考Nginx官方文檔

access.log

設置訪問日志 access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

#關閉訪問日志 access_log off;

?path 指定日志的存放位置。
?format 指定日志的格式。默認使用預定義的combined。
?buffer 用來指定日志寫入時的緩存大小。默認是64k。

?gzip 日志寫入前先進行壓縮。壓縮率可以指定,從1到9數值越大壓縮比越高,同時壓縮的速度也越慢。默認是1。
?flush 設置緩存的有效時間。如果超過flush指定的時間,緩存中的內容將被清空。
?if 條件判斷。如果指定的條件計算為0或空字符串,那么該請求不會寫入日志。

作用域:

可以應用access_log指令的作用域分別有http,server,location,limit_except。也就是說,在這幾個作用域外使用該指令,Nginx會報錯。

access_log /var/logs/nginx-access.log

該例子指定日志的寫入路徑為/var/logs/nginx-access.log,日志格式使用默認的combined。 access_log /var/logs/nginx-access.log buffer=32k gzip flush=1m

49/87

該例子指定日志的寫入路徑為/var/logs/nginx-access.log,日志格式使用默認的combined,指定日志的緩存大小為 32k,日志寫入前啟用 gzip 進行壓縮,壓縮比使用默認值 1,緩存數據有效時間為1分鐘。

3、log_format 指令

Nginx 預定義了名為 combined 日志格式,如果沒有明確指定日志格式默認使用該格式:

log_format combined '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"';

如果不想使用Nginx預定義的格式,可以通過log_format指令來自定義。語法:

log_format name [escape=default|json] string ...;

?name 格式名稱。在 access_log 指令中引用。

?escape 設置變量中的字符編碼方式是json還是default,默認是default。
?string 要定義的日志格式內容。該參數可以有多個。參數中可以使用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指令定義了一個main的格式,并在access_log指令中引用了它。假如客戶端有發起請求:https://qf.com/,我們看一下我截取的一個請求的日志記錄:
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都對應了一個-,這是因為這幾個變量為空。

error.log

錯誤日志在Nginx中是通過error_log指令實現的。該指令記錄服務器和請求處理過程中的錯誤信息。

語法
配置錯誤日志文件的路徑和日志級別

error_log file [level]; Default:

error_log logs/error.log error;

file 參數指定日志的寫入位置。
level 參數指定日志的級別。level可以是debug, info, notice, warn, error, crit, alert,emerg中的任意值。可
以看到其取值范圍是按緊急程度從低到高排列的。只有日志的錯誤級別等于或高于level指定的值才會寫入錯誤日志中。默認值是error。

基本用法:

error_log /var/logs/nginx/nginx-error.log

配置段:main, http, mail, stream, server, location作用域。
例子中指定了錯誤日志的路徑為:/var/logs/nginx/nginx-error.log,日志級別使用默認的 error。

50/87

open_log_file_cache

open_log_file_cache 指令

每一條日志記錄的寫入都是先打開文件再寫入記錄,然后關閉日志文件。如果你的日志文件路徑中使用了變量,如 access_log /var/logs/$host/nginx-access.log,為提高性能,可以使用open_log_file_cache指令設置日志文件描述符的緩存。

語法:

open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];

默認值:

open_log_file_cache off;

?max 設置緩存中最多容納的文件描述符數量,如果被占滿,采用LRU算法將描述符關閉。

?inactive 設置緩存存活時間,默認是10s。
?min_uses 在inactive時間段內,日志文件最少使用幾次,該日志文件描述符記入緩存,默認是1次。

?valid:設置多久對日志文件名進行檢查,看是否發生變化,默認是60s。
?off:不使用緩存。默認為off。

open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2; 配置段:http、server、location作用域中。
例子中,設置緩存最多緩存1000個日志文件描述符,20s內如果緩存中的日志文件描述符至少被被訪問2次,才不會被緩存關閉。每隔1分鐘檢查緩存中的文件描述符的文件名是否還存在。

rewrite.log

rewrite_log 指令

由ngx_http_rewrite_module模塊提供的。用來記錄重寫日志的。對于調試重寫規則建議開啟,啟用時將在error log中記錄notice級別的重寫日志。

基本語法: rewrite_log on | off;

默認值: rewrite_log off;

配置段: http, server, location, if作用域。

nginx的日志輪轉

[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 {  #指定需要輪轉處理的日志文件
daily   #日志文件輪轉周期,可用值為: daily/weekly/yearly
missingok   # 忽略錯誤信息
rotate 7    # 輪轉次數,即最多存儲7個歸檔日志,會刪除最久的歸檔日志
minsize 5M  #限制條件,大于5M的日志文件才進行分割,否則不操作
dateext # 以當前日期作為命名格式
compress    # 輪循結束后,已歸檔日志使用gzip進行壓縮
delaycompress   # 與compress共用,最近的一次歸檔不要壓縮
notifempty  # 日志文件為空,輪循不會繼續執行
create 640 nginx nginx  #新日志文件的權限
sharedscripts   #有多個日志需要輪詢時,只執行一次腳本
postrotate  # 將日志文件轉儲后執行的命令。以endscript結尾,命令需要單獨成行
if [ -f /var/run/nginx.pid ]; then #判斷nginx的PID。# 默認logrotate會以root身份運行 kill -USR1 cat /var/run/nginx.pid
fi endscript

}
執行命令:

[root@192 nginx]# /usr/sbin/logrotate -f /etc/logrotate.conf
創建計劃任務:

[root@192 nginx]# crontab -e

59 23 * /usr/sbin/logrotate -f /etc/logrotate.conf

企業實戰(面試)

nginx access log 分析

nginx 的 access log 中可以記錄很多有價值的信息,通過分析 access log,可以收集到很多指標1.制作nginx的日志切割,每天凌晨切割并壓縮。
PV:PV(訪問量): 即Page View, 即頁面瀏覽量或點擊量,用戶每次刷新即被計算一次。
UV:UV(獨立訪客):即Unique Visitor,訪問您網站的一臺電腦客戶端為一個訪客。00:00-24:00內相同的客戶端只被計算一次。
面試:
1.根據訪問IP統計UV awk '{print $1}' access.log|sort | uniq -c |wc -l 2.統計訪問URL統計PV
awk '{print $7}' access.log|wc -l 3.查詢訪問最頻繁的URL
awk '{print $7}' access.log|sort | uniq -c |sort -n -k 1 -r|more 4.查詢訪問最頻繁的IP awk '{print $1}' access.log|sort | uniq -c |sort -n -k 1 -r|more 5.查詢訪問最頻繁的前10的IP

awk '{print $1}' access.log|sort | uniq -c |sort -n -k 1 -r|head -n 10

nginx 的平滑升級(了解)

1、為什么要對 nginx 平滑升級
隨著 nginx 越來越流行,并且 nginx 的優勢也越來越明顯,nginx 的版本迭代也來時加速模式,1.9.0版本的nginx更新了許多新功能,例如 stream 四層代理功能,伴隨著 nginx 的廣泛應用,版本升級必然越來越快,線上業務不能停,此時 nginx 的升級就是運維的工作了。

52/87

nginx 方便地幫助我們實現了平滑升級。其原理簡單概括,就是:(1)在不停掉老進程的情況下,啟動新進程。
(2)老進程負責處理仍然沒有處理完的請求,但不再接受處理請求。(3)新進程接受新請求。
(4)老進程處理完所有請求,關閉所有連接后,停止。 這樣就很方便地實現了平滑升級。一般有兩種情況下需要升級 nginx,一種是確實要升級 nginx 的版本,另一種是要為 nginx 添加新的模塊。

2、nginx 平滑升級原理多進程模式下的請求分配方式

nginx 默認工作在多進程模式下,即主進程(master process)啟動后完成配置加載和端口綁定等動作,fork出指定數量的工作進程(worker process),這些子進程會持有監聽端口的文件描述符(fd),并通
過在該描述符上添加監聽事件來接受連接(accept)。信號的接收和處理

nginx 主進程在啟動完成后會進入等待狀態,負責響應各類系統消息,如SIGCHLD、SIGHUP、SIGUSR2等。

Nginx信號簡介:主進程支持的信號
?TERM, INT: 立刻退出
?QUIT: 等待工作進程結束后再退出
?KILL: 強制終止進程

?HUP: 重新加載配置文件,使用新的配置啟動工作進程,并逐步關閉舊進程。
?USR1: 重新打開日志文件

?USR2: 啟動新的主進程,實現熱升級
?WINCH: 逐步關閉工作進程

工作進程支持的信號
?TERM, INT: 立刻退出

?QUIT: 等待請求處理結束后再退出
?USR1: 重新打開日志文件

nginx 平滑升級實戰1

1、查看現有的 nginx 編譯參數
[root@nginx-server ~]# cd /usr/local/nginx/sbin/nginx -V

2、按照原來的編譯參數安裝 nginx 的方法進行安裝,只需要到 make,千萬不要 make install 。如果make install 會將原來的配置文件覆蓋

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 二進制文件備份二進制文件和 nginx 的配置文件(期間nginx不會停止服務)
[root@nginx-server nginx-1.16.0]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_$(date +%F)

4、復制新的nginx二進制文件,進入新的nginx源碼包

[root@nginx-server nginx-1.16.0]# cp /usr/local/nginx-1.16.0/objs/nginx /usr/local/nginx/sbin/

5、測試新版本的nginx是否正常

[root@nginx-server nginx-1.16.0]# /usr/local/nginx/sbin/nginx -t

6、給nginx發送平滑遷移信號(若不清楚pid路徑,請查看nginx配置文件)

[root@nginx-server ~]# kill -USR2 cat /var/run/nginx.pid(老版本進稱號)

7、查看nginx pid,會出現一個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、從容關閉舊的Nginx進程

[root@nginx-server ~]# kill -WINCH cat /var/run/nginx.pid.oldbin

9、此時不重載配置啟動舊的工作進程

[root@nginx-server ~]# kill -HUP cat /var/run/nginx.pid.oldbin

10、結束工作進程,完成此次升級

[root@nginx-server ~]# kill -QUIT cat /var/run/nginx.pid.oldbin

11、驗證Nginx是否升級成功

[root@nginx-server ~]# /usr/local/nginx/sbin/nginx -V

nginx 平滑升級實戰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、訪問驗證

[root@localhost nginx-1.6.3]# elinks 10.0.105.189

4、升級nginx:將 nginx 版本進行升級 并在不影響業務的情況下添加 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錯誤界面配置

nginx錯誤頁面包括404 403 500 502 503 504等頁面,只需要在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這個文件!!!

404.html上如果引用其他文件的png或css就會有問題,顯示不出來,因為其他文件的訪問也要做配置; 為了簡單,可以將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">哎呀,找不到該頁面啦!</p>

<p id="tips">請檢查您的網絡連接是否正常或者輸入的網址是否正確</p> </div>

</div>

</div>

</div>

</body>

</html>

nginx流量控制

流量限制 (rate-limiting),是Nginx中一個非常實用,卻經常被錯誤理解和錯誤配置的功能。我們可以用來限制用戶在給定時間內HTTP請求的數量。請求,可以是一個簡單網站首頁的GET請求,也可以是登錄表單的 POST 請求。流量限制可以用作安全目的,比如可以減慢暴力密碼破解的速率。通過將傳入請求的速

率限制為真實用戶的典型值,并標識目標URL地址(通過日志),還可以用來抵御 DDOS ***。更常見的情況,該功能被用來保護上游應用服務器不被同時太多用戶請求所壓垮。

1、Nginx如何限流
Nginx的”流量限制”使用漏桶算法(leaky bucket algorithm),該算法在通訊和分組交換計算機網絡中廣泛使用,用以處理帶寬有限時的突發情況。就好比,一個桶口在倒水,桶底在漏水的水桶。如果桶口倒水的速率大于桶底的漏水速率,桶里面的水將會溢出;同樣,在請求處理方面,水代表來自客戶端的請求,水

桶代表根據”先進先出調度算法”(FIFO)等待被處理的請求隊列,桶底漏出的水代表離開緩沖區被服務器處理的請求,桶口溢出的水代表被丟棄和不被處理的請求。

2、配置基本的限流

“流量限制”配置兩個主要的指令,limit_req_zone和limit_req,如下所示: limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;

limit_req_zone指令設置流量限制和共享內存區域的參數,但實際上并不限制請求速率。所以需要通過添加limit_req指令,將流量限制應用在特定的location或者server塊。在上面示例中,我們對/login/請求進行流量限制。現在每個IP地址被限制為每秒只能請求10次/login/,更準確地說,在前一個請求的100毫秒內不能請求該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配置(真實的WEB服務器): server {
listen 80; server_name localhost; location /login {

root /usr/share/nginx/html; index index.html index.html;

}

58/87

}

limit_req_zone指令定義了流量限制相關的參數,而limit_req指令在出現的上下文中啟用流量限制(示例中,對于”/login/”的所有請求)。
limit_req_zone指令通常在HTTP塊中定義,使其可在多個上下文中使用,它需要以下三個參數:

? Key - 定義應用限制的請求特性。示例中的 Nginx 變量$binary_remote_addr,保存客戶端IP地址的二進制形

式。這意味著,我們可以將每個不同的IP地址限制到,通過第三個參數設置的請求速率。(使用該變量是因為比字符串形式的客戶端IP地址$remote_addr,占用更少的空間)

? Zone - 定義用于存儲每個IP地址狀態以及被限制請求URL訪問頻率的共享內存區域。保存在內存共享區域的信息,意味著可以在Nginx的worker進程之間共享。定義分為兩個部分:通過zone=keyword標識區域的名
字,以及冒號后面跟區域大小。16000個IP地址的狀態信息,大約需要1MB,所以示例中區域可以存儲
160000個IP地址。

? Rate - 定義最大請求速率。在示例中,速率不能超過每秒10個請求。Nginx實際上以毫秒的粒度來跟蹤請

求,所以速率限制相當于每100毫秒1個請求。因為不允許”突發情況”(見下一章節),這意味著在前一個請求100毫秒內到達的請求將被拒絕。(1秒(s)=1000毫秒(ms))

處理突發

如果我們在100毫秒內接收到2個請求,怎么辦?對于第二個請求,Nginx將給客戶端返回狀態碼503。這可能并不是我們想要的結果,因為應用本質上趨向于突發性。相反地,我們希望緩沖任何超額的請求,然后及時地處理它們。我們更新下配置,在limit_req中使用burst參數:

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參數定義了超出zone指定速率的情況下(示例中的mylimit區域,速率限制在每秒10個請求,或每100毫秒一個請求),客戶端還能發起多少請求。上一個請求100毫秒內到達的請求將會被放入隊列,我們將隊列大小設置為20。

59/87

這意味著,如果從一個給定IP地址發送21個請求,Nginx會立即將第一個請求發送到上游服務器群,然

后將余下20個請求放在隊列中。然后每100毫秒轉發一個排隊的請求,只有當傳入請求使隊列中排隊的請求數超過20時,Nginx才會向客戶端返回503。

nginx流量限制(高級)

通過將基本的“流量限制”與其他Nginx功能配合使用,我們可以實現更細粒度的流量限制。

1、白名單

下面這個例子將展示,如何對任何不在白名單內的請求強制執行“流量限制”: 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;

}

這個例子同時使用了geo和map指令。geo塊將給在白名單中的IP地址對應的$limit變量分配一個值0,給其它不在白名單中的分配一個值1。然后我們使用一個映射將這些值轉為key,如下:
?如果$limit變量的值是0,$limit_key變量將被賦值為空字符串

?如果$limit變量的值是1,$limit_key變量將被賦值為客戶端二進制形式的IP地址

兩個指令配合使用,白名單內IP地址的$limit_key變量被賦值為空字符串,不在白名單內的被賦值為客戶端的IP地址。當limit_req_zone后的第一個參數是空字符串時,不會應用“流量限制”,所以白名單內的IP地
址(10.0.0.0/24和192.168.0.0/24 網段內)不會被限制。其它所有IP地址都會被限制到每秒5個請求。limit_req
指令將限制應用到/的location塊,允許在配置的限制上最多超過10個數據包的突發,并且不會延遲轉發。

60/87

流量控制相關功能

1、配置日志記錄
默認情況下,Nginx會在日志中記錄由于流量限制而延遲或丟棄的請求,如下所示:
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 - 表明日志條目記錄的是被“流量限制”請求

?excess - 每毫秒超過對應“流量限制”配置的請求數量
?zone - 定義實施“流量限制”的區域
?client - 發起請求的客戶端IP地址
?server - 服務器IP地址或主機名
?request - 客戶端發起的實際HTTP請求
?host - HTTP報頭中host的值

默認情況下,Nginx以error級別來記錄被拒絕的請求,如上面示例中的[error]所示(Ngin以較低級別記錄延時請求,一般是info級別)。如要更改Nginx的日志記錄級別,需要使用limit_req_log_level指令。這里,我
們將被拒絕請求的日志記錄級別設置為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、發送到客戶端的錯誤代碼

一般情況下,客戶端超過配置的流量限制時,Nginx響應狀態碼為503(Service Temporarily Unavailable)。可以使用limit_req_status指令來設置為其它狀態碼(例如下面的404狀態碼): 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訪問控制

1、nginx 訪問控制模塊(1)基于IP的訪問控制:http_access_module
(2)基于用戶的信任登錄:http_auth_basic_module

基于IP的訪問控制

2、基于IP的訪問控制
1)、配置語法
Syntax:allow address | CIDR | unix: | all; default:默認無Context:http,server,location,limit_except

Syntax:deny address | CIDR | unix: | all; default:默認無Context:http,server,location,limit_except

3、配置測試
修改/etc/nginx/conf.d/access_mod.conf內容如下: server {
listen 80; server_name localhost; location ~ ^/admin {

root /home/www/html; index index.html index.hml; deny 192.168.1.8;

allow all;

}

}
#需要注意:
如果先允許訪問,在定義拒絕訪問。那么拒絕訪問不生效。

虛擬機宿主機IP為192.168.1.8,虛擬機IP為192.168.1.11,故這里禁止宿主機訪問,允許其他所有IP訪

62/87

問。 宿主機訪問http://192.168.1.11/admin,顯示403 Forbidden。 當然也可以反向配置,同時也可以使用IP

網段的配置方式,如allow 192.168.1.0/24;,表示滿足此網段的IP都可以訪問。

4、指定location拒絕所有請求

如果你想拒絕某個指定URL地址的所有請求,而不是僅僅對其限速,只需要在location塊中配置deny all指令:

server {

listen 80; server_name localhost; location /foo.html {

root /home/www/html; deny all;

}

}

基于用戶的信任登錄

1、配置語法
Syntax:auth_basic string | off;
default:auth_basic off;
Context:http,server,location,limit_except

Syntax:auth_basic_user_file file; default:默認無Context:http,server,location,limit_except

file:存儲用戶名密碼信息的文件。

2、配置示例

配置auth_mod.conf,內容如下: 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,開啟登錄驗證功能,auth_basic_user_file加載賬號密碼文件。

3、建立口令文件
[root@192 ~]# yum install -y httpd-tools

#htpasswd 是開源 http 服務器 apache httpd 的一個命令工具,用于生成 http 基本認證的密碼文件 [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、訪問測試

63/87

5、局限性

(1)用戶信息依賴文件方式(2)操作管理機械,效率低下

6、解決方法
(1)Nginx結合LUA實現高效驗證(2)Nginx和LDAP打通,利用nginx-auth-ldap模塊
(3)Nginx只做中間代理,具體認證交給應用。

nginx變量(了解)

nginx變量簡介:
?所有的 Nginx變量在 Nginx 配置文件中引用時都須帶上 $ 前綴

?在 Nginx 配置中,變量只能存放一種類型的值,有且也只存在一種類型,那就是字符串類型
?nginx可以使用變量簡化配置與提高配置的靈活性,所有的變量值都可以通過這種方式引用:

64/87

nginx 變量的定義和使用:nginx中的變量分為兩種,自定義變量與內置預定義變量
1、自定義變量
可以在sever,http,location等標簽中使用set命令(非唯一)聲明變量,語法如下 set $變量名 變量值注意:

?nginx 中的變量必須都以$開頭

?nginx 的配置文件中所有使用的變量都必須是聲明過的,否則 nginx 會無法啟動并打印相關異常日志

nginx安裝echo模塊

一:安裝部署查看已經安裝的nginx的版本

[root@192 ~]# nginx -V

上傳或者下載一個相同版本的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/
添加上原來已經有的參數和新添加的模塊:

[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 否則會覆蓋原來的文件 [root@192 nginx-1.16.0]# mv /usr/sbin/nginx /usr/sbin/nginx_bak #將原來的nignx備份 [root@192 nginx-1.16.0]# cp objs/nginx /usr/sbin/ 拷貝nignx
[root@192 nginx-1.16.0]# systemctl restart nginx #啟動

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

使用大括號插值

在“變量插值”的上下文中,還有一種特殊情況,即當引用的變量名之后緊跟著變量名的構成字符時(比如后跟字母、數字以及下劃線),我們就需要使用特別的記法來消除歧義,例如:

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

這里,我們在 echo 配置指令的參數值中引用變量 first 的時候,后面緊跟著 world 這個單詞,所以如果直接寫作 "firstworld" 則 Nginx “變量插值”計算引擎會將之識別為引用了變量 firstworld. 為了解決這個難題,Nginx 的字符串記法支持使用花括號在 之后把變量名圍起來,比如這里的 ${first}。

內置預定義變量

內置預定義變量即無需聲明就可以使用的變量,通常包括一個http請求或響應中一部分內容的值,以下為一些常用的內置預定義變量

67/87

$arg_PARAMETER  GET請求中變量名PARAMETER參數的值。
$args   這個變量等于GET請求中的參數。例如,foo=123&bar=blahblah;這個變量只
可以被修改

$binary_remote_addr 二進制碼形式的客戶端地址。
$body_bytes_sent    傳送頁面的字節數
$content_length 請求頭中的Content-length字段。
$content_type   請求頭中的Content-Type字段。
$cookie_COOKIE  cookie COOKIE的值。
$document_root  當前請求在root指令中指定的值。
$document_uri   與$uri相同。
$host   請求中的主機頭(Host)字段,如果請求中的主機頭不可用或者空,則為處理
請求的server名稱(處理請求的server的server_name指令的值)。值為小寫,不
包含端口。

$hostname   機器名使用 gethostname系統調用的值
$httpHEADER    HTTP請求頭中的內容,HEADER為HTTP請求中的內容轉為小寫,-變為(破折
號變為下劃線),例如:$http_user_agent(Uaer-Agent的值);
$sent_httpHEADER   HTTP響應頭中的內容,HEADER為HTTP響應中的內容轉為小寫,-變為(破折
號變為下劃線),例如: $sent_http_cache_control, $sent_http_content_type…;
$is_args    如果$args設置,值為"?",否則為""。
$limit_rate 這個變量可以限制連接速率。
$nginx_version  當前運行的nginx版本號。
$query_string   與$args相同。
$remote_addr    客戶端的IP地址。
$remote_port    客戶端的端口。
$remote_user    已經經過Auth Basic Module驗證的用戶名。
$request_filename   當前連接請求的文件路徑,由root或alias指令與URI請求生成。
$request_body   這個變量(0.7.58+)包含請求的主要信息。在使用proxy_pass或fastcgi_pass
指令的location中比較有意義。
$request_body_file  客戶端請求主體信息的臨時文件名。
$request_completion 如果請求成功,設為"OK";如果請求未完成或者不是一系列請求中最后一部
分則設為空。

$request_method 這個變量是客戶端請求的動作,通常為GET或POST。包括0.8.20及之前的版
本中,這個變量總為main request中的動作,如果當前請求是一個子請求,并
不使用這個當前請求的動作。

$request_uri    這個變量等于包含一些客戶端請求參數的原始URI,它無法修改,請查看$uri
更改或重寫URI。
$scheme 所用的協議,比如http或者是https,比如rewrite ^(.+)$ $scheme://
example.com$1 redirect;
$server_addr    服務器地址,在完成一次系統調用后可以確定這個值,如果要繞開系統調
用,則必須在listen中指定地址并且使用bind參數。
$server_name    服務器名稱。
$server_port    請求到達服務器的端口號。
$server_protocol    請求使用的協議,通常是HTTP/1.0或HTTP/1.1。
變量名 定義

68/87

$uri    請求中的當前URI(不帶請求參數,參數位于args),不同于瀏覽器傳遞
的args),不同于瀏覽器傳遞的args),不同于瀏覽器傳遞的request_uri
的值,它可以通過內部重定向,或者使用index指令進行修改。不包括協議和主機名,例如/foo/bar.html
變量名 定義

uri vs request_uri

由 ngx_http_core 模塊提供的內建變量 uri,可以用來獲取當前請求的 URI(不含請求參數), 而 request_uri 則用來獲取請求最原始的 URI (包含請求參數)。

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

另一個特別常用的內建變量其實并不是單獨一個變量,而是有無限多變種的一群變量,即名字以 arg_ 開頭的所有變量,我們估且稱之為 arg_XXX 變量群。

一個例子是 arg_name,這個變量的值是當前請求中名為 name 的參數的值,而且還是未解碼的原始形式的值。

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 不區分大小寫

其實 $arg_name 不僅可以匹配 name 參數,也可以匹配 NAME 參數,抑或是 Name,Nginx 會在匹配參數名之前,自動把原始請求中的參數名調整為全部小寫的形式。

[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 監控

1、nginx的基礎監控
?進程監控

?端口監控

注意: 這兩個是必須要加在zabbix監控,加觸發器有問題及時告警。 web 服務器 nginx 以其高性能與抗并發能力越來越多的被用戶使用
nginx 提供了 ngx_http_stub_status_module,ngx_http_reqstat_module模塊,這個模塊提供了基本的監控功能

2、監控的主要指標
1)、基本活躍指標Accepts(接受)、Handled(已處理)、Requests(請求數)是一直在增加的計數器。
Active(活躍)、Waiting(等待)、Reading(讀)、Writing(寫)隨著請求量而增減。

70/87

名稱  描述  指標類型

Accepts(接受) NGINX 所接受的客戶端連接數    資源: 功能
Handled(已處理)    成功的客戶端連接數   資源: 功能
Dropped(已丟棄,計算得出)   丟棄的連接數(接受 - 已處理)    工作:錯誤*
Requests(請求數)   客戶端請求數  工作:吞吐量

2)、每秒請求數 -- QPS 通過持續的 QPS 監控,可以立刻發現是否被惡意***或對服務的可用性進行評估。雖然當問題發生
時,通過 QPS 不能定位到確切問題的位置,但是他卻可以在第一時間提醒你環境可能出問題了。

3)、請求處理時間請求處理時間也可以被記錄在 access log 中,通過分析 access log,統計請求的平均響應時間,通過持
續觀察,可以發現上游服務器的問題

3、指標的收集通過在編譯時加入 nginx 的 ngx_http_stub_status_module 模塊我們可以實時監控以下基本的指標:

1)、nginx Stub Status 監控模塊安裝
先使用命令查看是否已經安裝這個模塊:

-V大寫會顯示版本號和模塊等信息、v小寫僅顯示版本信息

[root@localhost ~]# nginx -V
如果沒有此模塊,需要重新安裝,編譯命令如下:
./configure –with-http_stub_status_module 具體的使用方法是在執行 ./configure 時,指定 --with-http_stub_status_module,然后通過配置: server {

listen 80; server_name localhost; location /nginx-status {

stub_status on;

access_log  on;

}

}
nginx 狀態查看

配置完成后在瀏覽器中輸入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   #當前nginx處理請求的數目(活躍的連接數)  
server  accepts   handled   requests    26  26  48
nginx總共處理了26個連接,成功創建26次握手,也就是成功的連接數connection. 總共處理了48個請求
失敗連接=(總連接數-成功連接數)(相等表示中間沒有失敗的), Reading : nginx讀取到客戶端的Header信息數。請求頭 -----速度快。 Writing :nginx返回給客戶端的Header信息數。響應頭
Waiting :開啟keep-alive的情況下,意思就是Nginx說已經處理完正在等候下一次請求指令的駐留連接。
#可以nginx有多少的長連接。相當于空閑的。可以把超時時間改的短一點。 ---------監控的對象通常,一個連接在同一時間只接受一個請求。在這種情況下,Active 連接的數目 == Waiting 的連接 + Reading 請求 + Writing

71/87

HTTPS

https簡介

HTTPS(全稱:HyperText Transfer Protocol over Secure Socket Layer),其實 HTTPS 并不是一個新鮮協議,Google 很早就開始啟用了,初衷是為了保證數據安全。 近些年,Google、Baidu、Facebook 等這樣的互
聯網巨頭,不謀而合地開始大力推行 HTTPS, 國內外的大型互聯網公司很多也都已經啟用了全站 HTTPS,這也是未來互聯網發展的趨勢。

一、加密算法

1:對稱加密 : A要給B發送數據
1,A做一個對稱密鑰 2,使用密鑰給文件加密 3,發送加密以后的文件和鑰匙 4,B拿鑰匙解密加密和解密都是使用的同一個密鑰。

2:非對稱加密 ---- 公鑰加密,私鑰解密 :A要給B發送數據
1.B做一對非對稱的密鑰
2.發送公鑰給A
3.A拿公鑰對數據進行加密
4.發送加密后的數據給B
5.B拿私鑰解密

3.哈希算法
將任意長度的信息轉換為較短的固定長度的值,通常其長度要比信息小得多。

例如:MD5、SHA-1、SHA-2、SHA-256 等

4.數字簽名

簽名就是在信息的后面再加上一段內容(信息經過hash后的值),可以證明信息沒有被修改過。hash值一般都會加密后(也就是簽名)再和信息一起發送,以保證這個hash值不被修改。

72/87

二:HTTPS 協議介紹

? HTTP 協議(HyperText Transfer Protocol,超文本傳輸協議):是客戶端瀏覽器或其他程序與Web服務器之

間的應用層通信協議 。
? HTTPS 協議(HyperText Transfer Protocol over Secure Socket Layer):可以理解為HTTP+SSL/TLS, 即

HTTP 下加入 SSL 層,HTTPS 的安全基礎是 SSL,因此加密的詳細內容就需要 SSL,用于安全的 HTTP 數據傳輸。

HTTPS 相比 HTTP 多了一層 SSL/TLS

SSL/TLS :SSL(Secure Sockets Layer 安全套接層),及其繼任者傳輸層安全(Transport Layer Security,TLS)是為網絡通信提供安全及數據完整性的一種安全協議。TLS與SSL在傳輸層為數據通訊進行加密提供安
全支持。

SSL協議可分為兩層:

SSL握手協議(SSL Handshake Protocol):它建立在SSL記錄協議之上,用于在實際的數據傳輸開始前,通訊雙方進行身份認證、協商加密算法、交換加密密鑰等。相當于連接

SSL記錄協議(SSL Record Protocol):它建立在可靠的傳輸協議(如TCP)之上,為高層協議提供數據封裝、壓縮、加密等基本功能的支持。 相當于通信

SSL協議提供的服務主要有:ssl:身份認證和數據加密。保證數據完整性1)認證用戶和服務器,確保數據發送到正確的客戶機和服務器;2)加密數據以防止數據中途被竊取;3)維護數據的完整性,確保數據在傳輸過程中不被改變。

https工作原理

HTTP請求過程中,客戶端與服務器之間沒有任何身份確認的過程,數據全部明文傳輸,“裸奔”在互聯網上,所以很容易遭到***的***。

客戶端發出的請求很容易被***截獲,如果此時***冒充服務器,則其可返回任意信息給客戶端,而不被客戶端察覺。

HTTP 傳輸面臨的風險有:

73/87

?竊聽風險:***可以獲知通信內容。

?篡改風險:***可以修改通信內容。

?冒充風險:***可以冒充他人身份參與通信。

那有沒有一種方式既可以安全的獲取公鑰,又能防止***冒充呢? 那就需要用到終極武器了:SSL 證書(申購)
?證書:.crt, .pem
?私鑰:.key
?證書請求文件:.csr

服務器發送了一個SSL證書給客戶端,SSL 證書中包含的具體內容有:(1)證書的發布機構CA
(2)證書的有效期(3)公鑰(4)證書所有者

(5)簽名 -----  簽名就可以理解為是鈔票里面的一個防偽標簽。

客戶端在接受到服務端發來的SSL證書時,會對證書的真偽進行校驗,以瀏覽器為例說明如下:(1)首先瀏覽器讀取證書中的證書所有者、有效期等信息進行一一校驗
(2)瀏覽器開始查找操作系統中已內置的受信任的證書發布機構CA,與服務器發來的證書中的頒發者CA比對,用于校驗證書是否為合法機構頒發
(3)如果找不到,瀏覽器就會報錯,說明服務器發來的證書是不可信任的。
(4)如果找到,那么瀏覽器就會從操作系統中取出 頒發者CA 的公鑰,然后對服務器發來的證書里面的簽名進行解密

(5)瀏覽器使用相同的hash算法計算出服務器發來的證書的hash值,將這個計算的hash值與證書中簽名做對比

(6)對比結果一致,則證明服務器發來的證書合法,沒有被冒充
(7)此時瀏覽器就可以讀取證書中的公鑰,用于后續加密了
(8)client與web協商對稱加密算法,client生成對稱加密密鑰并使用web公鑰加密,發送給web服務器,web服務器使用web私鑰解密
(9)使用對稱加密密鑰傳輸數據,并校驗數據的完整性

所以通過發送SSL證書的形式,既解決了公鑰獲取問題,又解決了***冒充問題,一箭雙雕,HTTPS加密過程也就此形成

相比HTTP,HTTPS 傳輸更加安全(1) 所有信息都是加密傳播,***無法竊聽。
(2) 具有校驗機制,一旦被篡改,通信雙方會立刻發現。(3) 配備身份證書,防止身份被冒充。

HTTPS 缺點:
1.SSL 證書費用很高,以及其在服務器上的部署、更新維護非常繁瑣
2.HTTPS 降低用戶訪問速度(多次握手)
3.網站改用HTTPS 以后,由HTTP 跳轉到 HTTPS 的方式增加了用戶訪問耗時(多數網站采用302跳轉)

4.HTTPS 涉及到的安全算法會消耗 CPU 資源,需要增加大量機器(https訪問過程需要加解密)

74/87

#國家;match表示申請者的申請信息必須與此一致
#州、省
#組織名、公司名
75/87

= match = match
= match

構建私有的 CA 機構

CA中心申請證書的流程:過程:
1。web服務器,生成一對非對稱加密密鑰(web公鑰,web私鑰)
2。web服務器使用 web私鑰 生成 web服務器的證書請求,并將證書請求發給CA服務器3。CA服務器使用 CA的私鑰 對 web 服務器的證書請求 進行數字簽名得到 web服務器的數字證書,并將web服務器的數字證書頒發給web服務器。
4。client訪問web服務器,請求https連接,下載web數字證書
5。client下載 CA數字證書(CA身份信息+CA公鑰,由上一級CA頒發,也可自簽名頒發),驗證 web數字證書(CA數字證書中有CA公鑰,web數字證書是使用CA私鑰簽名的)

1、CA 介紹
CA(Certificate Authority)證書頒發機構主要負責證書的頒發、管理以及歸檔和吊銷。證書內包含了擁
有證書者的姓名、地址、電子郵件帳號、公鑰、證書有效期、發放證書的CA、CA的數字簽名等信息。證書主要有三大功能:加密、簽名、身份驗證。

2、構建私有 CA 檢查安裝 openssl,如果未安裝
[root@https-ca ~]# rpm -qa openssl

[root@https-ca ~]# yum install openssl openssl-devel
查看配置文件
openssl 配置/etc/pki/tls/openssl.cnf有關CA的配置。如果服務器為證書簽署者的身份那么就會用到此配
置文件,此配置文件對于證書申請者是無作用的。

[root@https-ca ~]# vim /etc/pki/tls/openssl.cnf

####################################################################

[ ca ]

default_ca  = CA_default    # 默認的CA配置;CA_default指向下面配置塊

####################################################################

[ CA_default ]      
dir = /etc/pki/CA       # CA的默認工作目錄
certs   = $dir/certs        # 認證證書的目錄
crl_dir = $dir/crl  # 證書吊銷列表的路徑
database    = $dir/index.txt        # 數據庫的索引文件
new_certs_dir  = $dir/newcerts  # 新頒發證書的默認路徑
certificate = $dir/cacert.pem       # 此服務認證證書,如果此服務器為根CA那么這里為自頒發證書
serial  = $dir/serial       # 下一個證書的證書編號
crlnumber   = $dir/crlnumber    # 下一個吊銷的證書編號
crl = $dir/crl.pem      # The current CRL
private_key = $dir/private/cakey.pem# CA的私鑰
RANDFILE    = $dir/private/.rand   # 隨機數文件
x509_extensions = usr_cert      # The extentions to add to the cert
name_opt    = ca_default        # 命名方式,以ca_default定義為準
cert_opt    = ca_default        # 證書參數,以ca_default定義為準
default_days   = 365        # 證書默認有效期
default_crl_days= 30        # CRl的有效期
default_md  = sha256        # 加密算法
preserve    = no        # keep passed DN ordering
policy  = policy_match      #policy_match策略生效

For the CA policy [ policy_match ] countryName stateOrProvinceName organizationName

organizationalUnitName = optional   #部門名稱;optional表示申請者可以的信息與此可以不一致

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、根證書服務器目錄

根CA服務器:因為只有 CA 服務器的角色,所以用到的目錄只有/etc/pki/CA網站服務器:只是證書申請者的角色,所以用到的目錄只有/etc/pki/tls

4、創建所需要的文件

[root@https-ca ~]# cd /etc/pki/CA/ [root@https-ca CA]# ls

certs crl newcerts private

[root@https-ca CA]# touch index.txt #創建生成證書索引數據庫文件 [root@https-ca CA]# ls
certs crl index.txt newcerts private

[root@https-ca CA]# echo 01 > serial #指定第一個頒發證書的序列號 [root@https-ca CA]# ls
certs crl index.txt newcerts private serial [root@https-ca CA]#

5、創建密鑰

在根CA服務器上創建密鑰,密鑰的位置必須為/etc/pki/CA/private/cakey.pem,這個是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、生成自簽名證書

根CA自簽名證書,根CA是最頂級的認證機構,沒有人能夠認證他,所以只能自己認證自己生成自簽名證書。

[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:   生成新證書簽署請求
-x509:  專用于CA生成自簽證書

-key: 生成請求時用到的私鑰文件 -days n: 證書的有效期限
-out /PATH/TO/SOMECERTFILE:  證書的保存路徑

7、下載安裝證書/etc/pki/CA/cacert.pem就是生成的自簽名證書文件,使用 SZ/xftp工具將他導出到窗口機器中。然后雙
擊安裝此證書到受信任的根證書頒發機構. [root@https-ca CA]# yum install -y lrzsz [root@https-ca CA]# sz cacert.pem

8、客戶端CA 證書申請及簽名安裝 openssl
[root@nginx-server ~]# yum install openssl openssl-devel
客戶端生成私鑰文件
[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]#
客戶端用私鑰加密生成證書請求
[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為后綴,是網站向CA發起認證請求的文件,是中間文件。

最后把生成的請求文件(/etc/pki/tls/www.qf.com.csr)傳輸給CA ,這里我使用scp命令,通過ssh協議,將該文件傳輸到CA下的/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 簽署證書

[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

=========================================================
注意:可能遇到的問題
[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)

因為默認使用/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

查看生成的證書的信息

[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

將生成的證書發放給請求客戶端

[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.測試:

nginx-client(充當服務端): [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

還是在這臺機器安裝nginx并且配置證書: 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; #指定證書路徑

ssl_certificate_key /etc/pki/tls/private/www.qf.com.key; #指定私鑰路徑 ssl_session_timeout 5m; #配置用于SSL會話的緩存
ssl_protocols SSLv2 SSLv3 TLSv1;    #指定使用的協議
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; # //密碼指定為OpenSSL支持的格式
ssl_prefer_server_ciphers   on; #設置協商加密算法時,優先使用服務端的加密,而不是客戶端瀏覽器
的。

location / {

root /usr/share/nginx/html; index index.html index.htm;

}

}
保存重啟
[root@localhost conf.d]# nginx -t [root@localhost conf.d]# nginx -s reload

瀏覽器測試訪問:

79/87

CA吊銷證書

1、知道客戶端吊銷的證書的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、吊銷證書
先根據客戶提交的serial與subject信息,對比檢驗是否與index.txt文件中的信息一致;然后
[root@https-ca ~]# openssl ca -revoke /etc/pki/CA/newcerts/01.pem

3、生成吊銷證書的編號第一次吊銷一個證書時才需要執行

[root@https-ca ~]# echo 01 > /etc/pki/CA/crlnumber

80/87

4、更新證書吊銷列表

[root@https-ca ~]# openssl ca -gencrl -out thisca.crl

5、查看證書吊銷列表

[root@https-ca ~]# openssl crl -in /root/thisca.crl -noout -text

nginx的https部署實戰

1.申請證書與認證

2.證書下載與配置

3.問題分析與總結

1、證書申請(具體上課操作演示)

2、域名驗證(具體上課操作演示)

3、證書下載與配置(具體上課操作演示)

[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;

}

}

性能優化

當我需要進行性能優化時,說明我們服務器無法滿足日益增長的業務。性能優化是一個比較大的課題,需要從以下幾個方面進行探討
?當前系統結構瓶頸

?了解業務模式

?性能與安全

1、當前系統結構瓶頸

首先需要了解的是當前系統瓶頸,用的是什么,跑的是什么業務。里面的服務是什么樣子,每個服務最大支持多少并發。比如針對nginx而言,我們處理靜態資源效率最高的瓶頸是多大?

可以通過查看當前cpu負荷,內存使用率,進程使用率來做簡單判斷。還可以通過操作系統的一些工

81/87

具來判斷當前系統性能瓶頸,如分析對應的日志,查看請求數量。也可以通過nginx http_stub_status_module模塊來查看對應的連接數,總握手次數,總請求數。也可以對線上進行壓力測試,來了解當前的系統能性能,并發數,做好性能評估。

2、了解業務模式

雖然我們是在做性能優化,但還是要熟悉業務,最終目的都是為業務服務的。我們要了解每一個接口業務類型是什么樣的業務,比如電子商務搶購模式,這種情況平時流量會很小,但是到了搶購時間,流量一下子就會猛漲。也要了解系統層級結構,每一層在中間層做的是代理還是動靜分離,還是后臺進行直接服務。需要我們對業務接入層和系統層次要有一個梳理

3、性能與安全

性能與安全也是一個需要考慮的因素,往往大家注重性能忽略安全或注重安全又忽略性能。比如說我們在設計防火墻時,如果規則過于全面肯定會對性能方面有影響。如果對性能過于注重在安全方面肯定會留下很大隱患。所以大家要評估好兩者的關系,把握好兩者的孰重孰輕,以及整體的相關性。權衡好對應的點。

4、系統與nginx性能優化

大家對相關的系統瓶頸及現狀有了一定的了解之后,就可以根據影響性能方面做一個全體的評估和優
化。
?網絡(網絡流量、是否有丟包,網絡的穩定性都會影響用戶請求)

?系統(系統負載、飽和、內存使用率、系統的穩定性、硬件磁盤是否有損壞)

?服務(連接優化、內核性能優化、http服務請求優化都可以在nginx中根據業務來進行設置)
?程序(接口性能、處理請求速度、每個程序的執行效率)

?數據庫、底層服務上面列舉出來每一級都會有關聯,也會影響整體性能,這里主要關注的是nginx服務這一層。

文件句柄

1、文件句柄

在linux/unix操作系統中一切皆文件,我們的設備是文件,文件是文件,文件夾也是文件。當我們用戶每發起一次請求,就會產生一個文件句柄。文件句柄可以簡單的理解為文件句柄就是一個索引。文件句柄

就會隨著請求量的增多,進程調用頻繁增加,那么產生的文件句柄也就會越多。

系統默認對文件句柄是有限制的,不可能會讓一個進程無限制的調用句柄。因為系統資源是有限的,所以我們需要限制每一個服務能夠使用多大的文件句柄。操作系統默認使用的文件句柄是1024個句柄。

2、設置方式
?系統全局性修改

?用戶局部性修改

?進程局部性修改

3、系統全局性修該和用戶局部性修改

[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只是針對root這個用戶來限制,soft只是發提醒,操作系統不會強制限制,一般的站點設置為一萬左右就ok了 root soft nofile 65535

root hard nofile 65535

*代表通配符 所有的用戶

*soft nofile 25535

*hard nofile 25535

注意:

82/87

可以看到root和,root代表是root用戶,代表的是所有用戶,后面的數字就是文件句柄大小。大家可以根據個人業務來進行設置。

4、進程局部性修改:worker_rlimit_nofile 是在進程上面進行限制。 [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; #進程限制

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對于不同的work工作進程綁定到不同的cpu上面去。就能夠減少在work間不斷
切換cpu,把進程通常不會在處理器之間頻繁遷移,進程遷移的頻率小,來減少性能損耗。 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核心數

83/87

[root@nginx-server ~]# cat /proc/cpuinfo|grep "cpu cores"|uniq
查看cpu使用率

[root@nginx-server ~]#top 回車后按 1

worker_processes

[root@nginx-server ~]# vim /etc/nginx/nginx.conf 將剛才查看到自己cpu * cpu核心就是worker_processes
worker_processes 2; #根據自己cpu核心數配置/這里也可以設置為auto

cpu

通過下面命令查看nginx進程配置在哪個核上

[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版本之后,就幫我們自動綁定了cpu; worker_cpu_affinity auto;

通用配置優化

#將nginx進程設置為普通用戶,為了安全考慮 user nginx;

#當前啟動的worker進程,官方建議是與系統核心數一致 worker_processes 2;
#方式一,就是自動分配綁定 worker_cpu_affinity auto;

#日志配置成warn error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid;

#針對 nginx 句柄的文件限制 worker_rlimit_nofile 35535;
#事件模型 events {
#使用epoll內核模型 user epoll;
#每一個進程可以處理多少個連接,如果是多核可以將連接數調高 worker_processes * 1024 worker_connections 10240;
}

http {

include /etc/nginx/mime.types;

84/87

default_type application/octet-stream;

charset utf-8; #設置字符集

#設置日志輸出格式,根據自己的情況設置 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; #如果做靜態資源服務器可以打開 #tcp_nodeny on; #當nginx做動態的服務時可以選擇打開

keepalive_timeout 65;

########

#Gzip module

gzip on; #文件壓縮默認可以打開 gzip_disable "MSIE [1-6]."; #對于有些瀏覽器不能識別壓縮,需要過濾如ie6 gzip_http_version 1.1;

include /etc/nginx/conf.d/*.conf;

}

壓力測試

ab壓力測試

ab是Apache超文本傳輸協議(HTTP)的性能測試工具。其設計意圖是描繪當前所安裝的Apache的執行性能,主要是顯示你安裝的Apache每秒可以處理多少個請求。

[root@nginx-server ~]# yum install httpd-tools [root@nginx-server ~]# ab -n 2000 -c 2 http://127.0.0.1/

-n 總的請求數 -c 并發數
-k 是否開啟長連接

參數解釋

85/87

-n:即requests,用于指定壓力測試總共的執行次數
-c:即concurrency,用于指定的并發數
-t:即timelimit,等待響應的最大時間(單位:秒) -b:即windowsize,TCP發送/接收的緩沖大小(單位:字節) -p:即postfile,發送POST請求時需要上傳的文件,此外還必須設置-T參數-u:即putfile,發送PUT請求時需要上傳的文件,此外還必須設置-T參數
-T:即content-type,用于設置Content-Type請求頭信息,例如:application/x-www-form-urlencoded,默認值為text/plain -v:即verbosity,指定打印幫助信息的冗余級別-w:以HTML表格形式打印結果

-i:使用HEAD請求代替GET請求

-x:插入字符串作為table標簽的屬性-y:插入字符串作為tr標簽的屬性-z:插入字符串作為td標簽的屬性
-C:添加cookie信息,例如:"Apache=1234"(可以重復該參數選項以添加多個)
-H:添加任意的請求頭,例如:"Accept-Encoding: gzip",請求頭將會添加在現有的多個請求頭之后(可以重復該參數選項以添加多個)
-A:添加一個基本的網絡認證信息,用戶名和密碼之間用英文冒號隔開
-P:添加一個基本的代理認證信息,用戶名和密碼之間用英文冒號隔開
-X:指定使用的和端口號,例如:"126.10.10.3:88"
-V:打印版本號并退出
-k:使用HTTP的KeepAlive特性
-d:不顯示百分比
-S:不顯示預估和警告信息-g:輸出結果信息到gnuplot格式的文件中
-e:輸出結果信息到CSV格式的文件中
-r:指定接收到錯誤信息時不退出程序-H:顯示用法信息,其實就是ab -help

內容解釋

Server Software:    nginx/1.10.2 (服務器軟件名稱及版本信息)
Server Hostname:    192.168.1.106(服務器主機名)
Server Port:    80 (服務器端口)

Document Path:  /index1.html. (供測試的URL路徑)

Document Length:    3721 bytes (供測試的URL返回的文檔大小)

Concurrency Level:  1000 (并發數)
Time taken for tests:   2.327 seconds (壓力測試消耗的總時間)
Complete requests:  5000 (的總次數)
Failed requests:    688 (失敗的請求數)
Write errors:   0 (網絡連接寫入錯誤數)
Total transferred:  17402975 bytes (傳輸的總數據量)
HTML transferred:   16275725 bytes (HTML文檔的總數據量)
Requests per second: 2148.98 [#/sec] (mean) (平均每秒的請求數) 這個是非常重要的參數數值,服務器的吞吐量

Time per request:   465.338 [ms] (mean) (所有并發用戶(這里是1000)都請求一次的平均時間)
Time    request:    0.247 [ms] (mean, across all concurrent requests) (單個用戶請求一次的平均時間)
Transfer rate:      7304.41 [Kbytes/sec] received 每秒獲取的數據長度 (傳輸速率,單位:KB/s)
...        
Percentage of the requests served within a certain time (ms)
50% 347 ## 50%的請求在347ms內返回
66% 401 ## 60%的請求在401ms內返回
75% 431    
80% 516    
90% 600    
95% 846    
98% 1571

86/87

99% 1593
100%    1619 (longest request)

87/87

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

敖汉旗| 嵩明县| 岢岚县| 麻阳| 神木县| 全州县| 平南县| 垣曲县| 临洮县| 驻马店市| 阳谷县| 鹰潭市| 义乌市| 永兴县| 河北区| 皮山县| 孟村| 莱芜市| 治县。| 宁陕县| 沿河| 塔河县| 淮阳县| 开阳县| 东乡| 无极县| 奉贤区| 兴化市| 社旗县| 东阿县| 永新县| 铜陵市| 四子王旗| 汉沽区| 探索| 道孚县| 宁德市| 密云县| 蓝山县| 环江| 福清市|