草庐IT

连接到本地数据库时 Docker 容器运行速度很快,但在外部数据库上运行速度很慢

coder 2023-05-06 原文

我正在一个 docker 容器上运行一个 php 应用程序。当我连接到本地数据库时,响应非常快(< 1="" 秒)。当我连接到外部数据库(在谷歌云或亚马逊="" aws="" 上运行)时,性能真的很慢(=""> 35 秒)。

我已尝试使用我找到的几个链接中描述的 Google 的 DNS,但没有运气。我的 DNS 解析在 docker 容器内非常快,我直接使用 IP 地址连接到 Google Cloud SQL DB。

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

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

所以,总结一下我用来测试的场景(数据库内容完全相同):

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

  • 我的本地主机 (MAMP) 上的数据库:非常快(< 1="">
  • Google Cloud SQL 上的数据库:非常慢(> 35 秒);
  • Amazon RDS 上的数据库:非常慢(> 35 秒);

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

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

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

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

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

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

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

  • Google Cloud SQL 上的数据库:非常快(< 1="">
  • Amazon RDS 上的数据库:非常快(< 1="">

6) 我的应用程序在本地主机 (Mac) 上的 Docker 之外运行:

  • Google Cloud SQL 上的数据库:非常快(< 1="">
  • Amazon RDS 上的数据库:非常快(< 1="">
  • 我的本地主机 (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

最佳答案

首先你使用的是哪个版本的Docker?

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

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

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

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

调试

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

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

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

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

  • Ping MySql 实例并比较延迟。

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

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

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

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

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

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

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

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

附: 您还可以找到 this有趣,基本上是一个人无法连接到 MySql 实例并成功调试它

关于连接到本地数据库时 Docker 容器运行速度很快,但在外部数据库上运行速度很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48238592/

有关连接到本地数据库时 Docker 容器运行速度很快,但在外部数据库上运行速度很慢的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  4. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  5. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  6. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  7. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  8. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  9. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  10. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

随机推荐