【茶包射手日記】在 ASP.NET MVC 站台使用 IIS ARR
3 |
收到需求,A 網站某個目錄的內容想改從 B 網站取得,但 URL 要維持 A 的主機名稱。例如: 讓 httq://serverA/SomePath 顯示 httq://serverB/SomePath 的內容,但 URL 保持 httq://serverA/SomePath。 IIS 有個 ARR (Application Request Routing) 模組,可以輕鬆實現類似需求。
關於 ARR 的基本概念與安裝設定,可參考以下文章,在此:
- 如何利用 IIS7 的 ARR 模組實做 Reverse Proxy 機制 by 保哥
年代有點悠久,但基本觀念相去不遠 - 設定Reserve Proxy在Windows、Mac
這篇有 Win10 / IIS10 設定畫面可以參考
用 Platform Installer 安裝 ARR 是最簡便的做法,依照慣例,我又被卡在伺服器不能連 Internet 下載套件必須另謀他法。 ARR 得依賴 External Disk Cache、Request Router、Url Rewriter 等套件執行(以前還需要 Web Farm Framework,現已不用),疼惜上網處處受挫的苦命人,微軟有個四合一組合包 Application Request Routing 3.0 Stand-alone package (IExpress) x64 讓安裝程序可以簡單一些:
2023-09-13 更新:四合一安裝懶人包已無法下載,請參考IIS ARR (Application Request Routing) 安裝 2023 版
在 Windows 2016 安裝實測,我遇上亂流 - 找不到傳說中的 「Application Request Routing Cache」圖示,後來雖然有設定成功,但圖示始終沒出現過。
Stackoverflow 有篇相似討論,照著重新安裝仍無法解決問題。所幸,Url Rewrite 第一次新增 Reverse Proxy 時會提示,詢問要不要自動啟用 ARR Proxy:
回答 OK 後在新開的空白站台測試 Reverse Proxy 規則,一舉成功,士氣大振,準備在 MVC 專案站台啟用卻踼到鐵板。
在實驗站台可以運作的導向規則,原封不動搬到 MVC 站台卻得到 HTTP 404。測試改用 Redirect 或 Custom Response 動作有反應,代表 URL 比對條件沒問題:
同樣的規則,一個站台可行另一個失敗,推測是 web.config 某條設定導致 Url Rewrite 失效。祭出最笨但絕對有效的調查手法 - 將整個 MVC 站台另複製一份,修改 web.config 逐一移掉可疑設定反覆測試,觀察移掉什麼設定後問題消失,答案便可揭曉。
從嫌疑最高的 <handlers> 區開始,很快抓到兇手:
<handlers>
<!-- //...略.... -->
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*"
type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
ExtensionlessUrlHandler 是 ASP.NET MVC 4.0 引進用來處理「無副檔名 HTTP 要求」的處理器(延伸閱讀:ASP.NET MVC 4 在 .NET 4.0 與 .NET 4.5 的專案範本差異 by 保哥),猜想原本該由 Url Write 導向的請求是被它攔截,在比對 MVC 路由表無符合項目後,吐回 HTTP 404。
知道原因,要解決就不是難事。我選擇在 App_Start/RouteConfig.aspx 加入以下邏輯:
public class RouteConfig
{
static List<string> ARRPathsToIgnore =
ConfigurationManager.AppSettings.AllKeys.Where(o => o.StartsWith("arr:"))
.Select(o => ConfigurationManager.AppSettings[o]).ToList();
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
ARRPathsToIgnore.ForEach(o =>
{
routes.IgnoreRoute(o + "/{*pathInfo}");
});
之後便可在 web.config 以 appSetting 排除要交給 ARR 要導向的路徑:
<!-- ARR 忽略目錄 -->
<add key="arr:Rule1Name" value="Rule1Path" />
<add key="arr:Rule2Name" value="Rule2Path" />
</appSettings>
經過這番修改,終於成功在 MVC 站台啟用 ARR,又學到一項新把戲。
Tips of installing ARR(Application Request Routing) without Internet and hwo to setup ASP.NET MVC routing to support ARR.
Comments
# by JimmyHo
突然發現自己文章 「設定Reserve Proxy在Windows、Mac」 被黑大引用,真的深感榮幸
# by Calvin
黑大: 下載網址有變更唷,https://www.microsoft.com/en-us/download/details.aspx?id=47333
# by Jeffrey
to Clavin, 謝謝通知,已更新。