【问题标题】:super slow query times for laravel 5 / php-fpm / nginx in dockerized web appdockerized web 应用程序中 laravel 5 / php-fpm / nginx 的超慢查询时间
【发布时间】:2018-04-27 20:02:46
【问题描述】:

我在 nginx 后面有一个 Laravel 5.5/PHP-fpm (PHP 7) API,它们都在单独的 Docker 容器中。我的 API 调用仅返回一个 json 对象大约需要 2 秒,这对于这样一个简单的查询来说非常长(即使我从 dockerized mysql 数据库查询并返回一些行,也需要 3 秒以上)。它应该小于一百毫秒。我不确定如何调试这个问题。任何想法为什么它这么慢?

  • 在 Mac 上使用 Docker
  • docker-compose 版本 1.16.1,构建 6d1ac21
  • Docker 版本 17.09.0-ce,构建 afdb6d4

PHP API

Route::get('/api/names', function () {
  return array(
    1 => "Honey",
    2 => "Nut",
    3 => "Cheerios"
  );
});

Nginx dockerfile

FROM nginx

RUN rm /etc/nginx/conf.d/*

COPY nginx.conf /etc/nginx/conf.d/

nginx.conf

upstream phpie {
  server php-fpm:9000 weight=10 max_fails=3 fail_timeout=30s;
}

server {
  listen 80;
  index index.php index.html;
  root /var/www/api/public;

  resolver            127.0.0.11 valid=5s ipv6=off;

  location / {
    try_files $uri $uri/ /index.php$is_args$args;
  }

  location ~ \.php$ {
      try_files $uri /index.php =404;
      fastcgi_pass phpie:9000;
      fastcgi_index index.php;
      fastcgi_buffers 16 16k;
      fastcgi_buffer_size 32k;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      include fastcgi_params;
  }
}

PHP dockerfile

FROM php:7.1-fpm

RUN apt-get update && apt-get install -y libmcrypt-dev \
    mysql-client libmagickwand-dev --no-install-recommends \
    && pecl install imagick \
    && docker-php-ext-enable imagick \
    && docker-php-ext-install mcrypt pdo_mysql

docker-compose.yml

  php-fpm:
    build:
      context: ./api
    working_dir: /var/www/api
    volumes:
      - ./api:/var/www/api
    ports:
      - "9000"

  nginx:
    restart: always
    build:
      context: ./nginx
    volumes:
      - ./api:/var/www/api
    depends_on:
      - php-fpm
    ports:
      - "80:80"
    command: /bin/bash -c "nginx -g 'daemon off;'"

【问题讨论】:

  • 您是否进行了任何日志记录以确定减速发生的位置?

标签: php docker nginx laravel-5 docker-compose


【解决方案1】:

PHP 依靠文件缓存来快速加载每个请求。每次php 运行时,它都必须再次加载所有需要的文件。从 Mac 到 Docker VM 的挂载与文件缓存混淆,加载文件变慢,因此每个请求都变慢。尤其是任何加载包含大量文件的框架的东西,比如 Laravel。

在没有 Mac 的情况下运行应用程序 -> VM 卷挂载,将 api/ 文件复制到 Dockerfile 中的每个映像中以确认。

我习惯使用的一个解决方案是创建一个内容卷,它在运行时安装到每个容器中。对于开发,此内容卷由外部工具与您的本地开发更改同步。

内容 Dockerfile - Dockerfile.content

FROM scratch
WORKDIR /var/www/api/
COPY . /var/www/api/

作曲

  content:
    image: user3226932/api-content
    build:
      context: ./api
      dockerfile: Dockerfile.content
    volumes:
      - 'content:/var/www/api'

  php-fpm:
    build:
      context: ./api
    working_dir: /var/www/api
    volumes:
      - 'content:/var/www/api'
    depends_on:
      - content
    ports:
      - "9000"

  nginx:
    restart: always
    build:
      context: ./nginx
    volumes:
      - 'content:/var/www/api:ro'
    depends_on:
      - php-fpm
    ports:
      - "80:80"
    command: /bin/bash -c "nginx -g 'daemon off;'"

volumes:
  - content

尝试docker-sync 之类的方法(使用 rsync 策略)以使您的本地开发环境与卷保持同步。它主要是有效的,但有时会出现一些问题。另一种选择是直接使用fswatchrsync 到本地卷目录。 docker volume ls

【讨论】:

    猜你喜欢
    • 2018-01-17
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    • 2019-01-20
    • 2020-04-29
    • 2013-04-08
    • 2016-11-28
    相关资源
    最近更新 更多