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

时间:2018-01-13 09:34:51

标签: docker

我在docker-container上运行php应用程序。当我连接到本地数据库时,响应非常快(<1秒)。当我连接到外部数据库(在google cloud或amazon aws上运行)时,性能非常慢(> 35秒)。

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

我已检查此链接web server running inside a docker container running inside an EC2 instance responses very slowly和此Docker slow non-local database access。这似乎是相关的,但不确定。

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

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

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

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

2)在Google Compute Engine上,我的应用在Docker容器中运行:

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

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

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

4)在PHP Google应用引擎灵活环境中:

  • Google Cloud SQL上的数据库:非常慢(> 35秒);
  • Amazon RDS上的数据库:非常慢(> 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

1 个答案:

答案 0 :(得分:2)

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

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

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

他们提供了workaround,但现在应该足以更新Docker来解决糟糕的表现。

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

调试

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

这些只是一般建议,但您可以找到更多信息,例如here或Docker论坛。

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

  • 我会检查来自容器的网络速度是否类似下载存储在Google云端存储中的文件以及任何随机网站

  • Ping MySql实例并比较延迟。

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

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

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

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

  • 检查/var/log下容器端存在的任何类型的日志,以及是否可以访问MySql instaces log

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

  • 我会尝试建立一个显示性能下降的基本示例,我会在docker对应的GitHub repository中打开一个问题。

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

P.S。 你也可以找到this有趣的,基本上是一个有问题连接到MySql实例并成功调试它的人