🕛

NGINX +PHP-FPM (Laravel)を仮想マシンで動かす場合と仮想マシンの上でコンテナ立てて動かす時のレスポンスタイム比較

2024/09/15に公開

概要

コンテナ活用してアプリケーション開発したい!
しかし現職のインフラ環境がオンプレミス基盤で、古めのESXiを使って仮想マシンを立てて使う運用している。

仮想マシンの上にコンテナ立てた時のオーバーヘッドってあったりするんだろうか?
そんな疑問から実際に実験してみました。

  • AWSのEC2インスタンスで実験
    • Amazon Linux 2023 AMI
    • t2.micro
  • NGINX 1.27.1
  • PHP-FPM 8.3
  • PHP 8.3
  • Laravel v11.2.0
  • OPcache、JITなし

仮想マシンの上にLaravelアプリケーションを動かしてベンチマークを取る

### NGINXのインストール
$ sudo yum install nginx

### PHP-FPMのインストール
$ sudo yum install php8.3-fpm

### PHPのインストール
$ sudo yum install php8.3

### Composerのインストール
$ sudo chmod 777 /var/www
$ cd /var/www
$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
$ php composer-setup.php --filename=composer

### Laravelのセットアップ
$ cd /var/www
$ ./composer create-project --prefer-dist laravel/laravel laravel-app

### ディレクトリの権限設定
$ sudo chown -R nginx:nginx /var/www/laravel-app
$ sudo chmod -R 755 /var/www/laravel-app

### PHP-FPMの設定
$ sudo vi /etc/php-fpm.d/www.conf
~~~
user = nginx
group = nginx
listen = 127.0.0.1:9000
~~~

$ sudo rm /etc/php.d/10-opcache.ini

$ sudo systemctl restart php-fpm
$ php -v
PHP 8.3.10 (cli) (built: Jul 30 2024 13:44:37) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.3.10, Copyright (c) Zend Technologies
$ php-fpm -v
PHP 8.3.10 (fpm-fcgi) (built: Jul 30 2024 13:44:37)
Copyright (c) The PHP Group
Zend Engine v4.3.10, Copyright (c) Zend Technologies

### NGINXの設定
$ sudo vi /etc/nginx/conf.d/laravel.conf

server {
    listen 80;
    server_name XXX.XXX.XXX.XXX;

    root /var/www/laravel-app/public;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_index index.php;
    }

    location ~ /\.ht {
        deny all;
    }
}

$ sudo systemctl restart nginx

Apache Benchmarkで検証
※ネットワーク遅延は排除したかったので仮想マシン上でabコマンド実行

$ ab -n 1000 -c 10 http://XXX.XXX.XXX.XXX/

Concurrency Level:      10
Time taken for tests:   74.614 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      35128000 bytes
HTML transferred:       34020000 bytes
Requests per second:    13.40 [#/sec] (mean)
Time per request:       746.142 [ms] (mean)
Time per request:       74.614 [ms] (mean, across all concurrent requests)
Transfer rate:          459.76 [Kbytes/sec] received

仮想マシンの上にコンテナを立てて、コンテナでLaravelアプリケーションを動かしてベンチマークを取る

先ほど使った仮想マシンを使い回す。

### Webサーバ止める
$ sudo systemctl stop nginx
$ sudo systemctl stop php-fpm

### Dockerのパッケージをインストール
$ sudo yum update -y
$ sudo yum install -y docker

# Docker Compose CLIの最新版をダウンロードしてインストール
sudo curl -L "https://github.com/docker/compose/releases/download/v2.21.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 実行権限を付与
sudo chmod +x /usr/local/bin/docker-compose

# Docker Composeのバージョンを確認
docker-compose --version

### Dockerサービスを起動
$ sudo systemctl start docker
$ sudo systemctl enable docker

### ec2-userをdockerグループに追加して、sudoなしでdockerコマンドを実行できるようにする
$ sudo usermod -aG docker $USER

### 一度exit
$ exit

### コンテナを動かす準備
$ cd /var/www/laravel-app
$ sudo chmod -R 777 ./
$ vim docker-compose.yml
version: '3.8'

services:
  app:
    image: php:8.3-fpm
    container_name: laravel_app
    working_dir: /var/www/html
    volumes:
      - ./:/var/www/html
      - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - laravel
    expose:
      - 9000

  web:
    image: nginx:1.24.0
    container_name: laravel_web
    depends_on:
      - app
    volumes:
      - ./:/var/www/html
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - "80:80"
    networks:
      - laravel

networks:
  laravel:
    driver: bridge

$ sudo mkdir nginx
$ sudo vim nginx/nginx.conf
worker_processes 1;

events {
    worker_connections 1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen 80;
        server_name localhost;
        root /var/www/html/public;

        index index.php index.html index.htm;

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }

        location ~ \.php$ {
            include fastcgi_params;
            fastcgi_pass app:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_buffers 16 16k;
            fastcgi_buffer_size 32k;
        }

        location ~ /\.ht {
            deny all;
        }
    }
}

