戰(zhàn):從安裝配置到端口放行與排錯(cuò))
簡(jiǎn)介這份PDF資料面向需要在Windows服務(wù)器上部署.NET WebApi的開發(fā)者與運(yùn)維人員聚焦IIS環(huán)境搭建與端口開放這一常見落地難題。內(nèi)容從服務(wù)器管理器添加角色和功能入手逐步講解勾選Web服務(wù)器(IIS)、補(bǔ)齊.NET Framework 3.5與4.5組件、勾選管理工具等關(guān)鍵環(huán)節(jié)并延伸至站點(diǎn)、應(yīng)用程序池與虛擬目錄的配置幫助讀者打通從發(fā)布到外部訪問(wèn)的完整鏈路。資源包共1個(gè)PDF文件約536KB篇幅緊湊、步驟清晰適合作為部署時(shí)的對(duì)照手冊(cè)。目前已有341人學(xué)習(xí)下載說(shuō)明其在同類實(shí)操場(chǎng)景中具備一定參考價(jià)值。讀者可據(jù)此快速完成IIS安裝、應(yīng)用池配置與端口開放減少因組件缺失或配置不當(dāng)導(dǎo)致的部署失敗提升上線效率。1. 從一次“本地跑通、服務(wù)器 404”說(shuō)起IIS 托管 .NET WebApi 到底要過(guò)幾道關(guān)本地 IIS Express 里 Swagger 頁(yè)面刷得飛起一放到 Windows 服務(wù)器的 IIS 上瀏覽器直接甩回一個(gè) 404.0或者更氣人的是 500.19——配置文件明明沒動(dòng)過(guò)。這個(gè)場(chǎng)景我見過(guò)太多次問(wèn)題基本不在代碼而在 IIS 的角色、功能、應(yīng)用程序池和端口這四件事上沒對(duì)齊。.NET WebApi 發(fā)布到 Windows 服務(wù)器并開放端口本質(zhì)就是讓 IIS 認(rèn)識(shí)你的運(yùn)行時(shí)、給你的站點(diǎn)分配一個(gè)獨(dú)立進(jìn)程、再讓防火墻放行外部請(qǐng)求。這套流程適合手里有臺(tái) Windows Server、想把接口服務(wù)正式掛上去的后端和運(yùn)維同學(xué)也適合第一次從 IIS Express 切到完整 IIS 的開發(fā)者。下面按“裝 IIS → 配站點(diǎn) → 排錯(cuò) → 驗(yàn)證”的順序拆開講每一步都落到能直接抄的界面路徑和命令上。2. 裝 IIS 不是一路下一步角色服務(wù)勾選與 .NET 版本對(duì)齊IIS 的安裝向?qū)Э雌饋?lái)只是點(diǎn)幾下但真正決定后面能不能跑起來(lái)的是角色服務(wù)里那幾個(gè)勾。很多人裝完 IIS 發(fā)現(xiàn)站點(diǎn)起不來(lái)回頭一看要么是 .NET Framework 的版本沒勾全要么是管理工具沒裝導(dǎo)致連 IIS 管理器都打不開。這一章把安裝路徑和勾選邏輯講清楚順帶說(shuō)明為什么 .NET 3.5 和 4.x 要一起勾。2.1 添加角色和功能從服務(wù)器管理器進(jìn)入安裝向?qū)г?Windows Server 上IIS 不是單獨(dú)下載的安裝包而是通過(guò)“服務(wù)器管理器”里的“添加角色和功能”來(lái)裝。打開左下角第二個(gè)圖標(biāo)進(jìn)入服務(wù)器管理器點(diǎn)擊頂部“管理”菜單選擇“添加角色和功能”后面按向?qū)ё?。安裝類型選“基于角色或功能的安裝”服務(wù)器選擇默認(rèn)的本機(jī)即可。到“服務(wù)器角色”這一步勾選Web 服務(wù)器(IIS)。勾上的瞬間通常會(huì)彈出一個(gè)確認(rèn)框提示需要一并添加 IIS 管理控制臺(tái)等依賴功能點(diǎn)“添加功能”就行。這一步別跳過(guò)否則后面 IIS 管理器可能根本不在開始菜單里。# 如果習(xí)慣命令行也可以用 PowerShell 一次性裝 IIS 核心角色 # 注意這條命令裝的是基礎(chǔ) Web 服務(wù)器角色.NET 相關(guān)功能需要額外指定 Install-WindowsFeature -Name Web-Server -IncludeManagementTools # 查看當(dāng)前已安裝的 IIS 相關(guān)功能確認(rèn)角色是否落地 Get-WindowsFeature -Name Web-* | Where-Object { $_.Installed -eq $true }上面第一條命令里-IncludeManagementTools很關(guān)鍵它對(duì)應(yīng)圖形界面里“管理工具”那一組勾選不裝的話后面沒有 IIS 管理器可用。第二條命令用來(lái)回查輸出里帶[X]的才是已安裝項(xiàng)。如果你在圖形界面操作等價(jià)路徑就是在“角色服務(wù)”頁(yè)把“管理工具”下的 IIS 管理控制臺(tái)、IIS 管理腳本和工具全部勾上。2.2 .NET Framework 3.5 與 4.x 功能為什么兩個(gè)都要勾在“功能”節(jié)點(diǎn)下會(huì)看到.NET Framework 3.5 功能和.NET Framework 4.5 功能不同系統(tǒng)版本顯示為 4.x。這里有個(gè)血淚經(jīng)驗(yàn)很多人只勾了 4.x結(jié)果部署老一點(diǎn)的 WebApi 項(xiàng)目或者某些依賴 3.5 運(yùn)行時(shí)的組件時(shí)直接報(bào)錯(cuò)。穩(wěn)妥做法是把兩個(gè)大版本下的子項(xiàng)全部展開勾滿尤其是WCF 服務(wù)和HTTP 激活這兩類它們和 WebApi 的托管管道直接相關(guān)。功能節(jié)點(diǎn)必須勾選的子項(xiàng)不勾的后果.NET Framework 3.5 功能WCF HTTP 激活、WCF 非 HTTP 激活老項(xiàng)目或部分依賴報(bào) 500.19.NET Framework 4.5 功能WCF 服務(wù)、ASP.NET 4.xWebApi 托管管道無(wú)法加載IIS 角色服務(wù)管理工具全部、應(yīng)用程序開發(fā)里的 ASP.NET 4.xIIS 管理器缺失或站點(diǎn) 404勾選時(shí)注意每個(gè)可展開的下級(jí)選項(xiàng)框也要點(diǎn)開確認(rèn)向?qū)J(rèn)只勾父級(jí)、子級(jí)經(jīng)常是半選狀態(tài)。全部確認(rèn)后點(diǎn)“下一步”再點(diǎn)“安裝”等待進(jìn)度條走完。裝完后建議重啟一次服務(wù)器讓運(yùn)行時(shí)注冊(cè)徹底生效。2.3 驗(yàn)證安裝結(jié)果三個(gè)必查項(xiàng)裝完別急著建站點(diǎn)先做三個(gè)檢查。第一開始菜單里能不能找到“Internet Information Services (IIS) 管理器”第二瀏覽器訪問(wèn)http://localhost是否出現(xiàn) IIS 默認(rèn)歡迎頁(yè)第三在 IIS 管理器里點(diǎn)開“應(yīng)用程序池”看 .NET CLR 版本下拉里有沒有 v4.0。# 在服務(wù)器上快速驗(yàn)證 IIS 是否在監(jiān)聽 80 端口 netstat -ano | findstr :80 # 查看 IIS 服務(wù)狀態(tài)W3SVC 是核心 Web 服務(wù) sc query W3SVCnetstat那條如果看到0.0.0.0:80處于 LISTENING說(shuō)明 IIS 已經(jīng)在監(jiān)聽所有網(wǎng)卡的 80 端口。sc query W3SVC返回 RUNNING 才算服務(wù)正常。這兩條都過(guò)了再往下走站點(diǎn)配置能省掉一半“為什么訪問(wèn)不了”的排查時(shí)間。3. 建站點(diǎn)、配應(yīng)用程序池、放行端口讓外部請(qǐng)求真正進(jìn)來(lái)IIS 裝好只是有了托管環(huán)境真正讓 WebApi 跑起來(lái)還需要建站點(diǎn)、指定物理路徑、配應(yīng)用程序池最后在防火墻放行端口。這一章按操作順序走每一步都說(shuō)明參數(shù)怎么填、為什么這么填。3.1 添加網(wǎng)站物理路徑與綁定端口的填法打開 IIS 管理器左側(cè)展開服務(wù)器節(jié)點(diǎn)右鍵“網(wǎng)站”選“添加網(wǎng)站”。彈窗里幾個(gè)字段別填錯(cuò)網(wǎng)站名稱自己認(rèn)得就行比如MyWebApiSite不要用中文和空格。物理路徑指向你發(fā)布輸出的文件夾比如D:\publish\MyWebApi。注意是發(fā)布后的目錄不是項(xiàng)目源碼目錄。綁定類型選httpIP 地址選“全部未分配”表示監(jiān)聽本機(jī)所有網(wǎng)卡端口填一個(gè)沒被占用的比如8080。如果你有域名主機(jī)名可以填上沒有就留空。!-- 發(fā)布后的 web.config 里aspNetCore 或 system.webServer 節(jié)點(diǎn)決定了 IIS 如何托管 -- configuration system.webServer handlers !-- 如果是 ASP.NET Core 項(xiàng)目需要 AspNetCoreModuleV2 處理器 -- add nameaspNetCore path* verb* modulesAspNetCoreModuleV2 resourceTypeUnspecified / /handlers aspNetCore processPathdotnet arguments.\MyWebApi.dll stdoutLogEnabledfalse hostingModelinprocess / /system.webServer /configuration上面這段是 ASP.NET Core 項(xiàng)目發(fā)布后web.config的典型結(jié)構(gòu)。hostingModelinprocess表示進(jìn)程內(nèi)托管性能更好但要求服務(wù)器裝了對(duì)應(yīng)的 ASP.NET Core 運(yùn)行時(shí)。如果是傳統(tǒng) .NET Framework 的 WebApiweb.config里則是system.web和system.webServer的常規(guī)配置不需要aspNetCore節(jié)點(diǎn)。填完點(diǎn)“確定”站點(diǎn)就出現(xiàn)在左側(cè)列表里。3.2 應(yīng)用程序池.NET CLR 版本與托管管道模式站點(diǎn)建好后IIS 會(huì)自動(dòng)創(chuàng)建一個(gè)同名應(yīng)用程序池。點(diǎn)開“應(yīng)用程序池”找到它右鍵“基本設(shè)置”。這里兩個(gè)參數(shù)最關(guān)鍵.NET CLR 版本傳統(tǒng) .NET Framework 項(xiàng)目選v4.0.30319ASP.NET Core 項(xiàng)目選“無(wú)托管代碼”。托管管道模式選“集成”不要選“經(jīng)典”。經(jīng)典模式走的是老式 ISAPI 管道WebApi 的路由和中間件容易出問(wèn)題。項(xiàng)目類型.NET CLR 版本托管管道模式.NET Framework WebApiv4.0.30319集成ASP.NET Core WebApi無(wú)托管代碼集成選錯(cuò) CLR 版本的典型現(xiàn)象是站點(diǎn)一訪問(wèn)就 503應(yīng)用程序池自動(dòng)停止。這時(shí)候去“事件查看器 → Windows 日志 → 應(yīng)用程序”里能看到具體的加載失敗原因。改完基本設(shè)置后右鍵應(yīng)用程序池選“回收”讓新配置生效。3.3 防火墻放行入站規(guī)則與端口測(cè)試站點(diǎn)在服務(wù)器本機(jī)訪問(wèn)通了不代表外部能訪問(wèn)。Windows 防火墻默認(rèn)攔掉大部分入站端口。打開“高級(jí)安全 Windows Defender 防火墻”新建入站規(guī)則類型選“端口”協(xié)議 TCP特定本地端口填你站點(diǎn)綁定的端口比如 8080操作選“允許連接”配置文件三個(gè)都勾上最后起個(gè)名字。# 用 PowerShell 新建入站規(guī)則放行 8080 端口 New-NetFirewallRule -DisplayName MyWebApi 8080 -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow # 查看規(guī)則是否生效 Get-NetFirewallRule -DisplayName MyWebApi 8080 | Select-Object DisplayName, Enabled, Direction, Action第一條命令里-Direction Inbound表示入站-LocalPort 8080要和站點(diǎn)綁定端口一致。第二條用來(lái)確認(rèn)規(guī)則已啟用。放行后從另一臺(tái)機(jī)器用瀏覽器或curl訪問(wèn)http://服務(wù)器IP:8080/接口路徑能返回?cái)?shù)據(jù)就說(shuō)明端口通了。如果還不行回到服務(wù)器上用netstat -ano | findstr :8080確認(rèn) IIS 確實(shí)在監(jiān)聽這個(gè)端口而不是只監(jiān)聽了 localhost。4. 避坑與排查IIS 部署 WebApi 最常見的五個(gè)翻車點(diǎn)這一章按“現(xiàn)象 → 原因 → 解決”整理五個(gè)高頻問(wèn)題都是實(shí)際部署里反復(fù)遇到的。遇到報(bào)錯(cuò)先對(duì)照這里能省下大量翻日志的時(shí)間。4.1 現(xiàn)象訪問(wèn)返回 500.19配置錯(cuò)誤原因web.config里引用了 IIS 沒安裝的模塊比如 ASP.NET Core 項(xiàng)目缺少 AspNetCoreModuleV2或者 .NET Framework 版本沒勾全導(dǎo)致system.webServer節(jié)點(diǎn)無(wú)法識(shí)別。解決先看錯(cuò)誤頁(yè)里具體是哪個(gè)配置節(jié)報(bào)錯(cuò)。如果是 ASP.NET Core去微軟官網(wǎng)下載對(duì)應(yīng)版本的 Hosting Bundle 裝上裝完在命令行執(zhí)行net stop was /y再net start w3svc重啟 IIS。如果是 .NET Framework回到“添加角色和功能”里把對(duì)應(yīng)版本的 WCF 和 ASP.NET 子項(xiàng)補(bǔ)勾。4.2 現(xiàn)象訪問(wèn)返回 404.0但本機(jī) localhost 能通原因路由前綴或站點(diǎn)物理路徑不對(duì)。常見的是發(fā)布目錄里多了一層文件夾導(dǎo)致 IIS 的根指向了錯(cuò)誤位置或者 WebApi 的路由配置帶了前綴訪問(wèn)時(shí)沒加。解決在 IIS 管理器里點(diǎn)站點(diǎn)右側(cè)“基本設(shè)置”確認(rèn)物理路徑指向的是包含web.config和bin的那一層。然后用http://localhost:端口/實(shí)際路由在本機(jī)測(cè)通了再換服務(wù)器 IP 測(cè)。如果本機(jī) localhost 也不通問(wèn)題在應(yīng)用本身不在 IIS。4.3 現(xiàn)象應(yīng)用程序池自動(dòng)停止事件日志報(bào) 503原因應(yīng)用程序池的 .NET CLR 版本和項(xiàng)目不匹配或者進(jìn)程啟動(dòng)時(shí)崩潰。ASP.NET Core 項(xiàng)目如果 CLR 版本選了 v4.0就會(huì)因?yàn)檎也坏酵泄苋肟诙磸?fù)重啟。解決把應(yīng)用程序池的 .NET CLR 版本改成“無(wú)托管代碼”ASP.NET Core或v4.0.30319.NET Framework。改完回收應(yīng)用程序池。如果還停去事件查看器看“應(yīng)用程序”日志里的具體異常通常是缺少運(yùn)行時(shí)或依賴文件。4.4 現(xiàn)象外部機(jī)器訪問(wèn)超時(shí)服務(wù)器本機(jī)正常原因防火墻沒放行端口或者云服務(wù)器還有一層安全組規(guī)則沒開。解決先在服務(wù)器上用netstat -ano | findstr :端口確認(rèn)監(jiān)聽地址是0.0.0.0而不是127.0.0.1。如果是127.0.0.1說(shuō)明站點(diǎn)綁定里 IP 地址選了具體回環(huán)地址改成“全部未分配”。然后檢查 Windows 防火墻入站規(guī)則再檢查云平臺(tái)的安全組。兩層都放行后用telnet 服務(wù)器IP 端口從外部測(cè)連通性。4.5 現(xiàn)象接口返回 500但日志里沒有堆棧原因IIS 默認(rèn)不把詳細(xì)錯(cuò)誤發(fā)給外部客戶端只返回一個(gè)籠統(tǒng)的 500。開發(fā)環(huán)境能看到堆棧生產(chǎn)環(huán)境看不到。解決臨時(shí)在web.config里把customErrors設(shè)為Off.NET Framework或在launchSettings之外配置詳細(xì)錯(cuò)誤頁(yè)ASP.NET Core復(fù)現(xiàn)一次拿到堆棧后立刻改回去。更穩(wěn)妥的做法是配好日志組件把異常寫到文件里不依賴 IIS 的錯(cuò)誤頁(yè)。注意生產(chǎn)環(huán)境不要長(zhǎng)期開著詳細(xì)錯(cuò)誤排查完就關(guān)避免泄露內(nèi)部路徑和堆棧信息。5. 進(jìn)階驗(yàn)證用 curl 和日志把“端口開放”這件事坐實(shí)部署完最怕的是“以為通了”。我一般會(huì)走一套固定驗(yàn)證流程從本機(jī)到外部、從端口到接口、從響應(yīng)到日志全部過(guò)一遍才算完。這一章把這套流程拆成可復(fù)制的命令和檢查點(diǎn)。5.1 三層驗(yàn)證端口、站點(diǎn)、接口第一層驗(yàn)端口在服務(wù)器上執(zhí)行netstat -ano | findstr :8080確認(rèn)狀態(tài)是 LISTENING 且地址是0.0.0.0。第二層驗(yàn)站點(diǎn)在服務(wù)器瀏覽器訪問(wèn)http://localhost:8080看是否返回 IIS 默認(rèn)頁(yè)或應(yīng)用首頁(yè)。第三層驗(yàn)接口用curl帶完整路徑請(qǐng)求一個(gè)具體 API。# 從外部機(jī)器驗(yàn)證接口連通性-i 顯示響應(yīng)頭-v 顯示詳細(xì)過(guò)程 curl -i -X GET http://服務(wù)器IP:8080/api/values -H Accept: application/json # 如果接口需要 POST用 -d 帶 JSON 體 curl -i -X POST http://服務(wù)器IP:8080/api/values -H Content-Type: application/json -d {\name\:\test\}-i能看到 HTTP 狀態(tài)碼和響應(yīng)頭-v在連接失敗時(shí)能看出是卡在 TCP 握手還是 TLS 協(xié)商。如果返回 200 且 body 是預(yù)期 JSON說(shuō)明端口、站點(diǎn)、接口三層全通。如果返回 401 或 403說(shuō)明通了但認(rèn)證沒過(guò)那是應(yīng)用層的事和 IIS 部署無(wú)關(guān)。5.2 日志落盤讓每次請(qǐng)求都有跡可循IIS 自帶請(qǐng)求日志默認(rèn)在C:\inetpub\logs\LogFiles下按站點(diǎn)分目錄。開啟方法是點(diǎn)站點(diǎn)右側(cè)“日志”圖標(biāo)確認(rèn)“啟用”勾上格式選 W3C。應(yīng)用層的日志則取決于你用的框架ASP.NET Core 常用 Serilog 或 NLog 寫到文件。// ASP.NET Core 里用 Serilog 寫文件日志的最小配置 Log.Logger new LoggerConfiguration() .WriteTo.File(logs/mywebapi-.log, rollingInterval: RollingInterval.Day) .CreateLogger(); // 在 Program.cs 里掛上 builder.Host.UseSerilog();rollingInterval: RollingInterval.Day表示按天切分日志文件方便排查某一天的請(qǐng)求。掛上之后每次接口調(diào)用都會(huì)在logs目錄下留記錄配合 IIS 的請(qǐng)求日志能定位到是請(qǐng)求沒到 IIS、到了 IIS 沒進(jìn)應(yīng)用、還是進(jìn)了應(yīng)用報(bào)的錯(cuò)。5.3 一個(gè)我常犯的錯(cuò)改完配置忘了回收最后說(shuō)個(gè)習(xí)慣問(wèn)題。IIS 的很多配置改完不會(huì)自動(dòng)生效尤其是應(yīng)用程序池的 CLR 版本和web.config的改動(dòng)。我早期經(jīng)常改完web.config直接刷新瀏覽器結(jié)果還是舊行為折騰半天才發(fā)現(xiàn)要回收應(yīng)用程序池?,F(xiàn)在我的固定動(dòng)作是改完配置 → 右鍵應(yīng)用程序池“回收” → 再測(cè)。如果是 ASP.NET Core 改了web.config還要執(zhí)行net stop was /y net start w3svc重啟 IIS 才能讓新配置加載。從那以后我每次部署完都強(qiáng)制走一遍“回收 重啟 curl 驗(yàn)證”三步再也沒出現(xiàn)過(guò)“明明改了卻沒生效”的玄學(xué)問(wèn)題。希望這套流程幫到你。本文還有配套的精品資源點(diǎn)擊獲取