Skip to content

系統架構

乾太 edited this page Aug 23, 2021 · 1 revision

系統架構

本系統主要分為兩個部分「使用者建立訂單」與「查詢訂單內容」。前者為使用者隨機亂數選擇商品、亂數產生數量,並且新增一筆訂單,主要作用於測試寫入的部分,分別測試 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)。

Untitled

一整個流程建置完畢以後,這邊使用 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)
Clone this wiki locally