1、背景介紹
之前一直從事PHP開發工作,公司內業務均由PHP實現,最近由於公司架構微調,分配了幾個Java項目給團隊,但是由於團隊對Java不熟悉,有幾人對Java理解程度也是略懂,這里說的略懂,真的是略懂,所以不敢直接改Java代碼。那么怎么辦呢?經過商量將Java項目的新需求,暫時還是用PHP來實現,但是有一個前提:域名和URL不能變,不能Java代碼用一個域名,PHP用另外一個,因為項目提供的接口有被手機APP客戶端調用,如果更改接口域名或者是URL,客戶端要重新對接,假如將來PHP 要換回Java 又要重新對接,這樣非常不方便,所以域名和接口URL不能變化。
新需求不外乎包含兩種: 第一 更改之前的已有的功能;第二 新增之前沒有的功能。
對於上面兩種情況,第一種情況比較復雜,意味着要把Java已經實現的功能放棄(代碼不用改),用PHP實現一遍,在此基礎上添加新需求的功能,並且URL還不能變。第二種情況需要用PHP實現新功能,當然URL也是新的。根據上面分析,我們必須實現可以識別哪些URL是Java代碼負責的,哪些URL是PHP代碼負責的,並把它們分配到對應的服務器上去才行。
2、方案設計
根據上面的背景分析就是要實現PHP和Java處理同一個域名的不同URL請求,經過團隊內部討論可以用Nginx反向代理來實現,所謂的反向代理就是來自互聯網的請求不直接訪問web服務器,而是先訪問反向代理服務器(我們這里用Nginx),之后Nginx服務器將請求轉發到(內網環境)服務器。
具體方案如下:
首先,我們要給PHP站點和Java站點分別申請一個內網域名,例如(www.php.domain 和 www.java.domain)
1、假如需求是要更改之前java的已經實現的功能。由於此時由於URL已經存在,且不能更改,我們要把URL轉到PHP服務器上去處理,這樣的情況,可以在反向代理服務器上通過正則去匹配這個需要用PHP來實現已經存在的URL,之后把他rewrite到PHP處理路徑再分發到PHP服務器處理(prox_pass www.php.domain)。
2、假如需求是要開發新功能。由於之前的URL不存在,首先要制定一個PHP處理URL路徑約定(或者說規定),就是哪些路徑下的請求是用PHP來處理的。例如:http://www.abc/php/* 這路徑下所有請求都用PHP處理,其他路徑的所有請求都用Java處理,這樣根據Nginx Rewrite正則來匹配/php/ 路徑之后rewrite到php處理路徑,之后分發到PHP服務器(prox_pass www.php.domain)。
3、剩下的其他請求,還是需要java來處理,所以當上面兩種URL都沒有匹配上,自然就由java來處理,直接(prox_pass www.java.domain)
下面是架構圖:

3、nginx配置文件代碼
server{ listen 80; server_name www.abc.com; #PHP處理的請求 location ^~ /php/ { rewrite ^/php/(.*)?(.*)$ /index.php?service=$1$2 break; #重寫到PHP處理(這里只是示例,大家根據自己路徑更改) try_files $uri @my_php; } #原來由java處理,現在改為PHP處理的請求 location ^~ /java/urione{ rewrite ^/java/urione(.*)$ /index.php?service=Other.GetTime$1 break; #重寫到PHP處理(這里只是示例,大家根據自己路徑更改) try_files $uri @my_php; }
#原來該java處理的,現在還是由java處理 location / { try_files $uri @my_java; } location @my_php { proxy_pass http://www.php.domain:80; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location @my_java { proxy_pass http://www.java.domain:80; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
