[2020年面試題-PHP 與 golang] .Go 和 PHP 在運行的時候有什麼區別和優勢

原文鏈接

分享:[分享] 大環境下瑟瑟發抖辭職的第二天,拿了兩個 offer

面試題解析

  1. 看你簡歷裏也有用過 Go,Go 和 PHP 在運行的時候有什麼區別和優勢?
題主原回答:
PHP 每個請求進來時都會創建 fpm-worker 進程,從而導致系統併發高時 CPU 會產生頻繁創建進程的開銷,而 Go 不會。

解析回答:PHP 每個請求進來時都會創建 fpm-worker 進程

 

補充下,這裏 php 請求進來就會 由 PHP - FPM(php-fpm 是 php-cgi 的進程管理器)創建一個 PHP-CGI 進程來準備響

應用戶的請求。具體過程如圖,大家也可以繼續往下看詳細解析。

 

 

 

解析回答:而 go 不會

golang 是先編譯,後執行。 具體可以往下看詳細解析。

php 運行原理

目前常見的 4 種 PHP 運行模式

  1. CGI 通用網關接口模式
  2. FAST-CGI 模式
  3. CLI 命令行模式
  4. 模塊模式

CGI 通用網關接口模式

每有一個用戶請求,都會先要創建 cgi 的子進程,然後處理請求,處理完後結束這個子進程

cgi 是一種爲了保證 web server 傳遞過來的數據是標準格式的通用網關接口協議

比較老,比較原始,大多已經不用了

FAST-CGI 模式

是 cgi 的升級版本,FastCGI 像是一個常駐 (long-live) 型的 CGI,它可以一直執行着,只要激活後,不會每次都要花費時間

去 fork 一次,也是一種協議

FastCGI 的工作原理是:

  (1)、Web Server 啓動時載入 FastCGI 進程管理器【PHP 的 FastCGI 進程管理器是 PHP-FPM (php-FastCGI Process Manager)】(IIS ISAPI 或 Apache Module);

 

  (2)、FastCGI 進程管理器自身初始化,啓動多個 CGI 解釋器進程 (在任務管理器中可見多個 php-cgi.exe) 並等待來自 Web Server 的連接。

 

  (3)、當客戶端請求到達 Web Server 時,FastCGI 進程管理器選擇並連接到一個 CGI 解釋器。Web server 將 CGI 環境變量和標準輸入發送到 FastCGI 子進程 php-cgi。

 

  (4)、FastCGI 子進程完成處理後將標準輸出和錯誤信息從同一連接返回 Web Server。當 FastCGI 子進程關閉連接時,請求便告處理完成。FastCGI 子進程接着等待並處理來自 FastCGI 進程管理器(運行在 WebServer 中)的下一個連接。在正常的 CGI 模式中,php-cgi.exe 在此便退出了。

 

  在 CGI 模式中,可以想象 CGI 通常有多慢。每一個 Web 請求 PHP 都必須重新解析 php.ini、重新載入全部 dll 擴展並重初始化全部數據結構。使用 FastCGI,所有這些都只在進程啓動時發生一次。一個額外的好處是,持續數據庫連接 (Persistent database connection) 可以工作。

CLI 命令行模式

一般使用調用腳本、查看 php 信息時會使用到該模式

php -r”phpinfo ();” |less 分頁顯示

 

模塊模式

  1. Apache + mod_php
  2. lighttp + spawn-fcgi
  3. nginx + PHP-FPM

運行原理

PHP-CGI:fast-cgi 是一種協議,而 php-cgi 是實現了這種協議的進程。不過這種實現比較爛。它是單進程的,一個進程處

理一個請求,處理結束後進程就銷燬

 

PHP - FPM:是對 php-cgi 的改進版,它直接管理多個 php-cgi 進程 / 線程。也就是說,php-fpm 是 php-cgi 的進程管理器因此它也算是 fastcgi 協議的實現

php 的運行原理,就是在服務器啓動時,自動載入 PHP-FPM 進程管理器,從而管理多個 PHP-CGI 進程來準備響應用戶的

請求,如下圖所示:

 

 

 

多個運行模式相當於超市的不同入口,運行原理就是進入超市後的固定的行走路線,通過不同的運行模式進入到底層(進入超市)

 

golang 運行原理

golang 是先編譯爲靜態二進制可執行文件,再去運行。

看看 go run 與 go build 的區別

o 的執行原理以及 Go 的命令

 

go run 的執行過程

 

 

 

  1. 創建了兩個臨時文件夾 b001 和 exe
  2. 先執行了 compile 命令,然後 link,生成了歸檔文件.a 和 最終可執行文件
  3. 最終的可執行文件放在 exe 文件夾裏面。
  4. 命令的最後一步就是執行了可執行文件。

舉個例子,生成的臨時文件可以用 go run -work 看到,比如當前生成的臨時文件夾是如下的路徑:

localhost:hello ruby$ go run -work mytest.go
WORK=/var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go-build593750496
HelloWorld
你好,Go!!!
localhost:hello ruby$ 

我們進入:/var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go-build593750496 目錄,可以看到如下目錄結構:

 

 

 

可以看到,最終 go run 命令是生成了 2 個文件,一個是歸檔文件,一個是可執行文件。

 

go run 命令在第二次執行的時候,如果發現導入的代碼包沒有發生變化,那麼 go run 不會再次編譯這個導入的代碼包。直接靜態鏈接進來。

 

go build 的執行過程

go build 用於編譯我們指定的源碼文件或代碼包以及它們的依賴包。但是注意如果用來編譯非命令源碼文件,即庫源碼文件,go build 執行完是不會產生任何結果的。這種情況下,go build 命令只是檢查庫源碼文件的有效性,只會做檢查性的編譯,而不會輸出任何結果文件。

go build 編譯命令源碼文件,則會在該命令的執行目錄中生成一個可執行文件,上面的例子也印證了這個過程。

go build 後面不追加目錄路徑的話,它就把當前目錄作爲代碼包並進行編譯。go build 命令後面如果跟了代碼包導入路徑作爲參數,那麼該代碼包及其依賴都會被編譯。

go build 命令究竟做了些什麼呢?我們可以執行 - n 這個命令來查看。 這裏略過打印輸出。

執行過程和 go run 大體相同,唯一不同的就是在最後一步,go run 是執行了可執行文件,但是 go build 命令,只是把庫源碼文件編譯了一遍,然後把可執行文件移動到了當前目錄的文件夾中。

總結一下如下圖:

 

 

 

感謝關注

更多學習內容請訪問:

騰訊T3-T4標準精品PHP架構師教程目錄大全,只要你看完保證薪資上升一個臺階(持續更新)

很多人在剛接觸這個行業的時候或者是在遇到瓶頸期的時候,總會遇到一些問題,比如學了一段時間感覺沒有方向感,不知道該從那裏入手去學習,對此我整理了一些資料,需要的可以免費分享給大家(點擊此處加入php高級交流羣一起學習交流,11年架構師帶你解讀年薪50萬面試通關祕籍。)

如果喜歡我的文章,想與一羣資深開發者一起交流學習的話,獲取更多相關大廠面試諮詢和指導

以上內容希望幫助到大家,很多PHPer在進階的時候總會遇到一些問題和瓶頸,業務代碼寫多了沒有方向感,不知道該從那裏入手去提升,對此我整理了一些資料,包括但不限於:分佈式架構、高可擴展、高性能、高併發、服務器性能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階乾貨需要的可以免費分享給大家,需要的可以加入我的官方羣點擊此處

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章