У меня есть приложение laravel в среде докеров. В моем приложении у меня есть консольная команда, которая будет подключаться к брокеру MQTT и подписываться на определенную тему, а затем команда будет обрабатывать сообщение, полученное от брокера MQTT.
Это мой метод handle()
в классе команд:
public function handle()
{
$this->logger->info('Start connecting to broker.');
$subscribeTopic = '#';
$mqtt = MQTT::connection(MqttClient::MQTT_SUBSCRIBE_CONNECTION);
// Using a infinite loop for re-creating new connection in case current connection is broken
while (true) {
try {
if (!$mqtt->isConnected()) {
$this->logger->info('Client is disconnected. Re-connecting.');
$mqtt->connect();
}
$mqtt->subscribe($subscribeTopic, $this->handleSubscriberCallback());
$mqtt->loop(true);
} catch (Exception $exception) {
$this->logger->error($exception);
}
}
}
При запуске контейнера этот процесс автоматически запускается в фоновом режиме по команде
php artisan mqtt:start > /dev/null &
Процесс проверки запущен по команде ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
www 1 0.0 0.0 3832 3016 ? Ss 02:12 0:00 bash /usr/local/bin/cmd
www 64 0.1 1.0 126336 61000 ? S 02:12 0:02 php artisan mqtt:start
www 65 0.0 0.5 230460 35488 ? Ss 02:12 0:00 php-fpm: master process (/usr/local/etc/php-fpm.conf)
www 66 0.3 0.9 308336 57684 ? S 02:12 0:05 php-fpm: pool www
www 67 0.3 0.7 233172 46008 ? S 02:12 0:04 php-fpm: pool www
www 75 0.1 0.0 4096 3360 pts/0 Ss 02:34 0:00 bash
www 83 0.0 0.0 6696 2820 pts/0 R+ 02:35 0:00 ps aux
Эта команда работала нормально, но проблема возникает, когда клиент MQTT (моя ремесленная команда) постоянно получает сообщения, процесс останавливается без каких-либо журналов, ошибок или предупреждений.
Я пытался публиковать сообщения с разной задержкой при каждой публикации сообщения:
0.01
секундой -> процесс останавливается после ~ 4k5 сообщений0.1
-> остановка процесса после ~ 9k5 сообщенийМоя система:
Может кто знает откуда проблема? Или как я могу автоматически перезапустить свой процесс, когда он остановился. Спасибо
@Namoshek И подписчик, и издатель используют Qos 0. Я уверен, что издатель работает нормально, у меня есть другой клиент mqtt, подписавшийся на тему, в которой издатель публикует сообщения.
Я попробую использовать supervisord для автоматического перезапуска моего процесса, насколько смогу, спасибо за идею.
Кстати, просмотрите мой вопрос и обновите некоторую информацию для кого-то нужного.
Благодаря @Namoshek использование supervisor
решило проблему с помощью команды автоматического перезапуска при остановке.
Кроме того, файл журнала супервизора для процесса помог мне отладить мою ошибку. Это связано с ошибкой исчерпания памяти, вызванной Laravel Telescope. Когда я выключаю Телескоп, эта ошибка больше не возникает. Кроме того, когда я запускаю команду при запуске контейнера докеров, я использую команду php artisan mqtt:start > /dev/null &
, которая /dev/null
удаляет все ошибки вывода. Таким образом, я не мог отследить ошибку, выброшенную в журнал контейнера докеров.
Вы можете автоматически перезапустить свой процесс, подобно работникам очередей Laravel, используя supervisord или аналогичный. Ваша проблема может быть вызвана перегрузкой, хотя я не уверен, как это сделать. Вы используете QoS 0 для публикации сообщений или подписываетесь только с QoS 0? А вы уверены, что зависает подписчик, а не издатель (проверьте с помощью
mosquitto_sub
)? Если это постоянно воспроизводится, пожалуйста, создайте проблему в репозитории.