nginx實現常見場景

笑佛彌勒發表於2018-12-08

Nginx是一款輕量級的HTTP伺服器,採用事件驅動的非同步非阻塞處理方式框架,這讓其具有極好的IO效能。我們在日常開發中使用到Nginx的主要有以下幾個場景:

  • Nginx作為http伺服器
  • 跨域請求
  • 負載均衡
  • 網路資源的動靜分離

nginx作為http伺服器

Nginx本身是一個靜態資源的伺服器,當只有靜態資源的時候,就可以使用Nginx來做伺服器,如下,我們使用Nginx來部署一個打包好的vue專案

#vue專案
server
{
     listen 8081; #監聽埠
     server_name 209.250.235.145; 
     root /app/vue/dist/; # 我們的資源在伺服器中的路徑
     index index.html; #指定資源的入口檔案
}複製程式碼

完成後我們nginx -s reload一下,然後訪問209.250.235.145:8081,只要路徑沒錯靜態資源就訪問的到了

nginx實現常見場景

跨域請求

前後端分離的專案中由於前後端專案分別部署到不同的伺服器上,我們首先遇到的問題就是跨域,在這個場景我們下nginx可以幫助我們很好地解決這個問題

#跨域請求server
server{
	listen 9000;
	server_name 209.250.235.145;
	root /app/crossDomain/;
	index index.html;
	
	location /douban/ { #新增訪問目錄為/apis的代理配置
		rewrite   ^/douban/(.*)$ /$1 break;
		proxy_pass   https://m.douban.com;
   }
}
複製程式碼

在我的伺服器下我寫了一個

index.html請求豆瓣介面,模擬跨域

function nginxClick(){
	$.ajax({
		url: '/douban/rexxar/api/v2/muzzy/columns/10018/items?start=0&count=3',
		dataType: 'json',
		type: 'get',
		data: "",
		success:(res)=>{
		    console.log(res)
		}
	})
}
複製程式碼

當我們訪問點選請求時,匹配到location下的/douban/

rewrite   ^/douban/(.*)$ /$1 break;複製程式碼

這段配置將請求路徑重寫為/rexxar/api/v2/muzzy/columns/10018/items?start=0&count=3,其中$1代表正則模糊匹配到的第一個引數,

proxy_pass   https://m.douban.com;複製程式碼

這段配置是將請求域名代理到豆瓣的域名下面,所以從本地伺服器發出去的請求將被重新重寫為:

https://m.douban.com/rexxar/api/v2/muzzy/columns/10018/items?start=0&count=3,我們就能拿到豆瓣api提供的資料。詳情可以看看這篇文章

演示地址:http://209.250.235.145:9000/

負載均衡

負載均衡也是Nginx常用的一個功能,主要的是利用upstream來定義叢集伺服器。負載均衡配置一般都需要同時配置反向代理,通過反向代理跳轉到負載均衡。而Nginx目前支援自帶3種負載均衡策略

  • RR(預設):每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,能自動剔除
  • 權重:指定輪詢機率,weight和訪問比率成正比,用於後端伺服器效能不均的情況
  • ip_hash:上面的2種方式都有一個問題,那就是下一個請求來的時候請求可能分發到另外一個伺服器,當我們的程式不是無狀態的時候(採用了session儲存資料),這時候就有一個很大的很問題了,比如把登入資訊儲存到了session中,那麼跳轉到另外一臺伺服器的時候就需要重新登入了,所以很多時候我們需要一個客戶只訪問一個伺服器,那麼就需要用iphash了,iphash的每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端伺服器,可以解決session的問題。
這裡用第二900種策略來模擬實現了下負載均衡(同一臺伺服器上的兩個埠起了兩個node服務。)

nginx實現常見場景

使用upstream定義伺服器 

upstream smile.com{	
	server 209.250.235.145:9001 weight=1;
	server 209.250.235.145:9002 weight=2;
}複製程式碼

server{
	listen  9003;
	server_name 209.250.235.145;
	
	location / {
		proxy_pass		http://smile.com;
		proxy_redirect 		default;
	}
}複製程式碼

當我們訪問9003這個埠時,會根據我們設定的權重不同分別落在不同的伺服器(埠)。

nginx實現常見場景nginx實現常見場景



演示地址:http://209.250.235.145:9003/

網路資源的動靜分離

當我們的請求涉及靜態資源時,我們可以將請求分發到不同的伺服器。

    #動靜分離server
    upstream static {
	    server 209.250.235.145:9006;
    }
    server{
        listen 9005;
	    server_name 209.250.235.145;
	    root /app/dynSta;
		
	    location ~ .*.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
            proxy_pass http://static;
        }
    }
    server{
        listen 9006;
	   server_name 209.250.235.145;
	   root /app/dynSta;
    }
複製程式碼

我們定義了一個

為靜態資源新增了一個埠,並新增到
upstream模組,當我們的location匹配到以(gif|jpg|jpeg|png|bmp|swf|css|js)結尾的檔案時,我們都會把請求轉發到9006這個埠下(好想成為土豪,好想擁有兩臺伺服器啊啊啊啊。。)

nginx除了以上的使用場景外,還可以用來適配pc和移動環境

適配pc和移動環境

        #適配pc環境和移動環境
	server{
		listen 9007;
		server_name 209.250.235.145;
		root /app/pcAndh5/;
		index pc.html;
		
		location / {
			if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
				set $mobile_request '1';
			}
			if ($mobile_request = '1') {
				rewrite ^.+ https://www.baidu.com/;
				
			}
        }
    }
複製程式碼

這裡我們使用nginx內建變數$http_user_agent來匹配請求的來源,當來源是(Android|webOS|iPhone|iPod|BlackBerry)時,我們將請求整個重寫,讓他去訪問百度,否則訪問我伺服器的地址。

演示地址:http://209.250.235.145:9007/

以上就是nginx伺服器在我們日常開發中使用到的場景


相關文章