iT邦幫忙

1

請問關於php和laravel的QPS差距

  • 分享至 

  • xImage

各位前輩好,事情是這樣的
我用K6對server發起一個請求,請求的內容是對資料庫的3張表分別插入1筆資料
資料庫是postgreSQL,伺服器是IIS
K6設定是rate400/1s/vus500/持續2m
對原生PHP(版本8.3)發起請求時,結果如下圖
https://ithelp.ithome.com.tw/upload/images/20240522/20166610k8fXDvCxQd.jpg
status200的次數是47403,也成功對3張資料表分別插入47403筆資料
但目標換成laravel(版本11),結果變成
https://ithelp.ithome.com.tw/upload/images/20240522/20166610mLKHwpzKSh.jpg
僅發起1100多次的請求,status200的次數只有338
資料庫也只成功新增了300多筆資料,其餘的請求都是timeout

是有聽說laravel因為依賴太多,導致高併發表現很差,但這也未免太差了
第一個念頭是laravel可能有甚麼預設的限流設定,但查了一下未果
再來懷疑可能是session存database的原因,但改成cookie之後也並無改善

想請問是否有甚麼設定沒有調整到,導致laravel處理請求的效率如此的差
又或者這真的就是laravel的正常發揮?
先謝謝大家的回答

chan15 iT邦新手 2 級 ‧ 2024-05-23 08:51:50 檢舉
你打的是 web route 還是 api route?api route 沒修改預設值的話我記得每個 endpoint 同一個請求來源一分鐘只能打 60 次,我們也是用 k6 測試高併發效能沒那麼差
ufv23 iT邦新手 5 級 ‧ 2024-05-23 14:42:40 檢舉
抱歉,laravel的版本打錯了,是11.7才對
ufv23 iT邦新手 5 級 ‧ 2024-05-23 14:49:18 檢舉
都是web路由,所以web路由沒有預設1分鐘60次的限制是嗎?
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

3
Ray
iT邦大神 1 級 ‧ 2024-05-23 06:23:37
最佳解答

看一下你的 Laravel .env 檔案, 裡面是否有:

SESSION_DRIVER=file

把它改成這樣測看看(沒有這行的話, 請自行加入下面這行):

SESSION_DRIVER=array
看更多先前的回應...收起先前的回應...
ufv23 iT邦新手 5 級 ‧ 2024-05-23 14:55:59 檢舉

這邊.env本來是SESSION_DRIVER=database,改成array之後每秒請求數量從7上升到60左右,謝謝您的回覆

Ray iT邦大神 1 級 ‧ 2024-05-23 15:08:03 檢舉

所以你的問題根源是在:
Laravel Session 寫入 Disk 的速度太慢, 連帶拖累了 Database 受測的 Query 速度.

因為 Laravel Framework 預設會幫你前處理 Session 機制, 但是你自己寫的 Native PHP 可能沒有這段, 所以兩者速度相差在此.

SESSION_DRIVER=array 就是要求 Laravel 把 Session 資訊全部都寫到記憶體去, 不要寫到檔案或資料庫, 這樣可以少掉處理 Session 的 Disk I/O 時間.

但沒看到你寫的 Laravel 程式和完整 .env, 難以判斷是否除了 Session 寫入 Disk 之外, 還有其他隱含的前處理動作? (例如: MVC, safety mechanisms, Route model binding....) 必須關掉這些前處理, 才能跟 Native PHP 比較速度.

Ray iT邦大神 1 級 ‧ 2024-05-23 15:19:42 檢舉

這是 Laravel 內部預設的 MVC 流程, 你必須優化這些動作, 才會有高效:

ufv23 iT邦新手 5 級 ‧ 2024-05-25 06:45:25 檢舉

好的,我再研究看看,謝謝您

0

注意一下你的 middleware 的宣告。
LAEAVEL 預設會在 middleware 內宣告一個 throttle。
那會控制並發數的限制。

預設值是每分60次的樣子。超過就會出現429的錯誤。
記得要將其給關掉。

要不然你會被這個控制給阻擋

ufv23 iT邦新手 5 級 ‧ 2024-05-23 15:07:59 檢舉

抱歉,昨天寫的時候沒注意到版本寫錯了,laravel的版本是11.7
想請問新的版本中還有這個設定嗎?
我參考官方文件
https://laravel.com/docs/11.x/routing#rate-limiting
在AppServiceProvider加了一個for global的速率限制(10000/1m)
但反而比沒加的時候效率要來的差,這是否表示預設是沒有限制請求次數的?

11版我不確定。
不過正常 api 路由都會掛一個這個限制。
web 路由有沒有掛我不確定。
比較正規的做法是檢查你目前的路由及 middleware 的使用。
另外,你只要加上限制控制。
它是需要記錄資料的。(要不然它怎麼可能知道已經幾次了)
所以設定(10000/1m)其實是沒啥意義就是了。
一般如果要限制的話。500/m 就算很多了。再多就乾脆不要開了。

另外有件事我沒說清楚。
laravel想要資料庫快。如果是搭配ORM的情況下。
在程式碼沒處理好的情況下。或是不清楚如何正確使用ORM的話。
會比用原生的還慢。

因為使用ORM會比較容易佔用RAM。如RAM足夠的話。
速度一定不錯。RAM不足的情況下。會反而速度下降。

如何善用工具也是你需要考量的地方。

ufv23 iT邦新手 5 級 ‧ 2024-05-25 06:46:05 檢舉

好的,我再研究看看,謝謝您

我要發表回答

立即登入回答