Контейнер Docker работает быстро при подключении к localhost db, но очень медленный на внешнем db
Я запускаю приложение php на контейнере-докере. Когда я подключаюсь к ответам локальной базы данных, очень быстро (< 1 секунда). Когда я подключаюсь к внешнему db (работает в облаке Google или amazon aws), производительность очень медленная ( > 35 секунд).
Я попытался использовать Google DNS, как описано в нескольких ссылках, которые я нашел, но не повезло. Мое DNS-разрешение очень быстро входит в контейнер докеров и подключается к базе данных Google Cloud SQL. Я напрямую использую IP-адрес.
Я проверил эту ссылку веб-сервер, запущенный внутри контейнера докеров, запущенный внутри экземпляров экземпляра EC2 очень медленно, и этот Docker медленный доступ к нелокальным базам данных. Кажется, что-то связано, но не уверен.
Я думаю, что это проблема Docker или несколько связана с контейнером, потому что тот же удаленный db (в облаке Google и aws) используется в других приложениях, и скорость очень быстрая. По-моему, это связано с сетью внутри контейнера.
Итак, чтобы подвести итог, это сценарии, которые я использовал для тестирования (содержимое БД - это то же самое):
1) На моем Mac, как Localhost, запускающее мое приложение внутри контейнера Docker:
- DB на моем localhost (MAMP): очень быстро (< 1 секунда);
- БД в Google Cloud SQL: очень медленно ( > 35 секунд);
- DB на Amazon RDS: очень медленно ( > 35 секунд);
2) На Google Compute Engine с моим приложением, запущенным внутри контейнера Docker:
- БД в Google Cloud SQL: очень медленно ( > 35 секунд);
- DB на Amazon RDS: очень медленно ( > 35 секунд);
3) В пользовательской среде Flex для приложений Google с моим приложением, запущенным внутри Docker:
- БД в Google Cloud SQL: очень медленно ( > 35 секунд);
- DB на Amazon RDS: очень медленно ( > 35 секунд);
4) В флеш-среде с PHP-движком PHP:
- БД в Google Cloud SQL: очень медленно ( > 35 секунд);
- DB на Amazon RDS: очень медленно ( > 35 секунд);
5) Когда мое приложение работает за пределами Docker на экземпляре Google Compute Engine (PHP + apache):
- БД в Google Cloud SQL: очень быстро (< 1 секунда);
- DB на Amazon RDS: очень быстро (< 1 секунда);
6) Когда мое приложение работает за пределами Docker на локальном хосте (Mac):
- БД в Google Cloud SQL: очень быстро (< 1 секунда);
- DB на Amazon RDS: очень быстро (< 1 секунда);
- DB на моем localhost (MAMP): очень быстро (< 1 секунда);
Кто-нибудь знает подход к решению проблемы или найти проблему? Я понимаю, что это проблема, которую трудно решить. Итак, мой вопрос больше связан с тем, как я должен отлаживать это, чтобы найти проблему.
My 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
Прежде всего, какая версия Docker вы используете?
Поскольку некоторое время назад у меня возникла аналогичная проблема с моим Docker, работающим на Mac, и я нашел известную проблему для Docker для MAC, которая также может быть связана с вами.
Эта проблема была отображена в следующую.
Они предоставили обходной путь, но сейчас должно быть достаточно, чтобы обновить Docker для решения плохих характеристик.
Однако эти известные проблемы не объяснят поведение # 2 и # 3, поэтому я думаю, что это не связано, но это стоит того, чтобы я упоминал.
Отладка
Дело в том, что это не проблема с сервером или с приложением, поэтому я бы сосредоточился на отладке сетевой части Docker, которая по какой-то причине не работает должным образом.
Это просто общие советы, но вы можете найти более подробную информацию, например здесь или вокруг форумов Docker.
Чтобы отлаживать, я бы открыл два терминала, и с первым я бы ssh в мой контейнер выполнял все команды параллельно с локальной машиной, чтобы сравнить результаты.
-
Я бы проверял, является ли скорость сети из контейнера одинаковым загружаемым файлом, хранящимся в облачном хранилище Google, и любой случайный веб-сайт
-
Ping
экземпляр MySql и сравните задержку.
-
Traceroute
к экземпляру MySql и проверить путь к пакетам и задержку на каждом переходе.
-
Попробуйте подключиться к MySql через командную строку и сравнить время для настройки соединения и выполнения основных операций (создание, обновление, загрузка, падение, ecc).
-
Через tcpdump
(только из контейнера) я бы проверил трафик между двумя экземплярами, ищущими какой-либо вид или ошибку, соединение reset, дефектность пакета при подключении к экземпляру db и при запуске приложения
-
Попробуйте также выполнить поиск DNS и сравнить время
-
Осмотрите также любой вид журнала, который присутствует на стороне контейнера в разделе /var/log
, и если у вас есть доступ к журналу журнала MySql
-
Попытайтесь понять, какая операция, которая на самом деле занимает больше времени, должна выполняться внутри контейнера (это просто подключение к серверу?) Это весь процесс, который замедляется? Это при огромных передачах данных?)
-
Я попытался бы создать важный пример, демонстрирующий ухудшение производительности, и я бы открыл проблему в docker, соответствующем репозитории GitHub .
Если вы обнаружите какое-либо несоответствие между командами, запущенными на локальном хосте и в контейнере, обновите вопрос, чтобы узнать, сможет ли кто-нибудь помочь вам решить проблему.
P.S.
Вы также можете найти этот интересный, в основном парень, имеющий проблемы с подключением к экземпляру MySql и успешной его отладкой