windwos docker 下 laravel 项目运行慢的问题?

问题描述

我在windows 下安装的 docker for windows 自己创建了lnmp环境,
但是遇到了很尴尬的问题同样的代码,在我的云服务器上响应时间很短:

clipboard.png

但是在windows docker 环境下 响应时间需要一两秒,相差几乎十倍

clipboard.png

docker-compose
文件如下:

问题出现的平台版本及自己尝试过哪些方法

出现平台:windwos
我自己在网络上查找了相关的解决办法,说是io的问题 需要加上cached 参数
但是我加入这个参数之后,响应速度几乎没有提升?
请问有什么可以解决的办法吗??

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)

version: "3"
services:

nginx:
    image: nginx
    container_name: lnmp_nginx
    ports:
        - "80:80"
        - "443:443"
    networks: 
        lnmp:
            ipv4_address: ${NGINXADDR}
    volumes:
        - ./log/nginx/nginx:/var/log/nginx
        - ./code/php:/var/www/html/:cached 
        - ./config/nginx/nginx.conf:/etc/nginx/nginx.conf
        - ./config/nginx/conf.d:/etc/nginx/conf.d
mysql:
    image: mysql
    container_name: lnmp_mysql
    environment:
        MYSQL_ROOT_PASSWORD: root
    volumes:
        - ./data/mysql:/var/lib/mysql
    networks: 
        lnmp:
            ipv4_address: ${MYSQLADDR}
    ports:
        - "3306:3306"

phpfpm:
    build: ./Dockerfiles/php/
    container_name: lnmp_phpfpm
    links:
        - mysql:mysql
        - redis:redis
    volumes:
        - ./code/php:/var/www/html/:cached
        - ./config/php/:/usr/local/etc/
    networks: 
        lnmp:
            ipv4_address: ${PHPFPMADDR}
    ports:
        - "9000:9000"
        - "9501:9501"
        - "8000:8000"
redis:
    image: redis
    ports: 
        - "6379:6379"
    container_name: redis
    volumes: 
        - ./data/redis:/data
    networks: 
        lnmp:
            ipv4_address: ${REDISADDR}
    command: redis-server --appendonly yes

networks:

lnmp:
    driver: bridge
    ipam:
        driver: default
        config:
            - subnet: 172.16.238.0/24


阅读 7.4k
2 个回答

Docker for Windows是在Hyper-V虚拟机上跑Linux,文件挂载是通过SMB协议从Windows挂载到Linux,文件读写都经过网络,遇到Laravel这种每次启动就要加载几百个文件的框架,文件性能问题就尤其明显。

最好的验证方法就是进到容器里,strace一下php-fpm进程,看下系统调用的耗时,你就会发现大部分时间都是在stat或read,所以解决的思路就是减少网络文件系统的读写。

方案0: 开opcache,减少read调用

方案1:不使用SMB协议挂载文件,通过union、rsync之类的工具同步文件修改。

方案2: 用WSL2

方案3:修改cifs内核模块,单独加大vendor目录的缓存时间,因为vendor目录下的文件很少变更,加大文件信息的缓存时间可以减少大量网络调用。加上方案0,响应时间从1秒减少到0.1秒。(现在我就在用这个方案,自己在Hyper-V跑Arch Linux + 修改过的cifs模块化 + docker)

Github有相关的讨论:Shared Volumes Slow ,基本都是方案0-2。

在mac电脑上,可以使用"docker-machine-nfs"这个工具,把你的user文件夹挂载到docker容器中,这样就能解决使用传统的SMB协议进行挂载时需要通过网络来进行文件读取时的高延时问题。
但是这个工具在windows上不能使用,目前windows上可以考虑使用楼上所说的方法。
或者这样:
在容器中安装ftp服务,在phpstorm上配置laravel项目的文件夹映射,保存文件时实时FTP同步文件到docker容器中。在实例化镜像生成容器时,不要对laravel项目进行文件夹映射(-v参数设置),但是仍然可以对其他项目(不会出现运行时可能同时加载很多文件(超过17k))进行文件夹映射。这样相当于,单独对laravel项目的文件同步机制做了设置(使用FTP同步,而不是SMB),同时在nginx的虚拟主机文件配置处,设置root为对应的docker容器的项目路径。
这个过程略为繁琐:
1) 容器中安装ftp默认是不能正常运行的,需要在实例化生成容器时加privilege参数;
2) 对于要进行ftp同步的项目,需要使用docker cp手动复制一次,如果项目文件比较大,会比较耗时;
3) 同时phpstorm也需要做相关的FTP同步设置。

备注:在linux系统中不会存在这个问题

参考:https://thepracticalsysadmin....

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题