具體請參考這篇博文: 【Linux常識篇(1)】所謂的正向代理與反向代理php
經過Nginx強大的反向代理功能,把動態文件給Apache處理,這就造成了LNMPA架構前端
Nginx是一個小巧而高效的Linux下的Web服務器軟件,與Apache相比,消耗資源更少,支持的併發鏈接,更高的效率,反向代理功能效率高、靜態文件處理快等,但動態頁面處理能力不如Apache等老牌軟件成熟。單獨使用Nginx處理大量動態頁面時容易產生頻繁的502錯誤。mysql
Apache是一款老牌的Web服務器軟件,在高併發時對隊列的處理比FastCGI更成熟,Apache的mod_php效率比php-cgi更高且更穩定、對僞靜態支持好,不須要轉換、多用戶多站點權限等方面有着更好的效果,而單獨使用Apache處理靜態頁面時,對內存的佔用遠遠超過Nginx。web
LNMPA使用Nginx做爲前端服務器,可以更快、更及時地使用更少的系統資源處理靜態頁面、js、圖片等文件,當客戶端請求訪問動態頁面時,由Nginx反向代理給做爲後端服務器的Apache處理,Apache處理完再交予Nginx返回給客戶端。
採用LNMPA可以更好的解決LNMP架構中因爲PHP-FPM方面產生的502錯誤,同時可以以很簡單的方式提供更安全的多用戶多站點環境。sql
首先假設你已經假設好了LNMP架構了,這時咱們還要安裝Apache和php,爲何還要再裝一次PHP?由於Apache默認是把PHP做爲自己的一個模塊(mod_php)來運行的,與Nginx的運行方式不一樣.apache
咱們的目的是在localhost:88上配置web1和web2的站點segmentfault
yum -y install httpd httpd-devel # Ubuntu裏面叫作Apache2 yum -y install php php-mysql php-common php-gd php-mbstring php-mcrypt php-devel php-xml
Apache配置文件/etc/httpd/conf/httpd.conf修改以下信息(不一樣的就修改,沒有的就添加)後端
Listen 88 ServerName localhost:88 NameVirtualHost *:88 <VirtualHost *:88> DocumentRoot /home/wwwroot/web2/ ServerName web2.com ErrorLog logs/web2-error_log CustomLog logs/web2-access_log common </VirtualHost> <VirtualHost *:88> DocumentRoot /home/wwwroot/web1/ ServerName web1.com ErrorLog logs/web1-error_log CustomLog logs/web1-access_log common </VirtualHost>
而後配置hosts後經過如下能正常訪問到默認的index.php就表明完成第一步緩存
web1.com:88 web2.com:88
語法:proxy_pass URL 默認值:no 做用域:location, location中的if字段 這個指令設置被代理服務器的地址和被映射的URI,地址可使用主機名或IP加端口號的形式,例如:proxy_pass http://localhost:8000/uri/;
# 在Nginx的web1的server段加上 location / { proxy_pass http://127.0.0.1:88; }
重啓Nginx服務,而後再訪問web1.com(客戶端192.168.42.196 -> 服務端192.168.42.188),這個時候訪問的是Nginx監聽的80端口,進的是Nginx服務,而後Nginx的location命中,再而後由Nginx訪問88的httpd(Apache)服務,而後經過Apache來解析執行該文件,這時產生兩條日誌分別是Nginx服務和Apache服務的兩條訪問日誌安全
# Nginx 192.168.42.196 - - [27/Sep/2015:16:06:10 +0800] "GET / HTTP/1.1" 200 20 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0" - #Apache 192.168.42.188 - - [27/Sep/2015:16:06:10 +0800] "GET / HTTP/1.0" 200 20
咱們注意到訪問Apache的ip就是服務器的ip,這跟咱們想要的客戶端ip不符,這時咱們就要用到另一個指令proxy_set_header
這個指令容許將發送到被代理服務器的請求頭從新定義或者增長一些字段。這個值能夠是一個文本,變量或者它們的組合。proxy_set_header在指定的字段中沒有定義時會從它的上級字段繼承。
語法:proxy_set_header header value 默認值: Host and Connection 使用字段:http, server, location
location / { proxy_pass http://127.0.0.1:88; proxy_set_header X-Real-IP $remote_addr; #加上這一行,把$remote_addr賦給變量X-Real-IP,而後該變量能夠被後端服務器(被反向代理的服務器)的日誌格式中接收到(無論是Nginx和Apache均可以) }
注意: 此時Nginx已經經過proxy_pass向代理服務器Apache發送真實客戶端IP了,可是Apache還沒接受Nginx發送過來的IP
因此咱們還要去更改Apache的配置文件
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined # 將%h修改成%{X-Real-IP}i,這裏要注意在虛擬主機中的日誌格式是否是combined,反正就是修改對應的日誌格式既可; LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
此時咱們就能夠把PHP動態文件返回給Apache處理,而後Nginx自己就只處理靜態文件,這時咱們就能夠經過Nginx使用到Apache強大的僞靜態功能了
也能夠經過配置緩存功能加速Web請求,緩存真實Web服務器上的某些靜態資源,減輕真實Web服務器的負載壓力
location ~ \.(jpg|jpeg|png|gif)$ { proxy_pass http://192.168.1.204:8080; expires 1d; }
事實上Nginx須要反向代理過去的,不單單有ip,還包含着客戶端http請求頭必要信息,好比cookie,host,referer等信息,因此推薦以下配置:
location / { try_files $uri @apache; #try_files 將嘗試你列出的文件並設置內部文件指向 } location @apache { internal; # internal指令指定某個location只能被「內部的」請求調用,外部的調用請求會返回」Not found」 proxy_pass http://127.0.0.1:88; proxy_connect_timeout 300s; proxy_send_timeout 900; proxy_read_timeout 900; proxy_buffer_size 32k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_redirect off; proxy_hide_header Vary; proxy_set_header Accept-Encoding ''; proxy_set_header Host $host; proxy_set_header Referer $http_referer; proxy_set_header Cookie $http_cookie; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }