Изящное завершение работы микросервиса nodejs при использовании Docker Swarm

У меня есть несколько микросервисов, написанных на Nodejs Koa, работающих на Docker Swarm.

Поскольку инструменты оркестрации контейнеров, такие как Kubernetes или Swarm, могут мгновенно масштабировать службы, у меня есть вопрос о корректном завершении работы службы Nodejs, чтобы предотвратить незавершенный запущенный процесс.

Ниже приведен поток, о котором я могу думать:

  1. отправка сигнала SIGNINT каждому рабочему процессу. Отправляет ли docker swarm SIGNINT рабочему процессу при уменьшении масштаба службы?
  2. рабочий отвечает за перехват сигнала, очистку или освобождение любого используемого ресурса и завершение его процесса. Как я могу остановить новый запрос API, дождаться завершения любого запущенного процесса перед завершением работы?

    Некоторый код ниже из ссылки:

    process.on('SIGINT', () => {
      const cleanUp = () => {
        // How can I clean resources like DB connections using Sequelizer
      }
    
      server.close(() => {
    
        cleanUp()
        process.exit()
      })
    
      // Force close server after 5secs, `Should I do this?`
      setTimeout((e) => {
        cleanUp()
        process.exit(1)
      }, 5000)
    })
    

person Alvin    schedule 18.09.2017    source источник
comment
Я считаю, что Docker Swarm отправляет SIGTERM, а затем SIGKILL, поэтому вы можете переместить свой код в process.on('SIGTERM', () => {})   -  person Jarede    schedule 27.10.2020


Ответы (1)


Я создал библиотеку (https://github.com/sebhildebrandt/http-graceful-shutdown), который может обрабатывать изящные отключения, как вы описали. Хорошо работает с Express и Koa.

Этот пакет также позволяет вам создать функцию (должна возвращать обещание) для дополнительной очистки таких вещей, как БД,... вот пример кода, как его использовать:

const gracefulShutdown = require('http-graceful-shutdown');
...
server = app.listen(...);
...

// your personal cleanup function - this one takes one second to complete
function cleanup() {
  return new Promise((resolve) => {
    console.log('... in cleanup')
    setTimeout(function() {
        console.log('... cleanup finished');
        resolve();
    }, 1000)       
  });
}

// this enables the graceful shutdown with advanced options
gracefulShutdown(server,
    {
        signals: 'SIGINT SIGTERM',
        timeout: 30000,
        development: false,
        onShutdown: cleanup,
        finally: function() {
            console.log('Server gracefulls shutted down.....')
        }
    }
);

Лично я бы увеличил конечное время ожидания с 5 секунд до более высокого значения (10-30 секунд). Надеюсь, это поможет.

person Sebastian Hildebrandt    schedule 21.09.2017