靜態(tài)資源部署
Rewrite地址重寫
正則表達式
反向代理
負載均衡
輪詢、加權(quán)輪詢、ip_hash、url_hash、fair
Web緩存
環(huán)境部署
高可用的環(huán)境
用戶認證模塊…
nginx二進制可執(zhí)行文件
nginx.conf配置文件
error.log錯誤的日志記錄
access.log訪問日志記錄
一、Nginx核心配置文件結(jié)構(gòu)
首先我們來學習下,我們的配置文件,nginx,conf是最重要的一個配置文件,我們來看下最基本的配置文件中的內(nèi)容。
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
指令名 指令值; #全局塊,主要設置Nginx服務器整體運行的配置指令
#events塊,主要設置,Nginx服務器與用戶的網(wǎng)絡連接,這一部分對
Nginx服務器的性能影響較大
events {
指令名 指令值;
}
#http塊,是Nginx服務器配置中的重要部分,代理、緩存、日志記錄、
第三方模塊配置...
http {
指令名 指令值;
server { #server塊,是Nginx配置和虛擬主機相關的內(nèi)容
指令名 指令值;
location / {
#location塊,基于Nginx服務器接收請求字符串與
location后面的值進行匹配,對特定請求進行處理
指令名 指令值;
}
}
...
}
總結(jié)
全局塊、events塊、http塊。http塊中可以配置多個server塊,每個server塊又可以配置多個location塊。
1.全局塊
1.user指令
user:用于配置運行Nginx服務器的worker進程的用戶和用戶組
2.work process指令
master_process:用來指定是否開啟工作進程。worker_processes:用于配置Nginx生成工作進程的數(shù)量,這個是Nginx
服務器實現(xiàn)并發(fā)處理服務的關鍵所在。
3.daemon
=daemon:設定Nginx是否以守護進程的方式啟動。
4.pid
pid:用來配置Nginx當前master進程的進程號ID存儲的文件路徑。
5.error_log
6.include
include:用來引入其他配置文件,使Nginx的配置更加靈活
2.events塊
1.accept_mutex
accept_mutex:用來設置Nginx網(wǎng)絡連接序列化
2.multi_accept
multi_accept:用來設置是否允許同時接收多個網(wǎng)絡連接
3.worker_connections
worker_connections:用來配置單個worker進程最大的連接數(shù)
4.use
use:用來設置Nginx服務器選擇哪種事件驅(qū)動來處理網(wǎng)絡消息。.
3.http塊
1.定義MIME-Type
2.自定義服務日志
3.server塊和location塊
我們舉個例子就是,訪問如下路徑,并且配置conf文件,代碼如下
##全局塊 begin##
#配置允許運行Nginx工作進程的用戶和用戶組
user www;
#配置運行Nginx進程生成的worker進程數(shù)
worker_processes 2;
#配置Nginx服務器運行對錯誤日志存放的路徑
error_log logs/error.log;
#配置Nginx服務器允許時記錄Nginx的master進程的PID文件路徑和名
稱
pid logs/nginx.pid;
#配置Nginx服務是否以守護進程方法啟動
#daemon on;
##全局塊 end##
##events塊 begin##
events{
#設置Nginx網(wǎng)絡連接序列化
accept_mutex on;
#設置Nginx的worker進程是否可以同時接收多個請求
multi_accept on;
#設置Nginx的worker進程最大的連接數(shù)
worker_connections 1024;
#設置Nginx使用的事件驅(qū)動模型
use epoll;
}
##events塊 end##
##http塊 start##
http{
#定義MIME-Type
include mime.types;
default_type application/octet-stream;
#配置允許使用sendfile方式運輸
sendfile on;
#配置連接超時時間
keepalive_timeout 65;
#配置請求處理日志格式
log_format server1 '===>server1 access log';
log_format server2 '===>server2 access log';
##server塊 開始##
include /home/www/conf.d/*.conf;
##server塊 結(jié)束##
}
##http塊 end##
=server1.conf
server{
#配置監(jiān)聽端口和主機名稱
listen 8081;
server_name localhost;
#配置請求處理日志存放路徑
access_log
/home/www/myweb/server1/logs/access.log server1;
#配置錯誤頁面
error_page 404 /404.html;
#配置處理/server1/location1請求的location
location /server1/location1{
root /home/www/myweb;
index index_sr1_location1.html;
}
#配置處理/server1/location2請求的location
location /server1/location2{
root /home/www/myweb;
index index_sr1_location2.html;
}
#配置錯誤頁面轉(zhuǎn)向
location = /404.html {
root /home/www/myweb;
index 404.html;
}
}
server2.conf
server{
#配置監(jiān)聽端口和主機名稱
listen 8082;
server_name localhost;
#配置請求處理日志存放路徑
access_log
/home/www/myweb/server2/logs/access.log server2;
#配置錯誤頁面,對404.html做了定向配置
error_page 404 /404.html;
#配置處理/server1/location1請求的location
location /server2/location1{
root /home/www/myweb;
index index_sr2_location1.html;
}
#配置處理/server2/location2請求的location
location /server2/location2{
root /home/www/myweb;
index index_sr2_location2.html;
}
#配置錯誤頁面轉(zhuǎn)向
location = /404.html {
root /home/www/myweb;
index 404.html;
}
}
二、Nginx靜態(tài)資源部署
通過瀏覽器發(fā)送一個HTTP
請求實現(xiàn)從客戶端發(fā)送請求到服務器端獲取所需要內(nèi)容后并把內(nèi)容回顯
展示在頁面的一個過程。這個時候,我們所請 求的內(nèi)容就分為兩種類
型,一類是靜態(tài)資源、一類是動態(tài)資源。
靜態(tài)資源即指在服務器端真實
存在并且能直接拿來展示的一些文件,比如常見的html頁面、css文件、
js文件、圖 片、視頻等資源; 動態(tài)資源即指在服務器端真實存在但是要
想獲取需要經(jīng)過一定的業(yè)務邏輯處理,根據(jù)不同的條件展示在頁面不同
這 一部分內(nèi)容,比如說報表數(shù)據(jù)展示、根據(jù)當前登錄用戶展示相關具體
數(shù)據(jù)等資源;
(1)靜態(tài)資源的配置指令
(2)靜態(tài)資源的配置優(yōu)化
(3)靜態(tài)資源的壓縮配置指令
(4)靜態(tài)資源的緩存處理
(5)靜態(tài)資源的訪問控制,包括跨域問題和防盜鏈問題
Nginx靜態(tài)資源的配置指令
1.listen指令
listen:用來配置監(jiān)聽端口。
server{
listen 8080;
server_name 127.0.0.1;
location /{
root html;
index index.html;
}
}
server{
listen 8080 default_server;
server_name localhost;
default_type text/plain;
return 444 'This is a error request';
}
2.server_name指令
server_name:用來設置虛擬主機服務名稱。
配置方式一:精確匹配
server {
listen 80;
server_name www.itcast.cn www.itheima.cn;
...
}
.
配置方式二:使用通配符配置
server_name中支持通配符"*",但需要注意的是通配符不能出現(xiàn)在域名的
中間,只能出現(xiàn)在首段或尾段,如:
server {
listen 80;
server_name *.itcast.cn www.itheima.*;
# www.itcast.cn abc.itcast.cn www.itheima.cn
www.itheima.com
...
}
配置三:使用正則表達式配置
server_name中可以使用正則表達式,并且使用~作為正則表達式字符
串的開始標記。
server{
listen 80;
server_name ~^www\.(\w+)\.com$;
default_type text/plain;
return 200 $1 $2 ..;
}
匹配執(zhí)行順序
由于server_name指令支持通配符和正則表達式,因此在包含多個虛擬
主機的配置文件中,可能會出現(xiàn)一個名稱被多個虛擬主機的
server_name匹配成功,當遇到這種情況,當前的請求交給誰來處理
呢?
server{
listen 80;
server_name ~^www\.\w+\.com$;
default_type text/plain;
return 200 'regex_success';
}
server{
listen 80;
server_name www.itheima.*;
default_type text/plain;
return 200 'wildcard_after_success';
}
server{
listen 80;
server_name *.itheima.com;
default_type text/plain;
return 200 'wildcard_before_success';
}
server{
listen 80;
server_name www.itheima.com;
default_type text/plain;
return 200 'exact_success';
}
server{
listen 80 default_server;
server_name _;
default_type text/plain;
return 444 'default_server not found server';
}
3. location指令
server{
listen 80;
server_name localhost;
location / {
}
location /abc{
}
uri變量是待匹配的請求字符串,可以不包含正則表達式,也可以包含正
則表達式,那么nginx服務器在搜索匹配location的時候,是先使用不包
含正則表達式進行匹配,找到一個匹配度最高的一個,然后在通過包含
正則表達式的進行匹配,如果能匹配到直接訪問,匹配不到,就使用剛
才匹配度最高的那個location來處理請求。
不帶符號,要求必須以指定模式開始
server {
listen 80;
server_name 127.0.0.1;
location /abc{
default_type text/plain;
return 200 "access success";
}
}
以下訪問都是正確的
http://192.168.200.133/abc
http://192.168.200.133/abc?p1=TOM
http://192.168.200.133/abc/
http://192.168.200.133/abcdef
= : 用于不包含正則表達式的uri前,必須與指定的模式精確匹配
server {
listen 80;
server_name 127.0.0.1;
location =/abc{
default_type text/plain;
return 200 "access success";
}
}
可以匹配到
http://192.168.200.133/abc
http://192.168.200.133/abc?p1=TOM
匹配不到
http://192.168.200.133/abc/
http://192.168.200.133/abcdef
~ 和~*
~ : 用于表示當前uri中包含了正則表達式,并且區(qū)分大小寫 ~*: 用于表
示當前uri中包含了正則表達式,并且不區(qū)分大小寫
server {
listen 80;
server_name 127.0.0.1;
location ~^/abc\w${
default_type text/plain;
return 200 "access success";
}
}
server {
listen 80;
server_name 127.0.0.1;
location ~*^/abc\w${
default_type text/plain;
return 200 "access success";
}
}
^~
^~: 用于不包含正則表達式的uri前,功能和不加符號的一致,唯一不同
的是,如果模式匹配,那么就停止搜索其他模式了。
server {
listen 80;
server_name 127.0.0.1;
location ^~/abc{
default_type text/plain;
return 200 "access success";
}
}
設置請求資源的目錄root / alias
舉例說明:
(1)在/usr/local/nginx/html目錄下創(chuàng)建一個 images目錄,并在目
錄下放入一張圖片mv.png圖片
location /images {
root /usr/local/nginx/html;
}
http://192.168.200.133/images/mv.png
root的處理結(jié)果是: root路徑+location路徑
/usr/local/nginx/html/images/mv.png
alias的處理結(jié)果是:使用alias路徑替換location路徑
location /images {
alias /usr/local/nginx/html/images;
}
(3)如果location路徑是以/結(jié)尾,則alias也必須是以/結(jié)尾,root沒有要
求
location /images/ {
alias /usr/local/nginx/html/images/;
}
小結(jié):
root的處理結(jié)果是: root路徑+location路徑
alias的處理結(jié)果是:使用alias路徑替換location路徑
alias是一個目錄別名的定義,root則是最上層目錄的含義。
如果location路徑是以/結(jié)尾,則alias也必須是以/結(jié)尾,root沒有要
求
4.index指令
index后面可以跟多個設置,如果訪問的時候沒有指定具體訪問的資源,
則會依次進行查找,找到第一個為止。
location / {
root /usr/local/nginx/html;
index index.html index.htm;
}
訪問該location的時候,可以通過 http://ip:port/,地址后面如果
不添加任何內(nèi)容,則默認依次訪問index.html和index.htm,找到第一
個來進行返回
5.error_page指令
error_page:設置網(wǎng)站的錯誤頁面
error_page code … [=[response]] uri;
http、server、location…
server {
error_page 404 http://www.itcast.cn;
}
server{
error_page 404 /50x.html;
error_page 500 502 503 504 /50x.html;
location =/50x.html{
root html;
}
}
server{
error_page 404 @jump_to_error;
location @jump_to_error {
default_type text/plain;
return 404 'Not Found Page...';
}
}
可選項=[response]的作用是用來將相應代碼更改為另外一個
server{
error_page 404 =200 /50x.html;
location =/50x.html{
root html;
}
}
這樣的話,當返回404找不到對應的資源的時候,在瀏覽器上可以看到,
最終返回的狀態(tài)碼是200,這塊需要注意下,編寫error_page后面的內(nèi)
容,404后面需要加空格,200前面不能加空格
靜態(tài)資源的緩存處理
緩存(cache),原始意義是指訪問速度比一般隨機存取存儲器(RAM)
快的一種高速存儲器,通常它不像系統(tǒng)主存那樣使用DRAM技術(shù),而使用昂
貴但較快速的SRAM技術(shù)。緩存的設置是所有現(xiàn)代計算機系統(tǒng)發(fā)揮高性能的
重要因素之一。
什么是web緩存
Web緩存是指一個Web資源(如html頁面,圖片,js,數(shù)據(jù)等)存在于
Web服務器和客戶端(瀏覽器)之間的副本。緩存會根據(jù)進來的請求保存
輸出內(nèi)容的副本;當下一個請求來到的時候,如果是相同的URL,緩存會
根據(jù)緩存機制決定是直接使用副本響應訪問請求,還是向源服務器再次發(fā)
送請求。比較常見的就是瀏覽器會緩存訪問過網(wǎng)站的網(wǎng)頁,當再次訪問這
個URL地址的時候,如果網(wǎng)頁沒有更新,就不會再次下載網(wǎng)頁,而是直接
使用本地緩存的網(wǎng)頁。只有當網(wǎng)站明確標識資源已經(jīng)更新,瀏覽器才會再
次下載網(wǎng)頁
瀏覽器緩存
是為了節(jié)約網(wǎng)絡的資源加速瀏覽,瀏覽器在用戶磁盤上對最近請求過的文
檔進行存儲,當訪問者再次請求這個頁面時,瀏覽器就可以從本地磁盤顯
示文檔,這樣就可以加速頁面的閱覽.
成本最低的一種緩存實現(xiàn)
減少網(wǎng)絡帶寬消耗
降低服務器壓力
減少網(wǎng)絡延遲,加快頁面打開速度
瀏覽器緩存的執(zhí)行流程
(1)用戶首次通過瀏覽器發(fā)送請求到服務端獲取數(shù)據(jù),客戶端是沒有對
應的緩存,所以需要發(fā)送request請求來獲取數(shù)據(jù);
(2)服務端接收到請求后,獲取服務端的數(shù)據(jù)及服務端緩存的允許后,
返回200的成功狀態(tài)碼并且在響應頭上附上對應資源以及緩存信息;
(3)當用戶再次訪問相同資源的時候,客戶端會在瀏覽器的緩存目錄中
查找是否存在響應的緩存文件
(4)如果沒有找到對應的緩存文件,則走(2)步
(5)如果有緩存文件,接下來對緩存文件是否過期進行判斷,過期的判
斷標準是(Expires),
(6)如果沒有過期,則直接從本地緩存中返回數(shù)據(jù)進行展示
(7)如果Expires過期,接下來需要判斷緩存文件是否發(fā)生過變化
(8)判斷的標準有兩個,一個是ETag(Entity Tag),一個是Last-Modified
(9)判斷結(jié)果是未發(fā)生變化,則服務端返回304,直接從緩存文件中獲
取數(shù)據(jù)
(10)如果判斷是發(fā)生了變化,重新從服務端獲取數(shù)據(jù),并根據(jù)緩存協(xié)
商(服務端所設置的是否需要進行緩存數(shù)據(jù)的設置)來進行數(shù)據(jù)緩存。
expires指令
expires:該指令用來控制頁面緩存的作用。可以通過該指令控制HTTP應
答中的“Expires"和”Cache-Control"
add_header指令
Cache-control: must-revalidate
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: public
Cache-control: private
Cache-control: proxy-revalidate
Cache-Control: max-age=<seconds>
Cache-control: s-maxage=<seconds>
Nginx的跨域問題解決
同源策略
瀏覽器的同源策略:是一種約定,是瀏覽器最核心也是最基本的安全功
能,如果瀏覽器少了同源策略,則瀏覽器的正常功能可能都會受到影
響。
同源: 協(xié)議、域名(IP)、端口相同即為同源
http://192.168.200.131/user/1
https://192.168.200.131/user/1
不
http://192.168.200.131/user/1
http://192.168.200.132/user/1
不
http://192.168.200.131/user/1
http://192.168.200.131:8080/user/1
不
http://www.nginx.com/user/1
http://www.nginx.org/user/1
不
ttp://192.168.200.131/user/1
http://192.168.200.131:8080/user/1
不
http://www.nginx.org:80/user/1
http://www.nginx.org/user/1
滿足
跨域問題
有兩臺服務器分別為A,B,如果從服務器A的頁面發(fā)送異步請求到服務器B獲
取數(shù)據(jù),如果服務器A和服務器B不滿足同源策略,則就會出現(xiàn)跨域問題。
解決方案
此處用來解決跨域問題,需要添加兩個頭信息,一個是AccessControl-Allow-Origin , Access-Control-Allow-Methods
Access-Control-Allow-Origin: 直譯過來是允許跨域訪問的源地址信息,
可以配置多個(多個用逗號分隔),也可以使用*代表所有源
此處用來解決跨域問題,需要添加兩個頭信息,一個是AccessControl-Allow-Origin , Access-Control-Allow-Methods
Access-Control-Allow-Origin: 直譯過來是允許跨域訪問的源地址信息,
可以配置多個(多個用逗號分隔),也可以使用*代表所有源
location /getUser{
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods
GET,POST,PUT,DELETE;
default_type application/json;
return 200 '{"id":1,"name":"TOM","age":18}';
}
靜態(tài)資源防盜鏈
資源盜鏈指的是此內(nèi)容不在自己服務器上,而是通過技術(shù)手段,繞過別
人的限制將別人的內(nèi)容放到自己頁面上最終展示給用戶。以此來盜取大
網(wǎng)站的空間和流量。簡而言之就是用別人的東西成就自己的網(wǎng)站。
資源盜鏈指的是此內(nèi)容不在自己服務器上,而是通過技術(shù)手段,繞過別
人的限制將別人的內(nèi)容放到自己頁面上最終展示給用戶。以此來盜取大
網(wǎng)站的空間和流量。簡而言之就是用別人的東西成就自己的網(wǎng)站。
location ~*\.(png|jpg|gif){
valid_referers none blocked www.baidu.com
192.168.200.222 *.example.com example.*
www.example.org ~\.google\.;
if ($invalid_referer){
return 403;
}
root /usr/local/nginx/html;
}
針對目錄進行防盜鏈
location /images {
valid_referers none blocked www.baidu.com
192.168.200.222 *.example.com example.*
www.example.org ~\.google\.;
if ($invalid_referer){
return 403;
}
root /usr/local/nginx/html;
}
Rewrite功能配置
Rewrite規(guī)則
set指令
該指令用來設置一個新的變量。
if指令.
if (-f $request_filename){
#判斷請求的文件是否存在
}
if (!-f $request_filename){
#判斷請求的文件是否不存在
}
break指令
該指令用于中斷當前相同作用域中的其他Nginx配置。與該指令處于同
一作用域的Nginx配置中,位于它前面的指令配置生效,位于后面的指
令配置無效
location /{
if ($param){
set $id $1;
break;
limit_rate 10k;
}
}
return指令
該指令用于完成對請求的處理,直接向客戶端返回響應狀態(tài)代碼。在
return后的所有Nginx配置都是無效的。
rewrite指令
該指令通過正則表達式的使用來改變URI??梢酝瑫r存在一個或者多個指
令,按照順序依次對URL進行匹配和處理。
當我們匹配到rewrite/url路徑加上后面的任意字符的路徑,都將跳轉(zhuǎn)到百度的連接,看第二行,當我們匹配到test路徑的時候,我們將會訪問/$1,這個表示的是括號里test路徑的意思
rewrite_log指令
==
Rewrite的案例
域名鏡像
獨立域名
目錄自動添加"/"
server {
listen 80;
server_name localhost;
location /hm {
root html;
index index.html;
}
}
server {
listen 80;
server_name localhost;
server_name_in_redirect on;
location /hm {
if (-d $request_filename){
rewrite ^/(.*)([^/])$ http://$host/$1$2/
permanent;
}
}
}
合并目錄
防盜鏈
文件防盜鏈
server{
listen 80;
server_name www.web.com;
locatin ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)${
valid_referers none blocked server_names
*.web.com;
if ($invalid_referer){
rewrite ^/
http://www.web.com/images/forbidden.png;
}
}
}
目錄防盜鏈
server{
listen 80;
server_name www.web.com;
location /file/{
root /server/file/;
valid_referers none blocked server_names
*.web.com;
if ($invalid_referer){
rewrite ^/
http://www.web.com/images/forbidden.png;
}
}
}
Nginx反向代理
Nginx正向代理案例
http {
log_format main 'client send
request=>clientIp=$remote_addr serverIp=>$host';
server{
listen 80;
server_name localhost;
access_log logs/access.log main;
location {
root html;
index index.html index.htm;
}
}
}
server {
listen 82;
resolver 8.8.8.8;
location /{
proxy_pass http://$host$request_uri;
}
}
Nginx反向代理的配置語法
Nginx反向代理模塊的指令是由ngx_http_proxy_module模塊進行解
析,該模塊在安裝Nginx的時候已經(jīng)自己加裝到Nginx中了,接下來我們
把反向代理中的常用指令一一介紹下:
- proxy_pass
- proxy_set_header
- proxy_redirect
proxy_pass
URL:為要設置的被代理服務器地址,包含傳輸協(xié)議( http , https:// )、
主機名稱或IP地址加端口號、URI等要素。
我們?nèi)绻鹥roxy_pass不加斜杠,則代理的請求路徑則會拼接location中的/server。如果我們加上了,則我們直接訪問的是index.html頁面
proxy_set_header
該指令可以更改Nginx服務器接收到的客戶端請求的請求頭信息,然后
將新的請求頭發(fā)送給代理的服務器代理服務器: [192.168.200.133]
proxy_redirect
該指令是用來重置頭信息中的"Location"和"Refresh"的值。服務端[192.168.200.146]
代理服務端[192.168.200.133]
proxy_redirect default;
Nginx的安全控制
如何使用SSL對流量進行加密
翻譯成大家能熟悉的說法就是將我們常用的http請求轉(zhuǎn)變成https請求,
那么這兩個之間的區(qū)別簡單的來說兩個都是HTTP協(xié)議,只不過https是
身披SSL外殼的http.
HTTPS是一種通過計算機網(wǎng)絡進行安全通信的傳輸協(xié)議。它經(jīng)由HTTP進
行通信,利用SSL/TLS建立全通信,加密數(shù)據(jù)包,確保數(shù)據(jù)的安全性。
上述這兩個是為網(wǎng)絡通信提供安全及數(shù)據(jù)完整性的一種安全協(xié)議,TLS和
SSL在傳輸層和應用層對網(wǎng)絡連接進行加密。
- SSL(Secure Sockets Layer)安全套接層
- TLS(Transport Layer Security)傳輸層安全
Nginx要想使用SSL,需要滿足一個條件即需要添加一個模塊–withhttp_ssl_module ,而該模塊在編譯的過程中又需要OpenSSL的支持,
這個我們之前已經(jīng)準備好了。
》將原有/usr/local/nginx/sbin/nginx進行備份
》拷貝nginx之前的配置信息
》在nginx的安裝源碼進行配置指定對應模塊 ./configure --
with-http_ssl_module
》通過make模板進行編譯
》將objs下面的nginx移動到/usr/local/nginx/sbin下
》在源碼目錄下執(zhí)行 make upgrade進行升級,這個可以實現(xiàn)不停機添
加新模塊的功能
Nginx的SSL相關指令
SSL
ssl_certificate
ssl_certificate:為當前這個虛擬主機指定一個帶有PEM格式證書的證
書。
ssl_certificate_key
ssl_session_cache
ssl_session_timeout
ssl_ciphers
ssl_prefer_server_ciphers
生成證書
開啟SSL實例
server {
listen 443 ssl;
server_name localhost;
ssl_certificate server.cert;
ssl_certificate_key server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
反向代理系統(tǒng)調(diào)優(yōu)
相同點:
兩種方式都是用來提供IO吞吐效率,都是用來提升Nginx代理的性能。
不同點:
緩沖主要用來解決不同設備之間數(shù)據(jù)傳遞速度不一致導致的性能低的問
題,緩沖中的數(shù)據(jù)一旦此次操作完成后,就可以刪除。
緩存主要是備份,將被代理服務器的數(shù)據(jù)緩存一份到代理服務器,這樣的
話,客戶端再次獲取相同數(shù)據(jù)的時候,就只需要從代理服務器上獲取,效
率較高,緩存中的數(shù)據(jù)可以重復使用,只有滿足特定條件才會刪除.
(1)Proxy Buffer相關指令
》proxy_buffering :該指令用來開啟或者關閉代理服務器的緩沖區(qū);
》proxy_buffers:該指令用來指定單個連接從代理服務器讀取響應的緩
存區(qū)的個數(shù)和大小。
number:緩沖區(qū)的個數(shù)
size:每個緩沖區(qū)的大小,緩沖區(qū)的總大小就是number*size
`
》proxy_buffer_size:該指令用來設置從被代理服務器獲取的第一部分響
應數(shù)據(jù)的大小。保持與proxy_buffers中的size一致即可,當然也可以更
小。`
》proxy_busy_buffers_size:該指令用來限制同時處于BUSY狀態(tài)的緩
沖總大小。
》proxy_temp_path:當緩沖區(qū)存滿后,仍未被Nginx服務器完全接受,
響應數(shù)據(jù)就會被臨時存放在磁盤文件上,該指令設置文件路徑
》proxy_temp_file_write_size:該指令用來設置磁盤上緩沖文件的大
小。
proxy_buffering on;
proxy_buffer_size 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
負載均衡
負載均衡的原理及處理流程
系統(tǒng)的擴展可以分為縱向擴展和橫向擴展。
縱向擴展是從單機的角度出發(fā),通過增加系統(tǒng)的硬件處理能力來提升服
務器的處理能力
橫向擴展是通過添加機器來滿足大型網(wǎng)站服務的處理能力。
負載均衡的作用
1、解決服務器的高并發(fā)壓力,提高應用程序的處理性能。
2、提供故障轉(zhuǎn)移,實現(xiàn)高可用。
3、通過添加或減少服務器數(shù)量,增強網(wǎng)站的可擴展性。
4、在負載均衡器上進行過濾,可以提高系統(tǒng)的安全性。
負載均衡常用的處理方式
用戶手動選擇
DNS輪詢方式
域名系統(tǒng)(服務)協(xié)議(DNS)是一種分布式網(wǎng)絡目錄服務,主要用于域
名與 IP 地址的相互轉(zhuǎn)換。
大多域名注冊商都支持對同一個主機名添加多條A記錄,這就是DNS輪
詢,DNS服務器將解析請求按照A記錄的順序,隨機分配到不同的IP上,
這樣就能完成簡單的負載均衡。DNS輪詢的成本非常低,在一些不重要
的服務器,被經(jīng)常使用。
四/七層負載均衡
介紹四/七層負載均衡之前,我們先了解一個概念,OSI(open system
interconnection),叫開放式系統(tǒng)互聯(lián)模型,這個是由國際標準化組織ISO
指定的一個不基于具體機型、操作系統(tǒng)或公司的網(wǎng)絡體系結(jié)構(gòu)。該模型
將網(wǎng)絡通信的工作分為七層。
Nginx七層負載均衡
Nginx要實現(xiàn)七層負載均衡需要用到proxy_pass代理模塊配置。Nginx默
認安裝支持這個模塊,我們不需要再做任何處理。Nginx的負載均衡是
在Nginx的反向代理基礎上把用戶的請求根據(jù)指定的算法分發(fā)到一組
【upstream虛擬服務池】
Nginx七層負載均衡的指令
服務端設置
server {
listen 9001;
server_name localhost;
default_type text/html;
location /{
return 200 '<h1>192.168.200.146:9001</h1>';
}
}
server {
listen 9002;
server_name localhost;
default_type text/html;
location /{
return 200 '<h1>192.168.200.146:9002</h1>';
}
}
server {
listen 9003;
server_name localhost;
default_type text/html;
location /{
return 200 '<h1>192.168.200.146:9003</h1>';
}
}
負載均衡器設置
upstream backend{
server 192.168.200.146:9091;
server 192.168.200.146:9092;
server 192.168.200.146:9093;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
負載均衡狀態(tài)
down
down:將該服務器標記為永久不可用,那么該代理服務器將不參與負載
均衡。
upstream backend{
server 192.168.200.146:9001 down;
server 192.168.200.146:9002
server 192.168.200.146:9003;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
backup
backup:將該服務器標記為備份服務器,當主服務器不可用時,將用來傳
遞請求。
upstream backend{
server 192.168.200.146:9001 down;
server 192.168.200.146:9002 backup;
server 192.168.200.146:9003;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
max_fails和fail_timeout
max_conns
upstream backend{
server 192.168.200.133:9001 down;
server 192.168.200.133:9002 backup;
server 192.168.200.133:9003 max_fails=3
fail_timeout=15;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
負載均衡策略
輪詢
weight加權(quán)[加權(quán)輪詢]
ip_hash
當對后端的多臺動態(tài)應用服務器做負載均衡時,ip_hash指令能夠?qū)⒛硞€
客戶端IP的請求通過哈希算法定位到同一臺后端服務器上。這樣,當來
自某一個IP的用戶在后端Web服務器A上登錄后,在訪問該站點的其他
URL,能保證其訪問的還是后端web服務器A。
least_conn
upstream backend{
least_conn;
server 192.168.200.146:9001;
server 192.168.200.146:9002;
server 192.168.200.146:9003;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
url_hash
按訪問url的hash結(jié)果來分配請求,使每個url定向到同一個后端服務
器,要配合緩存命中來使用。同一個資源多次請求,可能會到達不同的
服務器上,導致不必要的多次下載,緩存命中率不高,以及一些資源時
間的浪費。而使用url_hash,可以使得同一個url(也就是同一個資源請求)
會到達同一臺服務器,一旦緩存住了資源,再此收到請求,就可以
從緩存中讀取。
fair
fair采用的不是內(nèi)建負載均衡使用的輪換的均衡算法,而是可以根據(jù)頁面
大小、加載時間長短智能的進行負載均衡。那么如何使用第三方模塊的
fair負載均衡策略。
upstream backend{
fair;
server 192.168.200.146:9001;
server 192.168.200.146:9002;
server 192.168.200.146:9003;
}
server {
listen 8083;
server_name localhost;
location /{
proxy_pass http://backend;
}
}
但是如何直接使用會報錯,因為fair屬于第三方模塊實現(xiàn)的負載均衡。需
要添加nginx-upstream-fair ,如何添加對應的模塊:
擴展案例
upstream backend{
server 192.168.200.146:9001;
server 192.168.200.146:9002;
server 192.168.200.146:9003;
}
server {
listen 80;
server_name localhost;
location /file/ {
rewrite ^(/file/.*) /server/$1 last;
}
location / {
proxy_pass http://backend;
}
}
四層負載均衡的案例
stream {
upstream redisbackend {
server 192.168.200.146:6379;
server 192.168.200.146:6378;
}
upstream tomcatbackend {
server 192.168.200.146:8080;
}
server {
listen 81;
proxy_pass redisbackend;
}
server {
listen 82;
proxy_pass tomcatbackend;
}
}
Nginx緩存集成
緩存就是數(shù)據(jù)交換的緩沖區(qū)(稱作:Cache),當用戶要獲取數(shù)據(jù)的時候,會
先從緩存中去查詢獲取數(shù)據(jù),如果緩存中有就會直接返回給用戶,如果
緩存中沒有,則會發(fā)請求從服務器重新查詢數(shù)據(jù),將數(shù)據(jù)返回給用戶的
同時將數(shù)據(jù)放入緩存,下次用戶就會直接從緩存中獲取數(shù)據(jù)
Nginx的web緩存服務
Nginx緩存設置的相關指令
Nginx的web緩存服務主要是使用ngx_http_proxy_module模塊相關指
令集來完成,接下來我們把常用的指令來進行介紹下。
proxy_cache_path
keys_zone:用來為這個緩存區(qū)設置名稱和指定大小,如:
proxy_cache
proxy_cache_key
proxy_cache_valid
proxy_cache_min_uses
proxy_cache_methods
Nginx緩存設置案例
http{
proxy_cache_path /usr/local/proxy_cache
levels=2:1 keys_zone=itcast:200m inactive=1d
max_size=20g;
upstream backend{
server 192.168.200.146:8080;
}
server {
listen 8080;
server_name localhost;
location / {
proxy_cache itcast;
proxy_cache_key itheima;
proxy_cache_min_uses 5;
proxy_cache_valid 200 5d;
proxy_cache_valid 404 30s;
proxy_cache_valid any 1m;
add_header nginx-cache
"$upstream_cache_status";
proxy_pass http://backend/js/;
}
}
}
Nginx緩存的清除
方式一:刪除對應的緩存目錄
rm -rf /usr/local/proxy_cache/......
使用第三方擴展模塊
ngx_cache_purge
server{
location ~/purge(/.*) {
proxy_cache_purge itcast itheima;
}
}
Nginx設置資源不緩存
前面咱們已經(jīng)完成了Nginx作為web緩存服務器的使用。但是我們得思考
一個問題就是不是所有的數(shù)據(jù)都適合進行緩存。比如說對于一些經(jīng)常發(fā)
生變化的數(shù)據(jù)。如果進行緩存的話,就很容易出現(xiàn)用戶訪問到的數(shù)據(jù)不
是服務器真實的數(shù)據(jù)。所以對于這些資源我們在緩存的過程中就需要進
行過濾,不進行緩存。
proxy_no_cache
該指令是用來定義不將數(shù)據(jù)進行緩存的條件。
proxy_no_cache $cookie_nocache $arg_nocache
$arg_comment;
proxy_cache_bypass
該指令是用來設置不從緩存中獲取數(shù)據(jù)的條件。
log_format params $cookie_nocache | $arg_nocache |
$arg_comment;
server{
listen 8081;
server_name localhost;
location /{
access_log logs/access_params.log params;
add_header Set-Cookie 'nocache=999';
root html;
index index.html;
}
}
Nginx實現(xiàn)服務器端集群搭建
環(huán)境準備(Tomcat)
環(huán)境準備(Nginx)
動靜分離實現(xiàn)步驟
配置Nginx的靜態(tài)資源與動態(tài)資源的訪問
upstream webservice{
server 192.168.200.146:8080;
}
server {
listen 80;
server_name localhost;
#動態(tài)資源
location /demo {
proxy_pass http://webservice;
}
#靜態(tài)資源
location ~/.*\.(png|jpg|gif|js){
root html/web;
gzip on;
}
location / {
root html/web;
index index.html index.htm;
}
}
Nginx實現(xiàn)Tomcat集群搭建
在使用Nginx和Tomcat部署項目的時候,我們使用的是一臺Nginx服務
器和一臺Tomcat服務器,效果圖如下:
Nginx高可用解決方案
Keepalived
Keepalived配置文件介紹
global全局部分:
global_defs {
#通知郵件,當keepalived發(fā)送切換時需要發(fā)email給具體的郵箱
地址
notification_email {
tom@itcast.cn
jerry@itcast.cn
}
#設置發(fā)件人的郵箱信息
notification_email_from zhaomin@itcast.cn
#指定smpt服務地址
smtp_server 192.168.200.1
#指定smpt服務連接超時時間
smtp_connect_timeout 30
#運行keepalived服務器的一個標識,可以用作發(fā)送郵件的主題信
息
router_id LVS_DEVEL
#默認是不跳過檢查。檢查收到的VRRP通告中的所有地址可能會比較
耗時,設置此命令的意思是,如果通告與接收的上一個通告來自相同的
master路由器,則不執(zhí)行檢查(跳過檢查)
vrrp_skip_check_adv_addr
#嚴格遵守VRRP協(xié)議。
vrrp_strict
#在一個接口發(fā)送的兩個免費ARP之間的延遲。可以精確到毫秒級。
默認是0
vrrp_garp_interval 0
#在一個網(wǎng)卡上每組na消息之間的延遲時間,默認為0
vrrp_gna_interval 0
}
VRRP部分,該部分可以包含以下四個子模塊
1. vrrp_script
2. vrrp_sync_group
3. 3. garp_group
4. vrrp_instance
我們會用到第一個和第四個,
#設置keepalived實例的相關信息,VI_1為VRRP實例名稱
vrrp_instance VI_1 {
state MASTER #有兩個值可選MASTER主 BACKUP備
interface ens33 #vrrp實例綁定的接口,用于發(fā)送VRRP
包[當前服務器使用的網(wǎng)卡名稱]
virtual_router_id 51#指定VRRP實例ID,范圍是0-255
priority 100 #指定優(yōu)先級,優(yōu)先級高的將成為
MASTER
advert_int 1 #指定發(fā)送VRRP通告的間隔,單位是秒
authentication { #vrrp之間通信的認證信息
auth_type PASS #指定認證方式。PASS簡單密碼認證(推
薦)
auth_pass 1111 #指定認證使用的密碼,最多8位
}
virtual_ipaddress { #虛擬IP地址設置虛擬IP地址,供用戶
訪問使用,可設置多個,一行一個
192.168.200.222
}
}
服務器1
global_defs {
notification_email {
tom@itcast.cn
jerry@itcast.cn
}
notification_email_from zhaomin@itcast.cn
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id keepalived1
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.200.222
}
}
服務器2
! Configuration File for keepalived
global_defs {
notification_email {
tom@itcast.cn
jerry@itcast.cn
}
notification_email_from zhaomin@itcast.cn
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id keepalived2
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.200.222
}
}
Nginx制作下載站點
location /download{
root /usr/local;
autoindex on;
autoindex_exact_size on;
autoindex_format html;
autoindex_localtime on;
}
Nginx的用戶認證模塊
location /download{
root /usr/local;
autoindex on;
autoindex_exact_size on;
autoindex_format html;
autoindex_localtime on;
auth_basic 'please input your auth';
auth_basic_user_file htpasswd;
}
Nginx的擴展模塊
Nginx是可擴展的,可用于處理各種使用場景。本節(jié)中,我們將探討使
用Lua擴展Nginx的功能。
Lua
ngx_lua操作Redis
lua-resty-redis提供了訪問Redis的詳細API,包括創(chuàng)建對接、連
接、操作、數(shù)據(jù)處理等。這些API基本上與Redis的操作一一對應。
(1)redis = require "resty.redis"
(2)new
語法: redis,err = redis:new(),創(chuàng)建一個Redis對象。
(3)connect
語
法:ok,err=redis:connect(host,port[,options_table]),設
置連接Redis的連接信息。
ok:連接成功返回 1,連接失敗返回nil
err:返回對應的錯誤信息
(4)set_timeout
語法: redis:set_timeout(time) ,設置請求操作Redis的超
時時間。
(5)close
語法: ok,err = redis:close(),關閉當前連接,成功返回1,
失敗返回nil和錯誤信息
(6)redis命令對應的方法
在lua-resty-redis中,所有的Redis命令都有自己的方法,方
法名字和命令名字相同,只是全部為小寫。
location / {
default_type "text/html";
content_by_lua_block{
local redis = require "resty.redis" -- 引入
Redis
local redisObj = redis:new() --創(chuàng)建Redis對象
redisObj:set_timeout(1000) --設置超時數(shù)據(jù)為1s
local ok,err =
redisObj:connect("192.168.200.1",6379) --設置redis連接
信息
if not ok then --判斷是否連接成功
ngx.say("failed to connection redis",err)
return
end
ok,err = redisObj:set("username","TOM")--存入
數(shù)據(jù)
if not ok then --判斷是否存入成功
ngx.say("failed to set username",err)
return
end
local res,err = redisObj:get("username") --從
redis中獲取數(shù)據(jù)
ngx.say(res) --將數(shù)據(jù)寫會消息體中
redisObj:close()
}
}
ngx_lua操作Mysql
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.200.111:3306/nginx_db
username=root
password=123456
(1)引入"resty.mysql"模塊
local mysql = require "resty.mysql"
(2)new
創(chuàng)建一個MySQL連接對象,遇到錯誤時,db為nil,err為錯誤描
述信息
語法: db,err = mysql:new()
(3)connect
嘗試連接到一個MySQL服務器
語法:ok,err=db:connect(options),options是一個參數(shù)的
Lua表結(jié)構(gòu),里面包含數(shù)據(jù)庫連接的相關信息
host:服務器主機名或IP地址
port:服務器監(jiān)聽端口,默認為3306
user:登錄的用戶名
password:登錄密碼
database:使用的數(shù)據(jù)庫名
(4)set_timeout
設置子請求的超時時間(ms),包括connect方法
語法:db:set_timeout(time)
(5)close
關閉當前MySQL連接并返回狀態(tài)。如果成功,則返回1;如果出現(xiàn)任
何錯誤,則將返回nil和錯誤描述。
語法:db:close()
(6)send_query
異步向遠程MySQL發(fā)送一個查詢。如果成功則返回成功發(fā)送的字節(jié)
數(shù);如果錯誤,則返回nil和錯誤描述
語法:bytes,err=db:send_query(sql)
(7)read_result
從MySQL服務器返回結(jié)果中讀取一行數(shù)據(jù)。res返回一個描述OK包
或結(jié)果集包的Lua表,語法:
res, err, errcode, sqlstate = db:read_result()
res, err, errcode, sqlstate =
db:read_result(rows) :rows指定返回結(jié)果集的最大值,默認為4
如果是查詢,則返回一個容納多行的數(shù)組。每行是一個數(shù)據(jù)列的
key-value對,如
{
{id=1,username="TOM",birthday="1988-11-
11",salary=10000.0},
{id=2,username="JERRY",birthday="1989-11-
11",salary=20000.0}
}
如果是增刪改,則返回類上如下數(shù)據(jù)
{
insert_id = 0,
server_status=2,
warning_count=1,
affected_rows=2,
message=nil
}
返回值:
res:操作的結(jié)果集
err:錯誤信息
errcode:MySQL的錯誤碼,比如1064
sqlstate:返回由5個字符組成的標準SQL錯誤碼,比如
42000
location /{
content_by_lua_block{
local mysql = require "resty.mysql"
local db = mysql:new()
local ok,err = db:connect{
host="192.168.200.111",
port=3306,
user="root",
password="123456",
database="nginx_db"
}
db:set_timeout(1000)
db:send_query("select * from users where id
=1")
local res,err,errcode,sqlstate =
db:read_result()
ngx.say(res[1].id..","..res[1].username..","..res[1].
birthday..","..res[1].salary)
db:close()
}
}
location /{
content_by_lua_block{
local mysql = require "resty.mysql"
local cjson = require "cjson"
local db = mysql:new()
local ok,err = db:connect{
host="192.168.200.111",
port=3306,
user="root",
password="123456",
database="nginx_db"
}
db:set_timeout(1000)
--db:send_query("select * from users where id
= 2")
db:send_query("select * from users")
local res,err,errcode,sqlstate =
db:read_result()
ngx.say(cjson.encode(res))
for i,v in ipairs(res) do
ngx.say(v.id..","..v.username..","..v.birthday..","..
v.salary)
end
db:close()
}
}
文章來源:http://www.zghlxwxcb.cn/news/detail-684882.html
location /{
content_by_lua_block{
local mysql = require "resty.mysql"
local db = mysql:new()
local ok,err = db:connect{
host="192.168.200.1",
port=3306,
user="root",
password="123456",
database="nginx_db",
max_packet_size=1024,
compact_arrays=false
}
db:set_timeout(1000)
local res,err,errcode,sqlstate =
db:query("select * from users")
--local res,err,errcode,sqlstate =
db:query("insert into
users(id,username,birthday,salary)
values(null,'zhangsan','2020-11-11',32222.0)")
--local res,err,errcode,sqlstate =
db:query("update users set username='lisi' where id =
6")
--local res,err,errcode,sqlstate =
db:query("delete from users where id = 6")
db:close()
}
}
綜合小案例
文章來源地址http://www.zghlxwxcb.cn/news/detail-684882.html
init_by_lua_block{
redis = require "resty.redis"
mysql = require "resty.mysql"
cjson = require "cjson"
}
location /{
default_type "text/html";
content_by_lua_block{
--獲取請求的參數(shù)username
local param = ngx.req.get_uri_args()
["username"]
--建立mysql數(shù)據(jù)庫的連接
local db = mysql:new()
local ok,err = db:connect{
host="192.168.200.111",
port=3306,
user="root",
password="123456",
database="nginx_db"
}
if not ok then
ngx.say("failed connect to
mysql:",err)
return
end
--設置連接超時時間
db:set_timeout(1000)
--查詢數(shù)據(jù)
local sql = "";
if not param then
sql="select * from users"
else
sql="select * from users where
username=".."'"..param.."'"
end
local
res,err,errcode,sqlstate=db:query(sql)
if not res then
ngx.say("failed to query from
mysql:",err)
return
end
--連接redis
local rd = redis:new()
ok,err =
rd:connect("192.168.200.111",6379)
if not ok then
ngx.say("failed to connect to
redis:",err)
return
end
rd:set_timeout(1000)
--循環(huán)遍歷數(shù)據(jù)
for i,v in ipairs(res) do
rd:set("user_"..v.username,cjson.encode(v))
end
ngx.say("success")
rd:close()
db:close()
}
}
到了這里,關于一篇文章讓你了解nginx和lua腳本(Nginx詳解)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!