摘要:說明開發(fā)和調(diào)試環(huán)境為本地中的,環(huán)境為本地下的。再次在容器中抓取端口數(shù)據(jù)包連接的源地址已經(jīng)正確再次使用的斷點調(diào)試時,控制臺如下所以,使用進行遠程調(diào)試時,需要選擇合適的調(diào)試模式,在下建議使用遠程模式。
首發(fā)于 樊浩柏科學(xué)院
我們經(jīng)常會使用 PhpStorm 結(jié)合 Xdebug 進行代碼斷點調(diào)試,這樣能追蹤程序執(zhí)行流程,方便調(diào)試代碼和發(fā)現(xiàn)潛在問題。博主將開發(fā)環(huán)境遷入 Docker 后,Xdebug 調(diào)試遇到了些問題,在這里整理出 Docker 中使用 Xdebug 的方法和注意事項。
說明:開發(fā)和調(diào)試環(huán)境為本地 Docker 中的 LNMP,IDE 環(huán)境為本地 Win10 下的 PhpStorm。這種情況下 Xdebug 屬于遠程調(diào)試模式,IDE 和本地 IP 為 192.168.1.101,Docker 中 LNMP 容器 IP 為 172.17.0.2。問題描述
在 Docker 中安裝并配置完 Xdebug ,并設(shè)置 PhpStorm 中對應(yīng)的 Debug 參數(shù)后,但是 Debug 并不能正常工作。
此時,php.ini中 Xdebug 配置如下:
xdebug.idekey = phpstorm xdebug.remote_enable = on xdebug.remote_connect_back = on xdebug.remote_port = 9001 //PhpStorm監(jiān)聽本地9001端口 xdebug.remote_handler = dbgp xdebug.remote_log = /home/tmp/xdebug.log
開始收集問題詳細(xì)表述。首先,觀察到 PhpStorm 的 Debug 控制臺出現(xiàn)狀態(tài):
Waiting for incoming connection with ide key ***
然后查看 Xdebug 調(diào)試日志xdebug.log,存在如下錯誤:
I: Checking remote connect back address. I: Checking header "HTTP_X_FORWARDED_FOR". I: Checking header "REMOTE_ADDR". I: Remote address found, connecting to 172.17.0.1:9001. W: Creating socket for "172.17.0.1:9001", poll success, but error: Operation now in progress (29). E: Could not connect to client. :-(分析問題
查看這些問題表述,基本上可以定位為 Xdebug 和 PhpStorm 之間的 網(wǎng)絡(luò)通信 問題,接下來一步步定位具體問題。
排查本地9001端口Win 下執(zhí)行 netstat -ant命令:
協(xié)議 本地地址 外部地址 狀態(tài) 卸載狀態(tài) TCP 0.0.0.0:9001 0.0.0.0:0 LISTENING InHost
端口 9001 監(jiān)聽正常,然后在容器中使用 telnet 嘗試同本地 9001 端口建立 TCP 連接:
$ telnet 192.168.1.101 9001 Trying 192.168.1.101... Connected to 192.168.1.101. Escape character is "^]".
說明容器同本地 9001 建立 TCP 連接正常,但是 Xdebug 為什么會報連接失敗呢?此時,至少可以排除不會是因為 PhpStorm 端配置的問題。
排查Xdebug問題回過頭來看看 Xdebug 的錯誤日志,注意觀察到失敗時的連接信息:
I: Remote address found, connecting to 172.17.0.1:9001. W: Creating socket for "172.17.0.1:9001", poll success, but error: Operation now in progress (29). E: Could not connect to client. :-(
此時,在容器中使用 tcpdump 截獲的數(shù)據(jù)包如下:
$ tcpdump -nnA port 9001 # 嘗試建立連接,但是失敗了 12:20:34.318080 IP 172.17.0.2.40720 > 172.17.0.1.9001: Flags [S], seq 2365657644, win 29200, options [mss 1460,sackOK,TS val 833443 ecr 0,nop,wscale 7], length 0 E..<..@.@.=...........#)...,......r.XT......... ............ 12:20:34.318123 IP 172.17.0.1.9001 > 172.17.0.2.40720: Flags [R.], seq 0, ack 2365657645, win 0, length 0 E..(.]@.@..M........#).........-P....B..
可以確定的是, Xdebug 是向 IP 為 172.17.0.1 且端口為 9001 的目標(biāo)機器嘗試建立 TCP 連接,而非正確的 192.168.1.101 本地 IP。到底發(fā)生了什么?
首先,為了搞懂 Xdebug 和 PhpStorm 的交互過程,查了 官方手冊 得知,Xdebug 工作在遠程調(diào)試模式時,有兩種工作方式:
1、IDE 所在機器 IP 確定/單人開發(fā)
圖中,由于 IDE 的 IP 和監(jiān)聽端口都已知,所以 Xdebug 端可以很明確知道 DBGP 交互時 IDE 目標(biāo)機器信息,所以 Xdebug 只需配置 xdebug.remote_host、xdebug.remote_port 即可。
2、IDE 所在機器 IP 未知/團隊開發(fā)
由于 IDE 的 IP 未知或者 IDE 存在多個 ,那么 Xdebug 無法提前預(yù)知 DBGP 交互時的目標(biāo) IP,所以不能直接配置 xdebug.remote_host 項(remote_port 項可以確定),必須設(shè)置 xdebug.remote_connect_back 為 On 標(biāo)識(會忽略 xdebug.remote_host 項)。這時,Xdebug 會優(yōu)先獲取 HTTP_X_FORWARDED_FOR 和 REMOTE_ADDR 中的一個值作為通信時 IDE 端的目標(biāo) IP,通過Xdebug.log記錄可以確認(rèn)。
I: Checking remote connect back address. I: Checking header "HTTP_X_FORWARDED_FOR". I: Checking header "REMOTE_ADDR". I: Remote address found
接下來,可以知道 Xdebug 端是工作在遠程調(diào)試的模式 2 上,Xdebug 會通過 HTTP_X_FORWARDED_FOR 和 REMOTE_ADDR 項獲取目標(biāo)機 IP。Docker 啟動容器時已經(jīng)做了 80 端口映射,忽略宿主機同 Docker 容器復(fù)雜的數(shù)據(jù)包轉(zhuǎn)發(fā)規(guī)則,先截取容器 80 端口數(shù)據(jù)包:
$ tcpdump -nnA port 80 # 請求信息 13:30:07.017770 IP 172.17.0.1.33976 > 172.17.0.2.80: Flags [P.], seq 1:208, ack 1, win 229, options [nop,nop,TS val 1250713 ecr 1250713], length 207 E....=@.@..............P.. .+.......Y...... ........GET /v2/room/list.json HTTP/1.1 Accept: */* Cache-Control: no-cache Host: localhost Connection: Keep-Alive User-Agent: Apache-HttpClient/4.5.2 (Java/1.8.0_152-release) Accept-Encoding: gzip,deflate
可以看出,數(shù)據(jù)包的源地址為 172.17.0.1,并非真正的源地址 192.168.1.101,HTTP 請求頭中也無 HTTP_X_FORWARDED_FOR 項。
說明:172.17.0.1 實際為 Docker 創(chuàng)建的虛擬網(wǎng)橋 docker0 的地址 ,也是所有容器的默認(rèn)網(wǎng)關(guān)。Docker 網(wǎng)絡(luò)通信方式默認(rèn)為 Bridge 模式,通信時宿主機會對數(shù)據(jù)包進行 SNAT 轉(zhuǎn)換,進而源地址變?yōu)?docker0,那么,怎么在 Docker 里獲取客戶端真正 IP 呢?。定位根源
最后,可以確定由于 HTTP_X_FORWARDED_FOR 未定義,因此 Xdebug 會取 REMOTE_ADDR 為 IDE 的 IP,同時由于 Docker 特殊的網(wǎng)絡(luò)轉(zhuǎn)發(fā)規(guī)則,導(dǎo)致 REMOTE_ADDR 變更為網(wǎng)關(guān) IP,所以 Xdebug 同 PhpStorm 進行 DBGP 交互會失敗。
解決問題由于 Docker 容器里獲取真正客戶端 IP 比較復(fù)雜,這里使用 Xdebug 的 遠程模式 1 明確 IDE 端 IP 來規(guī)避源 IP 被修改的情況,最終解決 Xdebug 調(diào)試問題。
模式 1 的 Xdebug 主要配置為:
//并沒有xdebug.remote_connect_back項 xdebug.idekey = phpstorm xdebug.remote_enable = on xdebug.remote_host = 192.168.1.101 xdebug.remote_port = 9001 xdebug.remote_handler = dbgp
重啟 php-fpm,使用php --ri xdebug確定無誤,使用 PhpStorm 重新進行調(diào)試。
再次在容器中 tcpdump 抓取 9001 端口數(shù)據(jù)包:
# 連接的源地址已經(jīng)正確 14:05:27.379783 IP 172.17.0.2.44668 > 192.168.1.101.9001: Flags [S], seq 3444466556, win 29200, options [mss 1460,sackOK,TS val 1462749 ecr 0,nop,wscale 7], length 0 E..<2.@.@..........e.|#).Nc|......r.nO......... ..Q.........
再次使用 PhpStorm 的 REST Client 斷點調(diào)試 API 時, Debug 控制臺如下:
所以,使用 Xdebug 進行遠程調(diào)試時,需要選擇合適的調(diào)試模式,在 Docker 下建議使用遠程模式 1。
其他注意事項Xdebug 版本和 PHP 版本一致
并不是每個 Xdebug 版本都適配 PHP 每個版本,可以直接使用 官方工具,選擇合適的 Xdebug 版本。
本地文件和遠端文件映射關(guān)系
如上圖,在使用 PhpStorm 時進行遠程調(diào)試時,需要配置本地文件和遠端文件的目錄映射關(guān)系,這樣 IDE 才能根據(jù) Xdebug 傳遞的當(dāng)前執(zhí)行文件路徑與本地文件做匹配,實現(xiàn)斷點調(diào)試和單步調(diào)試等。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/29832.html
摘要:說明開發(fā)和調(diào)試環(huán)境為本地中的,環(huán)境為本地下的。再次在容器中抓取端口數(shù)據(jù)包連接的源地址已經(jīng)正確再次使用的斷點調(diào)試時,控制臺如下所以,使用進行遠程調(diào)試時,需要選擇合適的調(diào)試模式,在下建議使用遠程模式。 首發(fā)于 樊浩柏科學(xué)院 我們經(jīng)常會使用 PhpStorm 結(jié)合 Xdebug 進行代碼斷點調(diào)試,這樣能追蹤程序執(zhí)行流程,方便調(diào)試代碼和發(fā)現(xiàn)潛在問題。博主將開發(fā)環(huán)境遷入 Docker 后,Xd...
摘要:連接容器內(nèi)的進行斷點調(diào)試進行斷點調(diào)試盡管不像其他語言那樣方便,但是有些是有確實有其用處,比如調(diào)試循環(huán)內(nèi)的數(shù)據(jù)異常時。 PhpStorm連接容器內(nèi)的XDebug進行斷點調(diào)試 php進行斷點調(diào)試盡管不像其他語言那樣方便,但是有些是有確實有其用處,比如調(diào)試循環(huán)內(nèi)的數(shù)據(jù)異常時。在php于phpstorm都安裝在同一環(huán)境下時,配置phpstorm的xdebug調(diào)試并不是多困難的事情,但是如果你使...
摘要:這樣就配置好了安裝插件監(jiān)聽地址開啟小電話以后,如果訪問會自動進入斷點中的模式,這樣我們的開發(fā)環(huán)境的斷點調(diào)試就已經(jīng)配置好了。 docker-compose環(huán)境來自:https://github.com/zhaojunlik...原文:http://blog.oeynet.com/post/9... 說明 在開發(fā)中,斷點調(diào)試是我們最快能找出Bug代碼問題的所在,那么在docker中如何使用...
摘要:這樣就配置好了安裝插件監(jiān)聽地址開啟小電話以后,如果訪問會自動進入斷點中的模式,這樣我們的開發(fā)環(huán)境的斷點調(diào)試就已經(jīng)配置好了。 docker-compose環(huán)境來自:https://github.com/zhaojunlik...原文:http://blog.oeynet.com/post/9... 說明 在開發(fā)中,斷點調(diào)試是我們最快能找出Bug代碼問題的所在,那么在docker中如何使用...
摘要:寫代碼總繞不過需要調(diào)試,除了外,我們還是需要借助進行調(diào)試。這里的使用,是分別整合到和下。安裝還是基于神級武器。至于下一步如何更好的使用,就看各自的實際項目和開發(fā)需要了。 寫代碼總繞不過需要調(diào)試,除了 UnitTest 外,我們還是需要借助 Xdebug 進行調(diào)試。 所以今天來說說如何基于本地 Docker 環(huán)境下,使用 Xdebug。 這里的使用,是分別整合到 VS Code 和 PH...
閱讀 3133·2021-09-22 15:50
閱讀 3334·2021-09-10 10:51
閱讀 3148·2019-08-29 17:10
閱讀 2923·2019-08-26 12:14
閱讀 1841·2019-08-26 12:00
閱讀 947·2019-08-26 11:44
閱讀 657·2019-08-26 11:44
閱讀 2823·2019-08-26 11:41