在 Windows 上使用 IIS 部署 PHP 專案

TomCzHen發表於2019-01-13

前言

如何選擇執行平臺需要從多方面考量,不想參與任何關於 Linux 與 Windows 的爭論,只是希望能更理性的看待問題,而不是毫無緣由的就否定一方。已經 9102 年了,不要把認知停留在 10 多年前的 Windows Server 2003 + IIS 6 時代,無論出於何種考量否定 Windows Server + IIS ,效能真的不能作為理由。

從 IIS 7 開始,使用 IOCP 模型與核心態執行的 http.sys 使 IIS 的效能提升非常大。同樣預設配置,純靜態檔案輸出效能甚至高於 Nginx。不過,雖然 Web Server 效能足夠,但 Windows Server 網路層效能確實比 Linux 差,考慮到 Linux 核心可以進一步調優,高負載下還是有可觀的效能差距存在。如果應用瓶頸不在網路層,那麼這個差距可以忽略。

功能方面,通過 IIS 整合的 Web Platform Installer (Web 平臺安裝程式) 安裝 URL Rewrite、Application Request Routing 元件之後,也可以實現 URL 重寫、反向代理、負載均衡、快取服務等功能。

平臺差異分析

PHP 部署方式分為三種:

  • Nginx + PHP-FPM
  • Apache + mod_php / mod_proxy_fcgi
  • IIS + PHP FastCGI

Nginx + PHP-FPM 與 IIS + PHP FastCGI 都可以看作 Web Server + FastCGI 的模式,差別在於 Nginx 與 FastCGI 之間多了一個 PHP-FPM(FastCGI 程式管理器)。Apache 也可以通過 mod_proxy_fcgi 搭配 PHP FastCGI,或者使用 mod_proxy_fcgi 搭配 PHP-FPM(High-performance PHP on apache httpd 2.4.x using mod_proxy_fcgi and php-fpm)。

另外還有一個關於執行緒安全的差異,即 NTS (Not Thread Safe) 與 TS (Thread Safe),可以在官方文件問答章節看到說明:

What does thread safety mean when downloading PHP?

Thread Safety means that binary can work in a multithreaded webserver context, such as Apache 2 on Windows. Thread Safety works by creating a local storage copy in each thread, so that the data won’t collide with another thread.

So what do I choose? If you choose to run PHP as a CGI binary, then you won’t need thread safety, because the binary is invoked at each request. For multithreaded webservers, such as IIS5 and IIS6, you should use the threaded version of PHP.

總結一下,對比 Windows 與 Linux 部署方式,除了 Web Server,最大的區別在於是否有 PHP-FPM ,而 PHP-FPM 暫時還沒有原生 Windows 版本,只能通過 Cygwin 的方式執行。

另外還需要考量的是 PHP 擴充套件,如果使用的擴充套件不支援 Windows 平臺,那麼可以直接放棄 Windows Server。

PHP On Windows

微軟專門開設了 PHP on Windows 網站 ,可以檢視相關的官方資料與技術支援文件。

安裝 IIS

Windows Server 系統需要通過伺服器管理新增 Web 伺服器角色。需要注意的是一定要勾選應用程式開發下的 CGI 支援

Windows 10 需要在 控制皮膚 中開啟 程式和功能 模組,通過左側的 啟用或關閉 Windows 功能 新增。但是要注意,非 Server 系統有一些限制,會影響 RPS 效能。

IIS 內建使用者組 IIS_IUSER,與 Linux 一樣,對應目錄需要有相應的許可權才能進行讀寫,對於安全要求非常高的情況下,需要每個站點進行使用者隔離,一般情況下使用 IIS_IUSER 足夠。

另外,Windows 系統分割槽許可權有一些特殊限制(與 SElinux 類似),一般使用者即使設定了 NTFS 寫入許可權,也仍然會有寫入問題存在。所以在非系統分割槽下存放專案可以避免很多不必要的麻煩。

關於配置 NTFS 檔案系統許可權的具體操作,請自行百度。

  • IIS 日誌

預設配置日誌儲存在系統盤路徑下,一般是 C:\inetpub\logs\LogFiles。可以在 IIS 管理器的根配置進行統一修改,也可以單獨針對站點配置。

推薦將日誌根目錄配置到非系統盤,按站點分日誌檔案,並配置為每天滾動更新。

  • 安裝 Web Platform Installer

www.microsoft.com/web/downloa…

一般情況下 IIS 已經安裝了該模組,如果沒有可以手動安裝。

  • 安裝 URL Rewrite 模組

