mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-22 22:36:06 +08:00
修改系统重启逻辑
This commit is contained in:
parent
2ac4581d54
commit
7a8a8ab9b3
|
@ -5,28 +5,6 @@ import Sock from './sock';
|
||||||
export default async ({ server }: { server: Server }) => {
|
export default async ({ server }: { server: Server }) => {
|
||||||
await Sock({ server });
|
await Sock({ server });
|
||||||
Logger.info('✌️ Sock loaded');
|
Logger.info('✌️ Sock loaded');
|
||||||
let exitTime = 0;
|
|
||||||
let timer: NodeJS.Timeout;
|
|
||||||
|
|
||||||
process.on('SIGINT', (singal) => {
|
|
||||||
Logger.warn(`Server need close, singal ${singal}`);
|
|
||||||
console.warn(`Server need close, singal ${singal}`);
|
|
||||||
exitTime++;
|
|
||||||
if (exitTime >= 3) {
|
|
||||||
Logger.warn('Forcing server close');
|
|
||||||
console.warn('Forcing server close');
|
|
||||||
clearTimeout(timer);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
server.close(() => {
|
|
||||||
if (timer) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
}
|
|
||||||
timer = setTimeout(() => {
|
|
||||||
process.exit();
|
|
||||||
}, 15000);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
process.on('uncaughtException', (error) => {
|
process.on('uncaughtException', (error) => {
|
||||||
Logger.error('Uncaught exception:', error);
|
Logger.error('Uncaught exception:', error);
|
||||||
|
|
|
@ -4,9 +4,9 @@ import cors from 'cors';
|
||||||
import { Application, NextFunction, Request, Response } from 'express';
|
import { Application, NextFunction, Request, Response } from 'express';
|
||||||
import jwt from 'express-jwt';
|
import jwt from 'express-jwt';
|
||||||
import Container from 'typedi';
|
import Container from 'typedi';
|
||||||
import Logger from './logger';
|
|
||||||
import config from '../config';
|
import config from '../config';
|
||||||
import SystemService from '../services/system';
|
import SystemService from '../services/system';
|
||||||
|
import Logger from './logger';
|
||||||
|
|
||||||
export default ({ app }: { app: Application }) => {
|
export default ({ app }: { app: Application }) => {
|
||||||
app.set('trust proxy', 'loopback');
|
app.set('trust proxy', 'loopback');
|
||||||
|
@ -22,6 +22,20 @@ export default ({ app }: { app: Application }) => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
app.put(
|
||||||
|
'/api/reload',
|
||||||
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const systemService = Container.get(SystemService);
|
||||||
|
const result = await systemService.reloadSystem();
|
||||||
|
res.send(result);
|
||||||
|
} catch (e) {
|
||||||
|
Logger.error('🔥 error: %o', e);
|
||||||
|
return next(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
app.put(
|
app.put(
|
||||||
'/api/system',
|
'/api/system',
|
||||||
async (req: Request, res: Response, next: NextFunction) => {
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
@ -35,6 +49,7 @@ export default ({ app }: { app: Application }) => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
app.put(
|
app.put(
|
||||||
'/api/data',
|
'/api/data',
|
||||||
async (req: Request, res: Response, next: NextFunction) => {
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
|
import { spawn } from 'cross-spawn';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
import { Service, Inject } from 'typedi';
|
import fs from 'fs';
|
||||||
|
import got from 'got';
|
||||||
|
import sum from 'lodash/sum';
|
||||||
|
import path from 'path';
|
||||||
|
import tar from 'tar';
|
||||||
|
import { Inject, Service } from 'typedi';
|
||||||
import winston from 'winston';
|
import winston from 'winston';
|
||||||
import config from '../config';
|
import config from '../config';
|
||||||
import {
|
import { TASK_COMMAND } from '../config/const';
|
||||||
AuthDataType,
|
|
||||||
AuthInfo,
|
|
||||||
SystemInstance,
|
|
||||||
SystemModel,
|
|
||||||
SystemModelInfo,
|
|
||||||
} from '../data/system';
|
|
||||||
import { NotificationInfo } from '../data/notify';
|
|
||||||
import NotificationService from './notify';
|
|
||||||
import ScheduleService, { TaskCallbacks } from './schedule';
|
|
||||||
import { spawn } from 'cross-spawn';
|
|
||||||
import SockService from './sock';
|
|
||||||
import got from 'got';
|
|
||||||
import {
|
import {
|
||||||
getPid,
|
getPid,
|
||||||
killTask,
|
killTask,
|
||||||
|
@ -23,13 +17,23 @@ import {
|
||||||
promiseExec,
|
promiseExec,
|
||||||
readDirs,
|
readDirs,
|
||||||
} from '../config/util';
|
} from '../config/util';
|
||||||
import { TASK_COMMAND } from '../config/const';
|
import {
|
||||||
|
DependenceModel,
|
||||||
|
DependenceStatus,
|
||||||
|
DependenceTypes,
|
||||||
|
} from '../data/dependence';
|
||||||
|
import { NotificationInfo } from '../data/notify';
|
||||||
|
import {
|
||||||
|
AuthDataType,
|
||||||
|
AuthInfo,
|
||||||
|
SystemInstance,
|
||||||
|
SystemModel,
|
||||||
|
SystemModelInfo,
|
||||||
|
} from '../data/system';
|
||||||
import taskLimit from '../shared/pLimit';
|
import taskLimit from '../shared/pLimit';
|
||||||
import tar from 'tar';
|
import NotificationService from './notify';
|
||||||
import path from 'path';
|
import ScheduleService, { TaskCallbacks } from './schedule';
|
||||||
import fs from 'fs';
|
import SockService from './sock';
|
||||||
import sum from 'lodash/sum';
|
|
||||||
import { DependenceModel, DependenceStatus, DependenceTypes } from '../data/dependence';
|
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export default class SystemService {
|
export default class SystemService {
|
||||||
|
@ -139,7 +143,10 @@ export default class SystemService {
|
||||||
}
|
}
|
||||||
let command = `cd && ${cmd}`;
|
let command = `cd && ${cmd}`;
|
||||||
const docs = await DependenceModel.findAll({
|
const docs = await DependenceModel.findAll({
|
||||||
where: { type: DependenceTypes.nodejs, status: DependenceStatus.installed },
|
where: {
|
||||||
|
type: DependenceTypes.nodejs,
|
||||||
|
status: DependenceStatus.installed,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
if (docs.length > 0) {
|
if (docs.length > 0) {
|
||||||
command += ` && pnpm i -g`;
|
command += ` && pnpm i -g`;
|
||||||
|
@ -326,7 +333,7 @@ export default class SystemService {
|
||||||
return { code: 200 };
|
return { code: 200 };
|
||||||
}
|
}
|
||||||
|
|
||||||
public async reloadSystem(target: 'system' | 'data') {
|
public async reloadSystem(target?: 'system' | 'data') {
|
||||||
const cmd = `real_time=true ql reload ${target || ''}`;
|
const cmd = `real_time=true ql reload ${target || ''}`;
|
||||||
const cp = spawn(cmd, { shell: '/bin/bash' });
|
const cp = spawn(cmd, { shell: '/bin/bash' });
|
||||||
cp.unref();
|
cp.unref();
|
||||||
|
@ -382,8 +389,13 @@ export default class SystemService {
|
||||||
|
|
||||||
public async exportData(res: Response) {
|
public async exportData(res: Response) {
|
||||||
try {
|
try {
|
||||||
await tar.create(
|
tar.create(
|
||||||
{ gzip: true, file: config.dataTgzFile, cwd: config.rootPath },
|
{
|
||||||
|
gzip: true,
|
||||||
|
file: config.dataTgzFile,
|
||||||
|
cwd: config.rootPath,
|
||||||
|
sync: true,
|
||||||
|
},
|
||||||
['data'],
|
['data'],
|
||||||
);
|
);
|
||||||
res.download(config.dataTgzFile);
|
res.download(config.dataTgzFile);
|
||||||
|
@ -395,7 +407,7 @@ export default class SystemService {
|
||||||
public async importData() {
|
public async importData() {
|
||||||
try {
|
try {
|
||||||
await promiseExec(`rm -rf ${path.join(config.tmpPath, 'data')}`);
|
await promiseExec(`rm -rf ${path.join(config.tmpPath, 'data')}`);
|
||||||
await tar.x({ file: config.dataTgzFile, cwd: config.tmpPath });
|
tar.x({ file: config.dataTgzFile, cwd: config.tmpPath, sync: true });
|
||||||
return { code: 200 };
|
return { code: 200 };
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return { code: 400, message: error.message };
|
return { code: 400, message: error.message };
|
||||||
|
|
|
@ -21,6 +21,7 @@ nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf
|
||||||
echo -e "nginx启动成功...\n"
|
echo -e "nginx启动成功...\n"
|
||||||
|
|
||||||
echo -e "======================4. 启动pm2服务========================\n"
|
echo -e "======================4. 启动pm2服务========================\n"
|
||||||
|
reload_update
|
||||||
reload_pm2
|
reload_pm2
|
||||||
|
|
||||||
if [[ $AutoStartBot == true ]]; then
|
if [[ $AutoStartBot == true ]]; then
|
||||||
|
|
|
@ -1,14 +1,5 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
apps: [
|
apps: [
|
||||||
{
|
|
||||||
name: 'update',
|
|
||||||
max_restarts: 10,
|
|
||||||
kill_timeout: 15000,
|
|
||||||
wait_ready: true,
|
|
||||||
listen_timeout: 10000,
|
|
||||||
time: true,
|
|
||||||
script: 'static/build/update.js',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'schedule',
|
name: 'schedule',
|
||||||
max_restarts: 10,
|
max_restarts: 10,
|
||||||
|
|
13
other.config.js
Normal file
13
other.config.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
module.exports = {
|
||||||
|
apps: [
|
||||||
|
{
|
||||||
|
name: 'update',
|
||||||
|
max_restarts: 10,
|
||||||
|
kill_timeout: 15000,
|
||||||
|
wait_ready: true,
|
||||||
|
listen_timeout: 10000,
|
||||||
|
time: true,
|
||||||
|
script: 'static/build/update.js',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
|
@ -81,6 +81,7 @@ main() {
|
||||||
check_ql
|
check_ql
|
||||||
check_nginx
|
check_nginx
|
||||||
check_pm2
|
check_pm2
|
||||||
|
reload_update
|
||||||
reload_pm2
|
reload_pm2
|
||||||
echo -e "\n=====> 检测结束\n"
|
echo -e "\n=====> 检测结束\n"
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,6 +305,11 @@ random_range() {
|
||||||
echo $((RANDOM % ($end - $beg) + $beg))
|
echo $((RANDOM % ($end - $beg) + $beg))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete_pm2() {
|
||||||
|
cd $dir_root
|
||||||
|
pm2 delete ecosystem.config.js
|
||||||
|
}
|
||||||
|
|
||||||
reload_pm2() {
|
reload_pm2() {
|
||||||
cd $dir_root
|
cd $dir_root
|
||||||
restore_env_vars
|
restore_env_vars
|
||||||
|
@ -312,6 +317,13 @@ reload_pm2() {
|
||||||
pm2 startOrGracefulReload ecosystem.config.js
|
pm2 startOrGracefulReload ecosystem.config.js
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reload_update() {
|
||||||
|
cd $dir_root
|
||||||
|
restore_env_vars
|
||||||
|
pm2 flush &>/dev/null
|
||||||
|
pm2 startOrGracefulReload other.config.js
|
||||||
|
}
|
||||||
|
|
||||||
diff_time() {
|
diff_time() {
|
||||||
local format="$1"
|
local format="$1"
|
||||||
local begin_time="$2"
|
local begin_time="$2"
|
||||||
|
|
|
@ -231,6 +231,8 @@ usage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
reload_qinglong() {
|
reload_qinglong() {
|
||||||
|
delete_pm2
|
||||||
|
|
||||||
local reload_target="${1}"
|
local reload_target="${1}"
|
||||||
local primary_branch="master"
|
local primary_branch="master"
|
||||||
if [[ "${QL_BRANCH}" == "develop" ]]; then
|
if [[ "${QL_BRANCH}" == "develop" ]]; then
|
||||||
|
@ -245,8 +247,8 @@ reload_qinglong() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$reload_target" == 'data' ]]; then
|
if [[ "$reload_target" == 'data' ]]; then
|
||||||
rm -rf ${dir_root}/data
|
rm -rf ${dir_root}/data/*
|
||||||
cp -rf ${dir_tmp}/data ${dir_root}/
|
mv -f ${dir_tmp}/data/* ${dir_root}/data/
|
||||||
fi
|
fi
|
||||||
|
|
||||||
reload_pm2
|
reload_pm2
|
||||||
|
@ -310,6 +312,8 @@ check_update_dep() {
|
||||||
echo -e "更新包下载成功..."
|
echo -e "更新包下载成功..."
|
||||||
|
|
||||||
if [[ "$needRestart" == 'true' ]]; then
|
if [[ "$needRestart" == 'true' ]]; then
|
||||||
|
delete_pm2
|
||||||
|
|
||||||
cp -rf ${dir_tmp}/qinglong-${primary_branch}/* ${dir_root}/
|
cp -rf ${dir_tmp}/qinglong-${primary_branch}/* ${dir_root}/
|
||||||
rm -rf $dir_static/*
|
rm -rf $dir_static/*
|
||||||
cp -rf ${dir_tmp}/qinglong-static-${primary_branch}/* ${dir_static}/
|
cp -rf ${dir_tmp}/qinglong-static-${primary_branch}/* ${dir_static}/
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import intl from 'react-intl-universal';
|
|
||||||
import React, { useEffect, useState, useRef, useCallback } from 'react';
|
|
||||||
import { Statistic, Modal, Tag, Button, Spin, message } from 'antd';
|
|
||||||
import { request } from '@/utils/http';
|
|
||||||
import config from '@/utils/config';
|
import config from '@/utils/config';
|
||||||
|
import { request } from '@/utils/http';
|
||||||
import WebSocketManager from '@/utils/websocket';
|
import WebSocketManager from '@/utils/websocket';
|
||||||
import Ansi from 'ansi-to-react';
|
import Ansi from 'ansi-to-react';
|
||||||
|
import { Button, Modal, Statistic, message } from 'antd';
|
||||||
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
|
||||||
const { Countdown } = Statistic;
|
const { Countdown } = Statistic;
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ const CheckUpdate = ({ systemInfo }: any) => {
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={() => reloadSystem('system')}
|
onClick={() => reloadSystem('reload')}
|
||||||
style={{ marginLeft: 8 }}
|
style={{ marginLeft: 8 }}
|
||||||
>
|
>
|
||||||
{intl.get('重新启动')}
|
{intl.get('重新启动')}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user