寫在前面
優化我們專案,服務器部署,不僅僅可以是分布式,Nginx一樣可以通過動靜分離,負載均衡來減輕我們服務器的壓力,Nginx的知識鏈,學習周期相對比較長,博主也是剛剛入門,這篇就先從實作基礎的動靜分離,再了解一下基礎概念與核心配置開始吧!
常見服務器對比
IIS
全稱(Internet Information Services)即互聯網資訊服務,是由微軟公司提供的基于windows系統的互聯網基本服務,windows作為服務器在穩定性與其他一些性能上都不如類UNIX作業系統,因此在需要高性能Web服務器的場合下,IIS可能就會被"冷落",
Tomcat
Tomcat是一個運行Servlet和JSP的Web應用軟體,Tomcat技術先進、性能穩定而且開放源代碼,因此深受Java愛好者的喜愛并得到了部分軟體開發商的認可,成為目前比較流行的Web應用服務器,但是Tomcat天生是一個重量級的Web服務器,對靜態檔案和高并發的處理比較弱,
Apache
Apache的發展時期很長,同時也有過一段輝煌的業績,從上圖可以看出大概在2014年以前都是市場份額第一的服務器,Apache有很多優點,如穩定、開源、跨平臺等,但是它出現的時間太久了,在它興起的年代,互聯網的產業規模遠遠不如今天,所以它被設計成一個重量級的、不支持高并發的Web服務器,在Apache服務器上,如果有數以萬計的并發HTTP請求同時訪問,就會導致服務器上消耗大量能存,作業系統內核對成百上千的Apache行程做行程間切換也會消耗大量的CUP資源,并導致HTTP請求的平均回應速度降低,這些都決定了Apache不可能成為高性能的Web服務器,這也促使了Lighttpd和Nginx的出現,
Lighttpd
Lighttpd是德國的一個開源的Web服務器軟體,它和Nginx一樣,都是輕量級、高性能的Web服務器,歐美的業界開發者比較鐘愛Lighttpd,而國內的公司更多的青睞Nginx,同時網上Nginx的資源要更豐富些,
其他的服務器
Google Servers,Weblogic, Webshpere(IBM)...
經過各個服務器的對比,種種跡象都表明,Nginx將以性能為王,這也是我們為什么選擇Nginx的理由,
?
Nginx的優點
?
(1)速度更快、并發更高
?
單次請求或者高并發請求的環境下,Nginx都會比其他Web服務器回應的速度更快,一方面在正常情況下,單次請求會得到更快的回應,另一方面,在高峰期(如有數以萬計的并發請求),Nginx比其他Web服務器更快的回應請求,Nginx之所以有這么高的并發處理能力和這么好的性能原因在于Nginx采用了多行程和I/O多路復用(epoll)的底層實作,
(2)配置簡單,擴展性強
Nginx的設計極具擴展性,它本身就是由很多模塊組成,這些模塊的使用可以通過組態檔的配置來添加,這些模塊有官方提供的也有第三方提供的模塊,如果需要完全可以開發服務自己業務特性的定制模塊,
(3)高可靠性
Nginx采用的是多行程模式運行,其中有一個master主行程和N多個worker行程,worker行程的數量我們可以手動設定,每個worker行程之間都是相互獨立提供服務,并且master主行程可以在某一個worker行程出錯時,快速去"拉起"新的worker行程提供服務,
(4)熱部署
現在互聯網專案都要求以7*24小時進行服務的提供,針對于這一要求,Nginx也提供了熱部署功能,即可以在Nginx不停止的情況下,對Nginx進行檔案升級、更新配置和更換日志檔案等功能,
(5)成本低、BSD許可證
BSD是一個開源的許可證,世界上的開源許可證有很多,現在比較流行的有六種分別是GPL、BSD、MIT、Mozilla、Apache、LGPL,這六種的區別是什么,我們可以通過下面一張圖來解釋下:
Nginx本身是開源的,我們不僅可以免費的將Nginx應用在商業領域,而且還可以在專案中直接修改Nginx的原始碼來定制自己的特殊要求,這些點也都是Nginx為什么能吸引無數開發者繼續為Nginx來貢獻自己的智慧和青春,OpenRestry [Nginx+Lua] Tengine[淘寶]
Nginx安裝與配置
直接通過一條命令來安裝相關環境
yum install -y gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
進行全部安裝,
wget
從官網中獲取下載地址,如 wget http://nginx.org/download/nginx-1.16.1.tar.gz
- 也可以自行下載然后上傳到服務器
tar -zxvf
建議直接安裝在/usr/local 中 , 檔案夾命名為nginx (后續操作會方便很多無需更改直接復用我的配置)
解壓你下載下來的壓縮包
***進入資源檔案中,發現configure,然后./configure
注意./configure的時候這樣設定就可以開啟SSL支持了
注意此處寫死了路徑為 /usr/local
所以可以安裝完更改一下nginx的安裝路徑為/usr/local/nginx
./configure --prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--modules-path=/usr/local/nginx/modules \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--error-log-path=/usr/local/nginx/logs/error.log \
--http-log-path=/usr/local/nginx/logs/access.log \
--pid-path=/usr/local/nginx/logs/nginx.pid \
--lock-path=/usr/local/nginx/logs/nginx.lock \
--with-http_ssl_module
make && make install
將nginx配置為環境變數
vi /etc/profil
然后添加
PATH=$PATH:/usr/local/nginx/sbin #此處對應為你的sbin目錄位置
export PATH
最后記得 source /etc/profile
重新加載環境
驗證一下 nginx -v
顯示如下就沒有問題了
nginx version: nginx/1.20.1
**最終完整配置(關于配置詳解見后文)
user root;
worker_processes auto;
error_log /usr/local/nginx/logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid /usr/local/nginx/logs/nginx.pid;
events {
use epoll;
worker_connections 1024;
multi_accept on;
accept_mutex on;
}
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;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 75;
#gzip on;
server {
#選擇要監聽的埠
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
再使用nginx -s reload重新讀取組態檔
發現報
nginx: [error] open() /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)錯誤,而且進到logs檔案發現沒有nginx.pid檔案
使用nginx -c的引數指定nginx.conf檔案的位置即可解決
nginx -c /usr/local/nginx/conf/nginx.conf
最后進入sbin目錄 , ./nginx即可開啟啦
記得先開啟80埠安全組,如果報錯地址已在使用,可能nginx已經啟動了
- 可以lsof -i :80看看是不是nginx在使用了
- 或者直接訪問 http://ip地址 看看是不是跳轉到nginx的首頁
至此,nginx的配置終于告一段落!
正向代理和反向代理
正向代理
正向代理,意思是一個位于客戶端和原始服務器(origin server)之間的服務器,為了從原始服務器取得內容,客戶端向代理發送一個請求并指定目標(原始服務器),然后代理向原始服務器轉交請求并將獲得的內容回傳給客戶端,
- 拿VPN舉個例子,我們大陸沒法直接訪問到美國的服務器,而香港可以
- 所以我們可以在客戶端和美國服務器之間加個中間商--香港服務器
- 讓我們的客戶端去請求香港服務器,然后香港服務器再幫我們去轉發到美國服務器
?
正向代理是為我們服務的,即為客戶端服務的,客戶端可以根據正向代理訪問到它本身無法訪問到的服務器資源,
正向代理對我們是透明的,對服務端是非透明的,即服務端并不知道自己收到的是來自代理的訪問還是來自真實客戶端的訪問,
反向代理
反向代理是為服務端服務的,反向代理可以幫助服務器接收來自客戶端的請求,幫助服務器做請求轉發,負載均衡等,
反向代理對服務端是透明的,對我們是非透明的,即我們并不知道自己訪問的是代理服務器,而服務器知道反向代理在為他服務,
?
反向代理的優勢:
- 隱藏真實服務器;
- 負載均衡便于橫向擴充后端動態服務;
- 動靜分離,提升系統健壯性;
?
動靜分離
一般來說,都需要將動態資源和靜態資源分開,由于 Nginx 的高并發和靜態資源快取等特性,經常將靜態資源部署在 Nginx 上,如果請求的是靜態資源,直接到靜態資源目錄獲取資源,如果是動態資源的請求,則利用反向代理的原理,把請求轉發給對應后臺應用去處理,從而實作動靜分離,
通俗來講什么是動靜分離?
- 動:后臺應用程式的業務處理
- 靜:網站的靜態資源(html,javaScript,css,images等檔案)
- 分離:將兩者進行分開部署訪問,提供用戶進行訪問,舉例說明就是以后所有和靜態資源相關的內容都交給Nginx來部署訪問,非靜態內容則交個類似于Tomcat的服務器來部署訪問,
為什么要動靜分離?
- 前面我們介紹過Nginx在處理靜態資源的時候,效率是非常高的,而且Nginx的并發訪問量也是名列前茅,而Tomcat則相對比較弱一些,所以把靜態資源交個Nginx后,可以減輕Tomcat服務器的訪問壓力并提高靜態資源的訪問速度,
- 動靜分離以后,降低了動態資源和靜態資源的耦合度,如動態資源宕機了也不影響靜態資源的展示,
假如某個時間點,由于某個原因導致Tomcat后的服務器宕機了,我們再次訪問Nginx,會得到如下效果,用戶還是能看到頁面,只是缺失了訪問次數的統計,這就是前后端耦合度降低的效果,并且整個請求只和后的服務器互動了一次,js和images都直接從Nginx回傳,提供了效率,降低了后的服務器的壓力,
如何實作動靜分離?
- 實作動靜分離的方式很多,比如靜態資源可以部署到CDN、Nginx等服務器上,動態資源可以部署到Tomcat,weblogic或者websphere上,我使用的是Nginx+Tomcat來實作動靜分離,
將war專案中的靜態資源洗掉掉,重新打包生成war包
自行新建一個目錄存放靜態資源
修改nginx.conf
修改后保存,然后nginx-s reload即可
server {
#監聽8081埠
listen 8081;
#服務器ip
server_name localhost;
#動態資源
location /demo {
proxy_pass localhostL:8082;
}
#靜態資源
location /demo-html {
root /usr/local/nginx/html/dist;
index index.html index.htm;
}
}
效果
當我們訪問 localhost:8081/demo/xxx , 就會去訪問Tomcat中埠號為8082專案的動態資源
這個一般是寫在前端的介面地址中的
而我們真正要在網頁訪問,只需要訪問 localhost:8081/demo-html/index.html 即可
就會去相應的靜態資源目錄中找
Nginx服務器啟停命令
默認多執行緒
?
核心組態檔結構
全域塊
user指令
(1)user:用于配置運行Nginx服務器的worker行程的用戶和用戶組,
| 語法 | USER USER [GROUP] |
|---|---|
| 默認值 | nobody |
| 位置 | 全域塊 |
該屬性也可以在編譯的時候指定,語法如下./configure --user=user --group=group,如果兩個地方都進行了設定,最終生效的是組態檔中的配置,
該指令的使用步驟:
(1)設定一個用戶資訊"www"
user www;
(2) 創建一個用戶
useradd www
(3)修改user屬性
user www
(4)創建/root/html/index.html頁面,添加如下內容
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
<p><em>I am WWW</em></p>
</body>
</html>
(5)修改nginx.conf
location / {
root /root/html;
index index.html index.htm;
}
?
(5)測驗啟動訪問
頁面會報403拒絕訪問的錯誤
?
(6)分析原因
因為當前用戶沒有訪問/root/html目錄的權限
?
(7)將檔案創建到 /home/www/html/index.html,修改配置
location / {
root /home/www/html;
index index.html index.htm;
}
(8)再次測驗啟動訪問
能正常訪問,
綜上所述,使用user指令可以指定啟動運行作業行程的用戶及用戶組,這樣對于系統的權限訪問控制的更加精細,也更加安全,
?
work process指令
master_process:用來指定是否開啟作業行程,
worker_processes:用于配置Nginx生成作業行程的數量,這個是Nginx服務器實作并發處理服務的關鍵所在,理論上來說workder process的值越大,可以支持的并發處理量也越多,但事實上這個值的設定是需要受到來自服務器自身的限制,建議將該值和服務器CPU的內核數保存一致,
rdc的服務器好像是用auto
| 語法 | WORKER_PROCESSES NUM/AUTO; |
|---|---|
| 默認值 | 1 |
| 位置 | 全域塊 |
如果將worker_processes設定成2,則會看到如下內容:
其他指令
daemon:設定Nginx是否以守護行程的方式啟動,
守護式行程是linux后臺執行的一種服務行程,特點是獨立于控制終端,不會隨著終端關閉而停止,
pid:用來配置Nginx當前master行程的行程號ID存盤的檔案路徑,
| 語法 | PID FILE; |
|---|---|
| 默認值 | 默認為:/usr/local/nginx/logs/nginx.pid |
| 位置 | 全域塊 |
該屬性可以通過./configure --pid-path=PATH來指定
error_log:用來配置Nginx的錯誤日志存放路徑
| 語法 | ERROR_LOG FILE [日志級別]; |
|---|---|
| 默認值 | error_log logs/error.log error; |
| 位置 | 全域塊、http、server、location |
該屬性可以通過./configure --error-log-path=PATH來指定
其中日志級別的值有:debug|info|notice|warn|error|crit|alert|emerg,翻譯過來為試|資訊|通知|警告|錯誤|臨界|警報|緊急,這塊建議大家設定的時候不要設定成info以下的等級,因為會帶來大量的磁盤I/O消耗,影響Nginx的性能,
include:用來引入其他組態檔,使Nginx的配置更加靈活
| 語法 | INCLUDE FILE; |
|---|---|
| 默認值 | 無 |
| 位置 | any |
events塊
(1)accept_mutex:用來設定Nginx網路連接序列化
這個配置主要可以用來解決常說的"驚群"問題,大致意思是在某一個時刻,客戶端發來一個請求連接,Nginx后臺是以多行程的作業模式,也就是說有多個worker行程會被同時喚醒,但是最終只會有一個行程可以獲取到連接,如果每次喚醒的行程數目太多,就會影響Nginx的整體性能,如果將上述值設定為on(開啟狀態),將會對多個Nginx行程接收連接進行序列號,一個個來喚醒接收,就防止了多個行程對連接的爭搶,
(2)multi_accept:用來設定是否允許同時接收多個網路連接
建議on,效率會高一點
如果multi_accept被禁止了,nginx一個作業行程只能同時接受一個新的連接,否則,一個作業行程可以同時接受所有的新連接
(3)worker_connections:用來配置單個worker行程最大的連接數
| 語法 | WORKER_CONNECTIONS NUMBER; |
|---|---|
| 默認值 | worker_commections 512; |
| 位置 | events |
這里的連接數不僅僅包括和前端用戶建立的連接數,而是包括所有可能的連接數,另外,number值不能大于作業系統支持打開的最大檔案句柄數量,
***(4)use:用來設定Nginx服務器選擇哪種事件驅動來處理網路訊息,
建議epoll
use epoll
| 語法 | USE METHOD; |
|---|---|
| 默認值 | 根據作業系統定 |
| 位置 | events |
注意:此處所選擇事件處理模型是Nginx優化部分的一個重要內容,method的可選值有select/poll/epoll/kqueue等,之前在準備centos環境的時候,我們強調過要使用linux內核在2.6以上,就是為了能使用epoll函式來優化Nginx,
?
另外這些值的選擇,我們也可以在編譯的時候使用
--with-select_module、--without-select_module、
--with-poll_module、--without-poll_module來設定是否需要將對應的事件驅動模塊編譯到Nginx的內核,
**events指令配置實體
打開Nginx的組態檔 nginx.conf,添加如下配置
events{
accept_mutex on;
multi_accept on;
worker_commections 1024;
use epoll;
}
啟動測驗
./nginx -t (測驗)
./nginx -s reload
其他配置指令
(1)sendfile:用來設定Nginx服務器是否使用sendfile()傳輸檔案,該屬性可以大大提高Nginx處理靜態資源的性能
(2)keepalive_timeout:用來設定長連接的超時時間,
為什么要使用keepalive?
我們都知道HTTP是一種無狀態協議,客戶端向服務端發送一個TCP請求,服務端回應完畢后斷開連接,
如何客戶端向服務端發送多個請求,每個請求都需要重新創建一次連接,效率相對來說比較多,使用keepalive模式,可以告訴服務器端在處理完一個請求后保持這個TCP連接的打開狀態,若接收到來自這個客戶端的其他請求,服務端就會利用這個未被關閉的連接,而不需要重新創建一個新連接,提升效率,但是這個連接也不能一直保持,這樣的話,連接如果過多,也會是服務端的性能下降,這個時候就需要我們進行設定其的超時時間,
| 語法 | KEEPALIVE_TIMEOUT TIME; |
|---|---|
| 默認值 | keepalive_timeout 75s; |
| 位置 | http、server、location |
(3)keepalive_requests:用來設定一個keep-alive連接使用的次數,
| 語法 | KEEPALIVE_REQUESTS NUMBER; |
|---|---|
| 默認值 | keepalive_requests 100; |
| 位置 | http、server、location |
靜態資源部署(root和index的含義)
root/alias
設定請求資源的目錄root / alias
root:設定請求的根目錄
| 語法 | root path; |
|---|---|
| 默認值 | root html; |
| 位置 | http、server、location |
?
path為Nginx服務器接收到請求以后查找資源的根目錄路徑,
?
alias:用來更改location的URI
| 語法 | alias path; |
|---|---|
| 默認值 | — |
| 位置 | location |
?
path為修改后的根路徑,
?
以上兩個指令都可以來指定訪問資源的路徑,那么這兩者之間的區別是什么?
?
舉例說明:
?
(1)在/usr/local/nginx/html目錄下創建一個 images目錄,并在目錄下放入一張圖片mv.png圖片
?
location /images {
root /usr/local/nginx/html;
}
?
訪問圖片的路徑為:
?
http://192.168.200.133/images/mv.png
?
(2)如果把root改為alias
?
location /images {
alias /usr/local/nginx/html;
}
?
再次訪問上述地址,頁面會出現404的錯誤,查看錯誤日志會發現是因為地址不對,所以驗證了:
?
*** root的處理結果是: root路徑+location路徑
/usr/local/nginx/html/images/mv.png
alias的處理結果是:使用alias路徑替換location路徑
/usr/local/nginx/html/mv.png
需要在alias后面路徑改為
?
location /images {
alias /usr/local/nginx/html/images;
}
?
(3)如果location路徑是以/結尾,則alias也必須是以/結尾,root沒有要求
?
將上述配置修改為
?
location /images/ {
alias /usr/local/nginx/html/images;
}
?
訪問就會出問題,查看錯誤日志還是路徑不對,所以需要把alias后面加上 /
?
小結:
?
root的處理結果是: root路徑+location路徑
alias的處理結果是:使用alias路徑替換location路徑
alias是一個目錄別名的定義,root則是最上層目錄的含義,
如果location路徑是以/結尾,則alias也必須是以/結尾,root沒有要求
?
index指令
index:設定網站的默認首頁
| 語法 | index file ...; |
|---|---|
| 默認值 | index index.html; |
| 位置 | http、server、location |
?
index后面可以跟多個設定,如果訪問的時候沒有指定具體訪問的資源,則會依次進行查找,找到第一個為止,
?
舉例說明:
?
location / {
root /usr/local/nginx/html;
index index.html index.htm;
}
訪問該location的時候,可以通過 http://ip:port/,地址后面如果不添加任何內容,則默認依次訪問index.html和index.htm,找到第一個來進行回傳
?
error_page指令
?
error_page:設定網站的錯誤頁面
| 語法 | error_page code ... [=[response]] uri; |
|---|---|
| 默認值 | — |
| 位置 | http、server、location...... |
?
當出現對應的回應code后,如何來處理,
?
舉例說明:
?
**(1)可以指定具體跳轉的地址
?
server {
error_page 404 http://www.itcast.cn;
}
?
(2)可以指定重定向地址
?
server{
error_page 404 /50x.html;
error_page 500 502 503 504 /50x.html;
location =/50x.html{
root html;
}
}
寫在最后
- 關于nginx的更多深入知識,負載均衡,快取,ReWrite等,本專欄會持續更進,在學到用到的時候第一時間跟大家分享分享,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/344034.html
標籤:架構設計
