系統架構 - Kantai235/laravel-typical-high-load-example GitHub Wiki
系統架構
本系統主要分為兩個部分「使用者建立訂單」與「查詢訂單內容」。前者為使用者隨機亂數選擇商品、亂數產生數量,並且新增一筆訂單,主要作用於測試寫入的部分,分別測試 10 個連線 300 次連續點擊、100 個連線 600 次連續點擊、300 個連線 1500 次連續點擊。而後者則為查找歷史訂單資訊,並且將資料結果顯示出來,主要作用於測試讀取的部分,單獨測試 300 個連線 1500 次連續點擊。
1. 使用者建立訂單
使用者建立訂單主要作用於測試寫入的部分,路由器(Router)去指定一個控制器(Controller),事件作用隨機從使用者當中抽選一名使用者、隨機抽選數個商品,並且建立訂單。
首先路由器(Router)的部分,指定 /testing/v1/shopping
為主要負責處理建立訂單的控制器(Controller),另外指定 /testing/v1/shopping/delete
為主要負責處理建立訂單,建立完畢後自動刪除資料的控制器(Controller)。
/*
* Shopping Testing Controllers
* All route names are prefixed with 'frontend.testing'.
*/
Route::group([
'prefix' => 'testing',
'as' => 'testing.',
], function () {
/**
* All route names are prefixed with 'frontend.testing.v1'.
*/
Route::group([
'prefix' => 'v1',
'as' => 'v1.',
], function () {
Route::get('shopping', [ShoppingV1Controller::class, 'shopping'])
->name('shopping');
Route::get('shopping/delete', [ShoppingV1Controller::class, 'shoppingDelete'])
->name('shopping.delete');
});
});
控制器(Controller)的部分,主要撰寫 shopping
負責處理建立訂單的事件,以及 shoppingDelete
負責處理建立訂單並刪除的事件。
/**
* @var OrderService
*/
protected $orderService;
/**
* @var ProductService
*/
protected $productService;
/**
* ShoppingV1Controller constructor.
*
* @param OrderService $orderService
* @param ProductService $productService
*/
public function __construct(OrderService $orderService, ProductService $productService)
{
$this->orderService = $orderService;
$this->productService = $productService;
}
/**
* @return \Illuminate\View\View
*/
public function shopping()
{
$order = $this->createOrder();
return view('frontend.order.index-v1')
->with('order', $order)
->with('items', $order->items);
}
/**
* @return \Illuminate\View\View
*/
public function shoppingDelete()
{
$order = $this->createOrder();
$items = $order->items;
$this->orderService->delete($order);
$this->orderService->destroy($order);
return view('frontend.order.index-v1')
->with('order', $order)
->with('items', $items);
}
/**
* @param array $data
*
* @return Orders
*/
protected function createOrder(): Orders
{
$products = array();
for ($i = 0; $i < mt_rand(1, 10); $i++) {
$product = $this->productService->firstActive();
if ($product->count >= 10) {
array_push($products, array(
'id' => $product->id,
'count' => mt_rand(1, 10),
));
} else {
array_push($products, array(
'id' => $product->id,
'count' => mt_rand(1, $product->count),
));
}
}
$order = $this->orderService->store(array(
'model_id' => mt_rand(2, 11),
'type' => Orders::UNPAID,
'active' => true,
'items' => $products,
));
return $order;
}
最後將訂單結果回應給使用者,透過 frontend.order.index-v1
來撰寫其視圖(View)。
一整個流程建置完畢以後,這邊使用 ApacheBench
作為主要測試工具,首先會先測試 10 個連線 300 次連續點擊。
This is ApacheBench, Version 2.3 <$Revision: 1874286 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking laravel-typical-high-load-exam.herokuapp.com (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Finished 300 requests
Server Software: nginx
Server Hostname: laravel-typical-high-load-exam.herokuapp.com
Server Port: 80
Document Path: /testing/v1/shopping
Document Length: 12423 bytes
Concurrency Level: 10
Time taken for tests: 64.790 seconds
Complete requests: 300
Failed requests: 288
(Connect: 0, Receive: 0, Length: 288, Exceptions: 0)
Total transferred: 5090789 bytes
HTML transferred: 4731089 bytes
Requests per second: 4.63 [#/sec] (mean)
Time per request: 2159.659 [ms] (mean)
Time per request: 215.966 [ms] (mean, across all concurrent requests)
Transfer rate: 76.73 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 207 213 3.5 211 223
Processing: 310 1887 277.6 1914 3111
Waiting: 306 1061 316.7 1062 1926
Total: 520 2100 278.0 2127 3322
Percentage of the requests served within a certain time (ms)
50% 2127
66% 2135
75% 2143
80% 2329
90% 2351
95% 2545
98% 2564
99% 2572
100% 3322 (longest request)
接著測試 100 個連線 600 次連續點擊,可以明顯地看到連線時間(Connection Times)的部分急遽上升。
This is ApacheBench, Version 2.3 <$Revision: 1874286 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking laravel-typical-high-load-exam.herokuapp.com (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Finished 600 requests
Server Software: nginx
Server Hostname: laravel-typical-high-load-exam.herokuapp.com
Server Port: 80
Document Path: /testing/v1/shopping
Document Length: 12423 bytes
Concurrency Level: 100
Time taken for tests: 129.688 seconds
Complete requests: 600
Failed requests: 595
(Connect: 0, Receive: 0, Length: 595, Exceptions: 0)
Total transferred: 10287980 bytes
HTML transferred: 9568580 bytes
Requests per second: 4.63 [#/sec] (mean)
Time per request: 21614.659 [ms] (mean)
Time per request: 216.147 [ms] (mean, across all concurrent requests)
Transfer rate: 77.47 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 207 212 3.4 210 227
Processing: 427 19265 5504.0 20565 32947
Waiting: 344 9684 4325.0 9527 21005
Total: 636 19477 5504.2 20781 33165
Percentage of the requests served within a certain time (ms)
50% 20781
66% 21866
75% 22482
80% 22991
90% 24583
95% 26164
98% 28381
99% 29891
100% 33165 (longest request)
最後測試 300 個連線 1500 次連續點擊,可以明顯地看到連線時間(Connection Times)的部分急遽上升以外,觀察到平均每秒可回應要求(Requests per second)大約著落於每秒可以處理大約 4 個回應,比起初始數值來講,降低了 20%。
This is ApacheBench, Version 2.3 <$Revision: 1874286 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking laravel-typical-high-load-exam.herokuapp.com (be patient)
Completed 150 requests
Completed 300 requests
Completed 450 requests
Completed 600 requests
Completed 750 requests
Completed 900 requests
Completed 1050 requests
Completed 1200 requests
Completed 1350 requests
Completed 1500 requests
Finished 1500 requests
Server Software: nginx
Server Hostname: laravel-typical-high-load-exam.herokuapp.com
Server Port: 80
Document Path: /testing/v1/shopping
Document Length: 12424 bytes
Concurrency Level: 300
Time taken for tests: 380.710 seconds
Complete requests: 1500
Failed requests: 1397
(Connect: 0, Receive: 0, Length: 1397, Exceptions: 0)
Total transferred: 25626810 bytes
HTML transferred: 23828310 bytes
Requests per second: 3.94 [#/sec] (mean)
Time per request: 76142.043 [ms] (mean)
Time per request: 253.807 [ms] (mean, across all concurrent requests)
Transfer rate: 65.74 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 208 214 3.8 212 231
Processing: 811 69217 17105.4 66176 127050
Waiting: 592 34430 17608.5 32051 86007
Total: 1021 69431 17105.3 66386 127266
Percentage of the requests served within a certain time (ms)
50% 66386
66% 71477
75% 75426
80% 78590
90% 93695
95% 107165
98% 116778
99% 119976
100% 127266 (longest request)
2. 查詢訂單內容
使用者查詢訂單內容主要作用於測試讀取的部分,路由器(Router)去指定一個控制器(Controller),事件作用根據路由器(Router)所帶入的訂單 UUID 參數,去查找訂單內容,並且將訂單資訊回傳顯示。
首先路由器(Router)的部分,指定 /testing/v1/order/{order}
為主要負責處理查詢訂單的控制器(Controller),其中 {order}
為訂單的 UUID 參數,系統會根據這個 UUID 參數來查找相對應的模型(Model),並將其帶入到控制器(Controller)當中。
/*
* Shopping Testing Controllers
* All route names are prefixed with 'frontend.testing'.
*/
Route::group([
'prefix' => 'testing',
'as' => 'testing.',
], function () {
/**
* All route names are prefixed with 'frontend.testing.v1'.
*/
Route::group([
'prefix' => 'v1',
'as' => 'v1.',
], function () {
Route::get('order/{order}', [ShoppingV1Controller::class, 'order'])
->name('order');
});
});
在控制器(Controller)直接將訂單資訊回傳給視圖(View)顯示。
/**
* @param Orders $order
*
* @return \Illuminate\View\View
*/
public function order(Orders $order)
{
return view('frontend.order.index-v1')
->with('order', $order)
->with('items', $order->items);
}
最後單獨測試 300 個連線 1500 次連續點擊,這裡可以明顯看到平均每秒可回應要求(Requests per second)比寫入的測試還小很多,由此得知比起資料讀取,資料的寫入更是需要優先處理並改善。
This is ApacheBench, Version 2.3 <$Revision: 1874286 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking laravel-typical-high-load-exam.herokuapp.com (be patient)
Completed 150 requests
Completed 300 requests
Completed 450 requests
Completed 600 requests
Completed 750 requests
Completed 900 requests
Completed 1050 requests
Completed 1200 requests
Completed 1350 requests
Completed 1500 requests
Finished 1500 requests
Server Software: nginx
Server Hostname: laravel-typical-high-load-exam.herokuapp.com
Server Port: 80
Document Path: /testing/v1/order/76c399c1-042a-46e9-81f3-75845368ca24
Document Length: 16341 bytes
Concurrency Level: 300
Time taken for tests: 303.845 seconds
Complete requests: 1500
Failed requests: 0
Total transferred: 26310000 bytes
HTML transferred: 24511500 bytes
Requests per second: 4.94 [#/sec] (mean)
Time per request: 60768.905 [ms] (mean)
Time per request: 202.563 [ms] (mean, across all concurrent requests)
Transfer rate: 84.56 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 198 202 2.1 202 217
Processing: 478 54382 14387.6 60397 60617
Waiting: 277 30094 17486.6 30102 60197
Total: 679 54584 14387.5 60599 60817
Percentage of the requests served within a certain time (ms)
50% 60599
66% 60627
75% 60653
80% 60663
90% 60672
95% 60675
98% 60680
99% 60689
100% 60817 (longest request)