www.iis.net/downloads/m…

部署 PHP 專案必須安裝的模組。

注:如果英語實在不行,可以在網頁上下載中文(Chinese Simplified)版本,確保安裝後的模組介面語言為中文。

  • 安裝 Application Request Routing 模組

www.iis.net/downloads/m…

對於一般 PHP 專案不是必須的,可以用於實現反向代理、代理快取、負載均衡等功能,該模組介面語言為英語。

安裝 PHP

Recommended Configuration on Windows systems

PHP 與微軟都推薦安裝的擴充套件 WinCache,可以與 OpCache 一同開啟,對提高效能有顯著效果。不過開啟 OpCache 與 WinCache 擴充套件可以有效提高效能,但是建議驗證部署成功後再開啟,以免因為快取存在排查問題陷入困難。

  • 下載 PHP For Windows

一般可以通過 Web Platform Installer 安裝,如果沒有需要的版本則需要手動下載。

開啟 windows.php.net/download/,下載需要的 PHP Non Thread Safe 版本即可。

需要注意版本名稱 VC15 x64 Non Thread Safe 表示依賴的 VC Runtime 版本,如果系統沒有安裝對應的 VC Runtime 將無法執行,頁面左側有對應的下載連線。

  • 安裝 PHP Manager For IIS

github.com/phpmanager/…

雖然可以手動註冊 PHP FastCGI,但是強烈建議使用 PHP Manager For IIS, 可以用於管理 PHP 配置、擴充套件也很方便。如果使用手動註冊 PHP FastCGI,需要在 IIS 管理介面中的預設文件手動新增 index.php

  • WinCache Extension for PHP

sourceforge.net/projects/wi…

WinCache 配置官方文件 php.net/manual/en/w…

OpCache 配置官方文件 php.net/manual/en/o…

PHP 配置

在 PHP Manager For IIS 中可以很方便的管理 PHP 的相關配置選項,也可以手動修改 php.ini 來進行配置。

臨時檔案
  • PHP FastCGI 錯誤日誌
  • 臨時檔案
  • session cache

PHP FastCGI 錯誤日誌預設路徑在 C:\WINDOWS\Temp 目錄下,生產環境需要在 PHP Manager For IIS 中配置伺服器型別為生產環境。

在 PHP 設定中 upload_tmp_dirsession.save_path 的路徑也都是 C:\WINDOWS\Temp。如果需要修改路徑,還需要注意目錄許可權問題。

上傳檔案限制

上傳檔案限制受以下因素影響:

  • Web Server
  • FastCGI

除了檔案大小限制之外,超時限制也會影響可上傳檔案大小。如果超時時間太短,頻寬不足以在超時之前上傳檔案,也會上傳失敗。另外還有檔案系統也可能造成上傳失敗,但是可能性比較小。

安全配置

微軟為 PHP On IIS 提供了詳細的安全實踐 Plan PHP Application Security | Microsoft Docs

  • 移除 Web Server 版本資訊

在 IIS 管理器根頁面,進入配置編輯器,找到 system.webServer/security/requestFiltering 下的 removeServerHeader 項,修改值為 True

可以在 HTTP 響應標頭 中新增一個自定義的 Server 頭,比如 Nginx

  • 移除 X-Powered-By PHP 版本資訊

在 PHP Manager For IIS 中配置 PHP 設定,修改 expose_phpOff

同樣,可以在 HTTP 響應標頭 中新增一個自定義的 X-Powered-By 頭,比如 Java

  • 請求篩選

請求篩選中可以設定Web Server 端允許的 URL 長度,Query String 長度。但是應用是否能接收到完整的資訊,還依賴與 PHP-FastCGI 的實現,以及 PHP 程式碼的實現。

通過請求篩選功能,可以阻止客戶端訪問特定路徑。如果使用了 Git 直接獲取程式碼用於部署,那麼最好把 .git 路徑遮蔽掉。如果有放程式碼壓縮包在目錄下的習慣,需要將特定路徑的 .rar.zip 檔案阻止訪問。

注意:一定不要開啟目錄瀏覽功能。

其他

如果需要同時執行不同版本的站點,或者每個站點擁有單獨的 php.ini 配置檔案,可以參考微軟文件 Configure PHP Application Security | Microsoft Docs 操作。

再次提醒,本文中關於目錄許可權的做法並不是最安全的實踐,為了便利而有所妥協。

來源:https://juejin.im/post/5c3b05a5e51d45518d46ce67

相關文章