Я использую gRPC для связи между Java (работающей на хосте) и Python (работающей на моих гостевых виртуальных машинах). Моя программа устанавливает несколько виртуальных машин при запуске с помощью libvirt. Я указываю свою сеть с диапазоном DHCP следующим образом:
<network>
...
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.128' end='192.168.122.254'/>
<host mac="00:16:3e:77:e2:ed" ip="192.168.122.128"/>
<host mac="00:16:3e:3e:a9:1a" ip="192.168.122.129"/>
...
</dhcp>
</ip>
...
</network>
Как только все настроено и мои виртуальные машины запущены, я создаю моментальный снимок каждой виртуальной машины. Теперь рабочий процесс программного обеспечения выглядит следующим образом: откройте интерфейс gRPC для гостевой виртуальной машины с указанным выше IP-адресом для Mac-адреса, установите правильное время (время сейчас, отличается из-за моментального снимка и отсутствия доступа в Интернет), выполните некоторую работу, затем восстановить снимок и повторить.
В коде Python на виртуальной машине я отправляю хосту сообщение ping каждые 5 секунд (своего рода сердцебиение). В большинстве случаев это работает нормально, и я получаю сообщение на хосте в коде Java. Однако время от времени я больше не получаю сообщение на хосте в течение 3 минут (после чего я генерирую настраиваемое исключение тайм-аута). В коде Python нет ошибки или бесконечного цикла, и на стороне Java также не возникает никаких исключений. Так что проблема должна быть в другом месте.
Изучая причину такого странного поведения, я обнаружил время аренды DHCP. Мои виртуальные машины получают свой IP-адрес из диапазона DHCP, настроенного через libvirt (см. Выше). Срок действия аренды DHCP истекает через 1 час. Интересно, что этот тайм-аут от контрольных сообщений часто случается (если это случается, то не всегда) примерно через 1 час после того, как я сделал свои первоначальные снимки, из которых я выполняю восстановление. Может ли моя проблема быть связана с процедурой продления аренды DHCP, когда виртуальная машина внезапно оказывается в состоянии, когда у нее больше нет исходного IP-адреса? Так, например, что я открываю свое gRPC-соединение с 192.168.122.128, получаю контрольные сообщения, и внезапно из-за истечения срока аренды DHCP IP изменяется, и gRPC не может доставить дальнейшие сообщения? Если это может быть проблемой, что я могу сделать с этим?
Я также выполнил специальный тест, в котором я открываю соединение gRPC с виртуальной машиной, а затем вручную меняю IP-адрес на виртуальной машине, а затем меняю его обратно на исходный IP. Затем я наблюдал точно такое же поведение: через 3 минуты у меня возникло исключение тайм-аута, так как после ручного изменения больше не поступало никаких сообщений о пульсе. Поэтому у меня есть сильное ощущение, что каким-то образом IP на виртуальной машине меняется, что может быть связано с истекающим сроком аренды DHCP, и это мешает соединению gRPC.
Может быть, это проблема или может быть что-то совсем другое, что вызывает проблемы с подключением gRPC? Что я мог сделать с этой проблемой? Любая помощь или доработка приветствуются.
Я почти уверен, что большинство случаев, когда gRPC зависал, можно проследить до продления срока аренды DHCP. Я также подозреваю, что в целом, когда DHCP-сервер недоступен в любой момент времени, соединение gRPC зависает (я тестировал это, вручную установив системное время и позвонив ipconfig /renew
из командной строки. Затем я сначала получил тайм-аут DHCP, но потом он сработал. Но в результате gRPC завис, хотя я снова получил тот же IP). Поскольку я до сих пор не до конца понимаю поведение продления срока аренды DHCP и общие аспекты запросов к DHCP-серверу и его тайм-аутов, я решил больше не возиться с ним. Я решил использовать статические IP-адреса для своих снимков виртуальной машины (отключенный DHCP). Если кто-то сталкивается с той же проблемой, вы можете попробовать это. Надеюсь, поможет.