1. 程式人生 > >Nginx+Apache Yii2.0 配置方案

Nginx+Apache Yii2.0 配置方案

  最近用Yii2.0框架做了個小專案,雖然專案本身業務邏輯不復雜,但是由於本身業務邏輯的特殊性,在上午9點到12點之間系統訪問量會突然上升(瀏覽量和使用者上傳檔案量)。導致系統單純的部署在Apache下,支撐不了這麼多的併發數;單獨部署Nginx又由於使用者頻繁的提交資料,出現大量的502錯誤。然後又由於各方面的原因,就想通過Nginx+Apache的方式來暫時性的解決這個問題。

  安裝apache和nginx的過程就跳過了。apache 監聽的是 8080 埠,nginx 監聽的是80埠。先貼出apache和nginx的配置內容,再來說下踩過的幾個坑。

  apache vhost 相關配置

1
<VirtualHost *:8080> 2 DocumentRoot "/www/wwwroot/website/web" 3 DirectoryIndex index.php 4 ServerName crm.yangcoder.com 5 ErrorLog "logs/crm-error.log" 6 CustomLog "logs/crm-access.log" common 7 </VirtualHost>

  nginx 相關配置

 1 upstream crm_cluster{
 2     server crm.yangcoder.com:8080;
3 #server crm.yangcoder.com:81; 4 #server crm.yangcoder.com:82; 5 } 6 server { 7 listen 80; 8 server_name crm.yangcoder.com; 9 10 #charset koi8-r; 11 access_log logs/crm.yangcoder.access.log; 12 error_log logs/crm.yangcoder.error.log; 13 root E:\\projects\\project\\trunk\\intracompany\\crm\\backend\\web;
14 index index.php index.html index.htm; 15 16 location / { 17 #設定主機頭和客戶端真實地址,以便伺服器獲取客戶端真實IP 18 proxy_set_header Host $host; 19 proxy_set_header X-Real-IP $remote_addr; 20 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 21 proxy_set_header X-Forwarded-Protocol $scheme; 22 proxy_set_header PATH-INFO $request_uri; 23 add_header backendIP $upstream_addr; 24 add_header backendCode $upstream_status; 25 26 #禁用快取 27 proxy_buffering off; 28 #反向代理的地址 29 proxy_pass http://crm_cluster; 30 31 if ($request_filename ~* ^.*?\.(txt|pdf|doc|xls|xlsx)$){ 32 add_header Content-Disposition: 'attachment;'; 33 34 } 35 } 36 37 38 #error_page 404 /404.html; 39 40 # redirect server error pages to the static page /50x.html 41 # 42 error_page 500 502 503 504 /50x.html; 43 location = /50x.html { 44 root E:\\projects\\project\\trunk\\intracompany\\crm\\backend\\web; 45 } 46 47 # proxy the PHP scripts to Apache listening on 127.0.0.1:80 48 # 49 #location ~ \.php$ { 50 # try_files $uri =404; 51 # proxy_redirect off; 52 # #設定主機頭和客戶端真實地址,以便伺服器獲取客戶端真實IP 53 # proxy_set_header Host $host; 54 # proxy_set_header X-Real-IP $remote_addr; 55 # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 56 # proxy_set_header X-Forwarded-Protocol $scheme; 57 # proxy_set_header PATH-INFO $request_uri; 58 # add_header backendIP $upstream_addr; 59 # add_header backendCode $upstream_status; 60 # 61 # #禁用快取 62 # proxy_buffering off; 63 # #反向代理的地址 64 # proxy_pass http://crm_cluster; 65 #} 66 67 68 69 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ 70 { 71 expires 30d; 72 } 73 74 location ~ .*\.(js|css)?$ 75 { 76 expires 30d; 77 } 78 }

 

      通過測試,能夠成功實現動態訪問走apache,靜態資源訪問走nginx。稍微緩解了,專案的壓力。

  踩過的坑:

  1、在本機除錯時,訪問動態內容沒又問題,但是訪問靜態資源時出現500的錯誤。找了好久,最後發現是:【root D:\trunk\src\websit 】,只用了單‘\’,導致nginx 把'\t'解析成一個tab空格了。相當的囧。換成'\\'就可以了。

  2、Yii2.0 開啟了Url美化功能後,導致轉發的動態訪問出現404或者只能訪問預設首頁。找了官方教程和網上的方法,用nginx或者apahce單獨部署是可以的。但是使用nginx+apache結合就不行。

    比如:如下解決方案

    

1 location / {  
2 
3     if (!-e $request_filename){  
4 
5         rewrite ^/(.*) /index.php last;  
6 
7     }  
8 
9 }

  通過日誌分析:假設我們訪問:crm.yangcoder.com/system/msg 這個時候nginx轉發給apache的是:crm.yangcoder.com/index.php/system/msg 。很明顯程式處理不了這個路由。

  後來在順著這個思路在網上找到了一個方法。就是新增如下配置:

  

 1 location / {
 2                 #設定主機頭和客戶端真實地址,以便伺服器獲取客戶端真實IP
 3                 proxy_set_header Host $host;                    
 4                 proxy_set_header X-Real-IP $remote_addr;
 5                 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 6                 proxy_set_header  X-Forwarded-Protocol  $scheme;
 7                 proxy_set_header  PATH-INFO $request_uri;
 8            
 9                 #禁用快取
10                 proxy_buffering off;
11                 #反向代理的地址
12                 proxy_pass   http://crm_cluster;
13         
14             if ($request_filename ~* ^.*?\.(txt|pdf|doc|xls|xlsx)$){ 
15                 add_header Content-Disposition: 'attachment;'; 
16 
17             } 
18         }

  這樣就可以正常訪問了。

  訪問結果如下圖:

  圖1,訪問首頁,顯示請求被轉發到了8080埠上。

  

  圖2,訪問靜態資源

  

 

  3、在同一臺電腦上還測試了負載均衡的效果。唯一的問題是,由於專案後臺部分,使用了Yii2.0的資源管理,在訪問的時候,不同的伺服器生成的靜態資源路徑不統一。導致有時候靜態資源加載出現404錯誤。如果前端要解決該問題,個人覺得可行的方法除了同步多伺服器程式碼檔案外,還有就是靜態資原始檔單獨存放。

1 upstream crm_cluster{
2     server crm.yangcoder.com:8080;
3     server crm.yangcoder.com:81;
4     server crm.yangcoder.com:82;
5 }

  4、當然針對當前專案的邏輯而言,這個方案並不是最優解決方案。其實通過分析,我們的瓶頸並不是出現在程式、資料查詢上,而是出現在使用者同一時間段大量上傳圖片佔用大量上行頻寬上。這一方案目前還能支撐住當前訪問量,8M頻寬,6000+活躍使用者在同一時間段內上傳圖片,統計發現在上午9點到12點之間頻寬的上行頻寬統計是一條平行線。下一步我們想在目前的基礎上介入第三方物件儲存和CDN服務,來優化當前方案。