前提概要
有一個新專案由於未知原因專案載入速度很慢
不清楚是不是 laravel 框架的原因,畢竟效能一直是它的軟肋
。不管是怎麼配置優化甚至直接寫了一個最簡單的路由到頁面輸出 hello word,問題還是依舊
,頁面的載入時間都需要1s
多。有問題自然是要想辦法解決,這時候 laravels出現了。經過一番肉搏,測試結果頁面載入速度提升到了
100 - 200 ms
。不過我還沒來的及高興多久,各種問題就接踵而至。
問題一 :
使用 laravel-menu 生成的選單會無限新增,簡直可以長到突破天際。
檢視文件發現,這是因為
單例問題
swoole 會在導致資料無線新增,要新增方法自己清理一下。
問題二 :
問題一解決還沒高興多久,問題二又來了。這次將是一個很曲折的故事。
問題概要:
當頁面過大或者介面返回的資料過的的時候
其實也有很大,也就不到1M
,swoole
會出現無法返回資料的情況。而且沒過多久整個專案就504
奔潰了。
解決過程
遇到問題不可怕,只要嘗試解決問題就好了。首先我檢視了
php
,nginx
,swoole
的日誌檔案,沒有發現任何報錯資訊。接著配置了一個沒有使用laravels
的域名地址,發現一切正常。這時候基本可以確定你是
laravels
的問題,接著來到laravels
的專案地址,檢視其他人是否遇到相同問題,並諮詢了專案作者作者還是很 nice 的響應很快
,也給了很多建議,然而問題還是沒有解決。 加了 laravels qq交流群,諮詢了很多大佬,得到的結構還是一樣,問題到這裡絲毫沒有進展。當然這不是完全一無所獲,至少我可以確定我碰到的問題是非常小眾的問題。我開始懷疑是我使用的開發環境的問題。
在 github 上輸入
wsl swoole
,我在 swoole/swoole-src#2386 看到了一條這樣的資訊,原來是wsl1
下swoole
確實返回資料過大,會出現程式會掛起問題。有了新的突破口,還是很開心的。不過我不知道,這只是新一輪問題求解的開始。
wsl2 安裝
按照教程使用
wsl --set-version Ubuntu-16.04 2
,出現沒有相關命令的提示。
wsl -h
看了一下,果真沒有這條命令。看了下文件
請注意,需要執行 Windows 10 版本 18917 或更高版本才能使用 WSL 2,並且需要已安裝 WSL(可在此處找到有關執行此操作的說明)
。
原來是系統版本太低了,只能更新到最新的預覽版才行。
百度一下更新預覽系統教程,經過一個上午的耕耘,終於更新到了最新的版本。重新 wsl --set-version Ubuntu-16.04 2,滿懷期待的以為會成功。結果出現
正在進行轉換,這可能需要幾分鐘時間... 有關與 WSL 2 的主要區別的資訊,請訪問 https://aka.ms/wsl2 連到系統上的裝置沒有發揮作用。
的報錯。 這什麼鬼?重複測試了多次結果還是一樣。以為是以前安裝的 wsl 無法直接切換 版本 ,檢視了文件後
wsl --set-default-version 2
重新安裝 ,結果出現Installing, this may take a few minutes... WslRegisterDistribution failed with error: 0x8007001f Error: 0x8007001f ??????????????? Press any key to continue...
。
這時候
wsl1
版本是可以正常使用的。到 https://github.com/microsoft/WSL 上查詢了很久也沒找到好的解決方法。
問題到這,幾乎已經到了山窮水盡的地步了(經過再次測試,此處問題是系統沒有更新完成,需要再多重啟幾次)。
不經過我還是沒有放棄,我還在思考我的問題到底出在哪裡。
回到家,坐到馬桶上我思考了半個小時。在第三次全軍出擊的提示聲中,我想到了一種可能。我是直接升級到最新的系統版本的,是不是系統還殘留有一些原來系統的設定導致了新的功能不能使用。
第二天一到公司,果斷使用重置系統的功能。再又經過了半天的肉搏後,我成功將
wsl
升級到了wsl2
。
到這裡,我以為一切都要結束了。
到了熟悉的配置開發環境的環節。當我配置好一切,輸入久違的域名的時候。我竟然看到了,
域名無法訪問
。一臉懵逼中!!!!經過這麼多年的環境配置磨練,我相信我的配置是沒有問題的。那麼問題就是出在
wsl2
上面的了。
檢視文件文件發現
wsl2
的域名規則和wsl1
。已經不一樣了
當使用遠端 IP 地址連線到應用程式時, 它們將被視為來自區域網 (LAN) 的連線。 這意味著你將需要確保你的應用程式可以接受 LAN 連線, 例如:你可能需要將應用程式繫結到0.0.0.0 , 127.0.0.1而不是。 例如, 在 python 中使用 flask, 可以使用以下命令完成此app.run(host='0.0.0.0')操作:。 進行這些更改時, 請牢記安全, 因為這將允許來自 LAN 的連線。
修改
nginx
配置,將listen 80;
修改為listen 0.0.0.0:80;
重啟nginx
。到這個時候前面的提到的問題
當頁面過大或者介面返回的資料過的的時候 其實也有很大,也就不到1M, swoole 會出現無法返回資料的情況。而且沒過多久整個專案就 504奔潰了
,終於解決了。
你以為問題到這裡就全部結束了?
其實還遠遠沒有結束。這時候你會發現,當你想用
navicat
連線資料庫的時候,原來正常的配置會報錯2003 - Can’t connect to MySQL server on ******* (10060 "Unknown error ")
。
原因自然和前面一樣
127.0.0.1
,已經無法訪問子系統資料庫了。
解決方法:
//修改配置
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address =127.0.0.1
//修改為
bind-address = 0.0.0.0
//重啟mysql
sudo service mysql restart
// 檢視當前 wsl 系統IP
ifconfig
// 複製 eth0 -> inet addr: 後面的地址 作為訪問資料庫的地址
這時候就可以正常通過
navicat
訪問wsl2
的資料庫了。
注意:
wsl2
每次重啟後 IP 都會變化,所以每次重啟後都需要重新設定一次navicat
。
wsl2
每次重啟後 IP 都會變問題解決方案
每次重啟都要重新修改
nginx
,mysql
等等和 IP 相關的配置檔案,會顯得非常麻煩。不過有問題肯定就有解決方法。 有個大神 edwindijas 寫了個指令碼解決這個問題。 相關連線https://github.com/microsoft/WSL/issues/41...
//指令碼
$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if( $found ){
$remoteport = $matches[0];
} else{
echo "The Script Exited, the ip address of WSL 2 cannot be found";
exit;
}
#[Ports]
#All the ports you want to forward separated by coma
$ports=@(80,443,10000,3000,5000);
#[Static ip]
#You can change the addr to your ip config to listen to a specific address
$addr='0.0.0.0';
$ports_a = $ports -join ",";
#Remove Firewall Exception Rules
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";
#adding Exception Rules for inbound and outbound Rules
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $ports_a -Action Allow -Protocol TCP";
for( $i = 0; $i -lt $ports.length; $i++ ){
$port = $ports[$i];
iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
}
exit 0;
可以設定一個開機任務。每次開機自動執行該指令碼。這樣不用每次都手動執行。
執行後就可以像 wsl1
用 127.0.0.1
訪問 nginx
,mysql
了。