$ sudo mkdir php
$ sudo vim php/php.ini
memory_limit = 512M
upload_max_filesize = 100M
post_max_size = 100M
max_execution_time = 300

$ docker-compose up -d

$ sudo chown -R nginx:nginx /var/www/laravel-app
$ sudo chmod -R 777 /var/www/laravel-app

Apache Benchmarkで検証
※ネットワーク遅延は排除したかったので仮想マシン上でabコマンド実行

$ ab -n 1000 -c 10 http://XXX.XXX.XXX.XXX/

Concurrency Level:      10
Time taken for tests:   70.694 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      35154000 bytes
HTML transferred:       34020000 bytes
Requests per second:    14.15 [#/sec] (mean)
Time per request:       706.940 [ms] (mean)
Time per request:       70.694 [ms] (mean, across all concurrent requests)
Transfer rate:          485.62 [Kbytes/sec] received

結果の比較

  • 仮想マシン Time taken for tests: 74.614 seconds
  • 仮想マシン&コンテナ Time taken for tests: 70.694 seconds

あれ、そんなに結果が変わらない??

仮想マシンのPHPでOPcacheを有効にしてベンチマーク

$ cd /var/www/laravel-app/
$ docker-compose down

$ sudo vi /etc/php.d/10-opcache.ini
; OPcache settings
zend_extension=opcache.so
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2

$ sudo systemctl start nginx
$ sudo systemctl start php-fpm
$ php-fpm -v
PHP 8.3.10 (fpm-fcgi) (built: Jul 30 2024 13:44:37)
Copyright (c) The PHP Group
Zend Engine v4.3.10, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.10, Copyright (c), by Zend Technologies

$ ab -n 1000 -c 10 http://XXX.XXX.XXX.XXX/

Concurrency Level:      10
Time taken for tests:   10.138 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      35128000 bytes
HTML transferred:       34020000 bytes
Requests per second:    98.64 [#/sec] (mean)
Time per request:       101.382 [ms] (mean)
Time per request:       10.138 [ms] (mean, across all concurrent requests)
Transfer rate:          3383.72 [Kbytes/sec] received

コンテナのPHPでOPcacheを有効にしてベンチマーク

$ sudo systemctl stop nginx
$ sudo systemctl stop php-fpm

$ vim Dockerfile

# Dockerfile
FROM php:8.3-fpm

# OPcacheを有効にするための設定を追加
RUN docker-php-ext-install opcache

$ vim docker-compose.yml
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
~~~

$ docker-compose up -d

$ docker exec -it laravel_app php-fpm -v
PHP 8.3.12 (fpm-fcgi) (built: Sep 27 2024 06:21:30)
Copyright (c) The PHP Group
Zend Engine v4.3.12, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.12, Copyright (c), by Zend Technologies

$ ab -n 1000 -c 10 http://XXX.XXX.XXX.XXX/

Concurrency Level:      10
Time taken for tests:   9.376 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      35154000 bytes
HTML transferred:       34020000 bytes
Requests per second:    106.65 [#/sec] (mean)
Time per request:       93.761 [ms] (mean)
Time per request:       9.376 [ms] (mean, across all concurrent requests)
Transfer rate:          3661.43 [Kbytes/sec] received

Discussion