Docker容器在连接到localhost db时运行速度很快但在外部db上运行速度很慢

Ren*_*Ren 15 docker

我在docker-container上运行php应用程序.当我连接到本地数据库时,响应非常快(<1秒).当我连接到外部数据库(在谷歌云或亚马逊aws上运行)时,性能非常慢(> 35秒).

我尝试过使用谷歌的DNS,如我发现的一些链接所描述但没有运气.我的DNS解析在docker容器内非常快,并且连接到Google Cloud SQL DB我直接使用IP地址.

我已经检查了在EC2实例内部运行的docker容器内运行的这个链接Web服务器响应非常慢,这个Docker减慢了非本地数据库访问速度.这似乎是相关的,但不确定.

我认为这是一个Docker问题,或者与容器有些相关,因为在其他应用程序上使用相同的远程数据库(在google cloud和aws上)并且速度非常快.在我看来,它与容器内的网络有关.

所以,总结一下我用于测试的场景(DB内容完全相同):

1)在我的Mac上作为Localhost在Docker容器中运行我的应用程序:

  • 我的localhost(MAMP)上的数据库:非常快(<1秒);
  • Google Cloud SQL上的数据库:非常慢(> 35秒);
  • Amazon RDS上的DB:非常慢(> 35秒);

2)在我的应用程序在Docker容器内运行的Google Compute Engine上:

  • Google Cloud SQL上的数据库:非常慢(> 35秒);
  • Amazon RDS上的DB:非常慢(> 35秒);

3)在我的应用程序在Docker中运行的自定义Google应用程序引擎flex环境中:

  • Google Cloud SQL上的数据库:非常慢(> 35秒);
  • Amazon RDS上的DB:非常慢(> 35秒);

4)在PHP Google应用程序引擎flex环境中:

  • Google Cloud SQL上的数据库:非常慢(> 35秒);
  • Amazon RDS上的DB:非常慢(> 35秒);

5)我的应用程序在Google Compute Engine实例(PHP + apache)上运行Docker之外:

  • Google Cloud SQL上的数据库:非常快(<1秒);
  • Amazon RDS上的数据库:非常快(<1秒);

6)我的应用程序在localhost(Mac)上运行Docker之外:

  • Google Cloud SQL上的数据库:非常快(<1秒);
  • Amazon RDS上的数据库:非常快(<1秒);
  • 我的localhost(MAMP)上的数据库:非常快(<1秒);

有谁知道解决问题或找到问题的方法?我知道这是一个可能难以解决的问题.所以,我的问题与我应该如何调试以找到问题更相关.

我的Dockerfile:


    FROM php:7.0.17-apache

    RUN apt-get update
    RUN apt-get install -y apt-utils curl vim
    RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli
    RUN docker-php-ext-install pdo pdo_mysql && docker-php-ext-enable pdo_mysql
    RUN pecl install xdebug
    # The base image does not have php.ini.
    # Copy our own, with xdebug settings
    ADD ./php.ini /usr/local/etc/php/

    # Configure apache
    RUN a2enmod rewrite
    RUN a2dissite 000-default.conf

    # Copy sites available
    ADD ./www.metalar.net.conf /etc/apache2/sites-available/

    # Copy Ports file
    ADD ./ports.conf /etc/apache2/

    # Copy Ports file
    ADD ./apache2.conf /etc/apache2/apache2.conf

    # Copy error log
    ADD ./error.log /var/log/apache2/error.log

    # Make directory to host project files
    RUN mkdir -p /srv/www/www.metalar.net

    # Copy App to proper destination
    ADD . /srv/www/www.metalar.net

    # Enable config
    RUN a2ensite www.metalar.net.conf

    EXPOSE 8080

netstat -s

Ip:
    187 total packets received
    0 forwarded
    0 incoming packets discarded
    187 incoming packets delivered
    163 requests sent out
Icmp:
    0 ICMP messages received
    0 input ICMP message failed.
    ICMP input histogram:
    0 ICMP messages sent
    0 ICMP messages failed
    ICMP output histogram:
Tcp:
    2 active connections openings
    0 passive connection openings
    0 failed connection attempts
    0 connection resets received
    0 connections established
    181 segments received
    157 segments send out
    0 segments retransmited
    0 bad segments received.
    0 resets sent
Udp:
    6 packets received
    0 packets to unknown port received.
    0 packet receive errors
    6 packets sent
UdpLite:
TcpExt:
    2 TCP sockets finished time wait in fast timer
    171 packet headers predicted
    4 acknowledgments not containing data payload received
    TCPRcvCoalesce: 82
    TCPOrigDataSent: 4
IpExt:
    InOctets: 234466
    OutOctets: 7205
    InNoECTPkts: 187

Gal*_*one 5

首先,您使用的 Docker 版本是什么?

因为前段时间我在 Mac 上运行的 Docker 遇到了类似的问题,并且我发现了 Docker for MAC 的一个已知问题也可能与您相关。

此问题已映射到以下问题。

他们提供了一个解决方法,但现在应该足以更新 Docker 来解决性能不佳的问题。

然而,这些已知问题无法解释行为 #2 和 #3,所以我猜它不相关,但值得我提及。

调试

关键是这不是服务器或应用程序的问题,因此我将重点调试 Docker 的网络部分,该部分由于某种原因未按预期工作。

这些只是一般建议,但您可以在此处或 Docker 论坛中找到更多信息。

为了调试,我将打开两个终端,在第一个终端上,我将 ssh 进入容器,与本地计算机并行运行所有命令,以便比较结果。

  • 我会检查容器的网络速度是否与存储在 Google 云存储和任何随机网站中的下载文件相似

  • PingMySql 实例并比较延迟。

  • Traceroute发送到 MySql 实例并检查数据包的路径和每一跳的延迟。

  • 尝试通过命令行连接到MySql,并比较建立连接和执行基本操作(创建、更新、上传、删除、ecc)的时间。

  • 通过tcpdump(仅从容器),我将检查两个实例之间的流量,以查找连接到数据库实例和运行应用程序时的任何类型或错误、连接重置、数据包畸形

  • 也尝试执行一些 DNS 查找并比较时间

  • 还检查容器端中存在的任何类型的日志/var/log,以及您是否有权访问 MySql 实例日志

  • 尝试了解哪些操作实际上需要在容器内执行更长的时间(是否只是连接到服务器?整个过程是否变慢?是否在大量数据传输期间?)

  • 我会尝试构建一个显示性能下降的基本示例,并在 docker 相应的 GitHub存储库中提出一个问题。

如果您发现本地主机和容器中运行的命令之间存在任何差异,请更新问题以查看是否有人可以帮助您实际解决问题。

PS 你也可以发现这个有趣的事情,基本上是一个人在连接到 MySql 实例并成功调试它时遇到问题