Изменен алгоритм останова сервера - добавлен таймаут останова, экземпляр ParusAppServer больше не управляет процессом (убрал process.exit), переписан перехват сигналов останова
This commit is contained in:
parent
f01ee89790
commit
dd9f5cddbb
@ -7,6 +7,12 @@
|
|||||||
// Тело модуля
|
// Тело модуля
|
||||||
//------------
|
//------------
|
||||||
|
|
||||||
|
//Общие параметры
|
||||||
|
let common = {
|
||||||
|
//Таймаут останова сервера (мс)
|
||||||
|
nTerminateTimeout: 60000
|
||||||
|
};
|
||||||
|
|
||||||
//Параметры подключения к БД
|
//Параметры подключения к БД
|
||||||
let dbConnect = {
|
let dbConnect = {
|
||||||
//Пользователь БД
|
//Пользователь БД
|
||||||
@ -60,6 +66,7 @@ let mail = {
|
|||||||
//-----------------
|
//-----------------
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
common,
|
||||||
dbConnect,
|
dbConnect,
|
||||||
outGoing,
|
outGoing,
|
||||||
inComing,
|
inComing,
|
||||||
|
16
core/app.js
16
core/app.js
@ -40,6 +40,8 @@ class ParusAppServer {
|
|||||||
this.notifier = null;
|
this.notifier = null;
|
||||||
//Флаг остановки сервера
|
//Флаг остановки сервера
|
||||||
this.bStopping = false;
|
this.bStopping = false;
|
||||||
|
//Таймаут останова сервера
|
||||||
|
this.terminateTimeout = null;
|
||||||
//Список обслуживаемых сервисов
|
//Список обслуживаемых сервисов
|
||||||
this.services = [];
|
this.services = [];
|
||||||
//Привяжем методы к указателю на себя для использования в обработчиках событий
|
//Привяжем методы к указателю на себя для использования в обработчиках событий
|
||||||
@ -175,16 +177,14 @@ class ParusAppServer {
|
|||||||
await this.logger.warn("Отключение сервера приложений от БД...");
|
await this.logger.warn("Отключение сервера приложений от БД...");
|
||||||
try {
|
try {
|
||||||
await this.dbConn.disconnect();
|
await this.dbConn.disconnect();
|
||||||
process.exit(0);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await this.logger.error(`Ошибка отключения от БД: ${e.sCode}: ${e.sMessage}`);
|
await this.logger.error(`Ошибка отключения от БД: ${e.sCode}: ${e.sMessage}`);
|
||||||
process.exit(1);
|
|
||||||
}
|
}
|
||||||
} else {
|
//Мы закончили останов - сброс таймера аварийного останова, процесс завершится самостоятельно
|
||||||
process.exit(0);
|
if (this.terminateTimeout) {
|
||||||
|
clearTimeout(this.terminateTimeout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
process.exit(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Инициализация сервера
|
//Инициализация сервера
|
||||||
@ -252,10 +252,12 @@ class ParusAppServer {
|
|||||||
await this.dbConn.connect();
|
await this.dbConn.connect();
|
||||||
}
|
}
|
||||||
//Останов сервера
|
//Останов сервера
|
||||||
async stop() {
|
async stop(terminateTimeout) {
|
||||||
if (!this.bStopping) {
|
if (!this.bStopping) {
|
||||||
//Установим флаг - остановка в процессе
|
//Установим флаг - остановка в процессе
|
||||||
this.bStopping = true;
|
this.bStopping = true;
|
||||||
|
//Запомним таймер аварийного останова
|
||||||
|
this.terminateTimeout = terminateTimeout;
|
||||||
//Сообщаем, что начался останов сервера
|
//Сообщаем, что начался останов сервера
|
||||||
await this.logger.warn("Останов сервера приложений...");
|
await this.logger.warn("Останов сервера приложений...");
|
||||||
//Останов обслуживания очереди исходящих
|
//Останов обслуживания очереди исходящих
|
||||||
|
63
index.js
63
index.js
@ -10,7 +10,8 @@
|
|||||||
require("module-alias/register"); //Поддержка псевонимов при подключении модулей
|
require("module-alias/register"); //Поддержка псевонимов при подключении модулей
|
||||||
const cfg = require("./config"); //Настройки сервера приложений
|
const cfg = require("./config"); //Настройки сервера приложений
|
||||||
const app = require("./core/app"); //Сервер приложений
|
const app = require("./core/app"); //Сервер приложений
|
||||||
const { makeErrorText } = require("./core/utils"); //Вспомогательные функции
|
const { makeErrorText, getNowString } = require("./core/utils"); //Вспомогательные функции
|
||||||
|
const { SCONSOLE_LOG_COLOR_PATTERN_ERR, SCONSOLE_LOG_COLOR_PATTERN_WRN } = require("./core/constants"); //Общие константы
|
||||||
|
|
||||||
//--------------------------
|
//--------------------------
|
||||||
// Глобальные идентификаторы
|
// Глобальные идентификаторы
|
||||||
@ -28,43 +29,41 @@ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|||||||
//Обработка события "выход" жизненного цикла процесса
|
//Обработка события "выход" жизненного цикла процесса
|
||||||
process.on("exit", code => {
|
process.on("exit", code => {
|
||||||
//Сообщим о завершении процесса
|
//Сообщим о завершении процесса
|
||||||
appSrv.logger.warn("Сервер приложений остановлен (код: " + code + ") ");
|
console.log(
|
||||||
|
SCONSOLE_LOG_COLOR_PATTERN_WRN,
|
||||||
|
`${getNowString()} ПРЕДУПРЕЖДЕНИЕ: `,
|
||||||
|
`Сервер приложений остановлен (код: ${code})`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
//Перехват CTRL + C (останов процесса)
|
["SIGINT", "SIGQUIT", "SIGTERM"].forEach(sSig => {
|
||||||
process.on("SIGINT", async () => {
|
process.on(sSig, async () => {
|
||||||
appSrv.logger.warn("Получен сигнал на останов сервера приложений: SIGINT");
|
await appSrv.logger.warn(`Получен сигнал на останов сервера приложений: ${sSig}`);
|
||||||
//Инициируем выход из процесса
|
const terminateTimeout = setTimeout(() => {
|
||||||
await appSrv.stop();
|
console.log(
|
||||||
});
|
SCONSOLE_LOG_COLOR_PATTERN_ERR,
|
||||||
|
`${getNowString()} ОШИБКА: `,
|
||||||
//Перехват CTRL + \ (останов процесса)
|
`Истекло время ожидания останова сервера приложений. Инициирован аварийный выход из процесса.`
|
||||||
process.on("SIGQUIT", () => {
|
);
|
||||||
appSrv.logger.warn("Получен сигнал на останов сервера приложений: SIGQUIT");
|
process.exit(1);
|
||||||
//Инициируем выход из процесса
|
}, cfg.common.nTerminateTimeout);
|
||||||
appSrv.stop();
|
try {
|
||||||
});
|
await appSrv.stop(terminateTimeout);
|
||||||
|
} catch (e) {
|
||||||
//Перехват мягкого останова процесса
|
console.log(e);
|
||||||
process.on("SIGTERM", () => {
|
await appSrv.logger.error(`При останове сервера приложений: ${makeErrorText(e)}`);
|
||||||
appSrv.logger.warn("Получен сигнал на останов сервера приложений: SIGTERM");
|
clearTimeout(terminateTimeout);
|
||||||
//Инициируем выход из процесса
|
process.exit(1);
|
||||||
appSrv.stop();
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Грубый останов процесса (здесь сделать ничего нельзя, но мы пытаемся)
|
|
||||||
process.on("SIGKILL", () => {
|
|
||||||
appSrv.logger.warn("Получен сигнал на останов сервера приложений: SIGKILL");
|
|
||||||
//Инициируем выход из процесса
|
|
||||||
appSrv.stop();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//Перехват всех неохваченных ошибок
|
//Перехват всех неохваченных ошибок
|
||||||
process.on("uncaughtException", e => {
|
process.on("uncaughtException", e => {
|
||||||
//Протоколируем ошибку
|
//Протоколируем ошибку
|
||||||
appSrv.logger.error(makeErrorText(e));
|
console.log(SCONSOLE_LOG_COLOR_PATTERN_ERR, `${getNowString()} НЕПРЕДВИДЕННАЯ ОШИБКА: `, makeErrorText(e));
|
||||||
//Инициируем выход из процесса
|
//Останов с ошибкой
|
||||||
appSrv.stop();
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
//Запуск сервера приложений
|
//Запуск сервера приложений
|
||||||
@ -82,7 +81,7 @@ const start = async () => {
|
|||||||
await appSrv.stop();
|
await appSrv.stop();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
//Могут быть ошибки и при остановке - это аварийный выход
|
//Могут быть ошибки и при остановке - это аварийный выход
|
||||||
appSrv.logger.error(makeErrorText(e));
|
await appSrv.logger.error(makeErrorText(e));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,9 @@ const Schema = require("validate"); //Схемы валидации
|
|||||||
// Тело модуля
|
// Тело модуля
|
||||||
//-------------
|
//-------------
|
||||||
|
|
||||||
|
//Функция проверки значения таймаута останова сервера
|
||||||
|
const validateTerminateTimeout = val => val >= 1000 && val <= 120000 && Number.isInteger(val);
|
||||||
|
|
||||||
//Функция проверки значения размера блока одновременно обрабатываемых исходящих сообщений
|
//Функция проверки значения размера блока одновременно обрабатываемых исходящих сообщений
|
||||||
const validateMaxWorkers = val => val >= 1 && val <= 100 && Number.isInteger(val);
|
const validateMaxWorkers = val => val >= 1 && val <= 100 && Number.isInteger(val);
|
||||||
|
|
||||||
@ -25,6 +28,22 @@ const validateInComingPort = val => val >= 0 && val <= 65535 && Number.isInteger
|
|||||||
//Функция проверки значения порта сервера обслуживания входящих сообщений
|
//Функция проверки значения порта сервера обслуживания входящих сообщений
|
||||||
const validateMsgMaxSize = val => val >= 1 && val <= 1000 && Number.isInteger(val);
|
const validateMsgMaxSize = val => val >= 1 && val <= 1000 && Number.isInteger(val);
|
||||||
|
|
||||||
|
//Схема валидации общих параметров сервера приложений
|
||||||
|
const common = new Schema({
|
||||||
|
//Таймаут останова сервера (мс)
|
||||||
|
nTerminateTimeout: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
use: { validateTerminateTimeout },
|
||||||
|
message: {
|
||||||
|
type: path => `Таймаут останова сервера (${path}) имеет некорректный тип данных (ожидалось - Number)`,
|
||||||
|
required: path => `Не указан таймаут останова сервера (${path})`,
|
||||||
|
validateTerminateTimeout: path =>
|
||||||
|
`Таймаут останова сервера (${path}) должен быть целым числом в диапазоне от 1000 до 120000`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
//Схема валидации параметров подключения к БД
|
//Схема валидации параметров подключения к БД
|
||||||
const dbConnect = new Schema({
|
const dbConnect = new Schema({
|
||||||
//Пользователь БД
|
//Пользователь БД
|
||||||
@ -209,6 +228,14 @@ const mail = new Schema({
|
|||||||
|
|
||||||
//Схема валидации файла конфигурации
|
//Схема валидации файла конфигурации
|
||||||
const config = new Schema({
|
const config = new Schema({
|
||||||
|
//Общие параметры
|
||||||
|
common: {
|
||||||
|
schema: common,
|
||||||
|
required: true,
|
||||||
|
message: {
|
||||||
|
required: path => `Не указаны общие параметры конфигурации сервера приложений (${path})`
|
||||||
|
}
|
||||||
|
},
|
||||||
//Параметры подключения к БД
|
//Параметры подключения к БД
|
||||||
dbConnect: {
|
dbConnect: {
|
||||||
schema: dbConnect,
|
schema: dbConnect,
|
||||||
@ -247,6 +274,8 @@ const config = new Schema({
|
|||||||
// Интерфейс модуля
|
// Интерфейс модуля
|
||||||
//------------------
|
//------------------
|
||||||
|
|
||||||
|
//Схема валидации общих параметров сервера приложений
|
||||||
|
exports.common = common;
|
||||||
//Схема валидации записи журнала работы сервиса обмена
|
//Схема валидации записи журнала работы сервиса обмена
|
||||||
exports.dbConnect = dbConnect;
|
exports.dbConnect = dbConnect;
|
||||||
//Схема валидации параметров обработки очереди исходящих сообщений
|
//Схема валидации параметров обработки очереди исходящих сообщений
|
||||||
|
Loading…
x
Reference in New Issue
Block a user