mirror of
				https://github.com/whyour/qinglong.git
				synced 2025-10-31 17:06:07 +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 }) => { | ||||
|   await Sock({ server }); | ||||
|   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) => { | ||||
|     Logger.error('Uncaught exception:', error); | ||||
|  |  | |||
|  | @ -4,9 +4,9 @@ import cors from 'cors'; | |||
| import { Application, NextFunction, Request, Response } from 'express'; | ||||
| import jwt from 'express-jwt'; | ||||
| import Container from 'typedi'; | ||||
| import Logger from './logger'; | ||||
| import config from '../config'; | ||||
| import SystemService from '../services/system'; | ||||
| import Logger from './logger'; | ||||
| 
 | ||||
| export default ({ app }: { app: Application }) => { | ||||
|   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( | ||||
|     '/api/system', | ||||
|     async (req: Request, res: Response, next: NextFunction) => { | ||||
|  | @ -35,6 +49,7 @@ export default ({ app }: { app: Application }) => { | |||
|       } | ||||
|     }, | ||||
|   ); | ||||
| 
 | ||||
|   app.put( | ||||
|     '/api/data', | ||||
|     async (req: Request, res: Response, next: NextFunction) => { | ||||
|  |  | |||
|  | @ -1,20 +1,14 @@ | |||
| import { spawn } from 'cross-spawn'; | ||||
| 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 config from '../config'; | ||||
| import { | ||||
|   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 { TASK_COMMAND } from '../config/const'; | ||||
| import { | ||||
|   getPid, | ||||
|   killTask, | ||||
|  | @ -23,13 +17,23 @@ import { | |||
|   promiseExec, | ||||
|   readDirs, | ||||
| } 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 tar from 'tar'; | ||||
| import path from 'path'; | ||||
| import fs from 'fs'; | ||||
| import sum from 'lodash/sum'; | ||||
| import { DependenceModel, DependenceStatus, DependenceTypes } from '../data/dependence'; | ||||
| import NotificationService from './notify'; | ||||
| import ScheduleService, { TaskCallbacks } from './schedule'; | ||||
| import SockService from './sock'; | ||||
| 
 | ||||
| @Service() | ||||
| export default class SystemService { | ||||
|  | @ -139,7 +143,10 @@ export default class SystemService { | |||
|     } | ||||
|     let command = `cd && ${cmd}`; | ||||
|     const docs = await DependenceModel.findAll({ | ||||
|       where: { type: DependenceTypes.nodejs, status: DependenceStatus.installed }, | ||||
|       where: { | ||||
|         type: DependenceTypes.nodejs, | ||||
|         status: DependenceStatus.installed, | ||||
|       }, | ||||
|     }); | ||||
|     if (docs.length > 0) { | ||||
|       command += ` && pnpm i -g`; | ||||
|  | @ -326,7 +333,7 @@ export default class SystemService { | |||
|     return { code: 200 }; | ||||
|   } | ||||
| 
 | ||||
|   public async reloadSystem(target: 'system' | 'data') { | ||||
|   public async reloadSystem(target?: 'system' | 'data') { | ||||
|     const cmd = `real_time=true ql reload ${target || ''}`; | ||||
|     const cp = spawn(cmd, { shell: '/bin/bash' }); | ||||
|     cp.unref(); | ||||
|  | @ -382,8 +389,13 @@ export default class SystemService { | |||
| 
 | ||||
|   public async exportData(res: Response) { | ||||
|     try { | ||||
|       await tar.create( | ||||
|         { gzip: true, file: config.dataTgzFile, cwd: config.rootPath }, | ||||
|       tar.create( | ||||
|         { | ||||
|           gzip: true, | ||||
|           file: config.dataTgzFile, | ||||
|           cwd: config.rootPath, | ||||
|           sync: true, | ||||
|         }, | ||||
|         ['data'], | ||||
|       ); | ||||
|       res.download(config.dataTgzFile); | ||||
|  | @ -395,7 +407,7 @@ export default class SystemService { | |||
|   public async importData() { | ||||
|     try { | ||||
|       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 }; | ||||
|     } catch (error: any) { | ||||
|       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 "======================4. 启动pm2服务========================\n" | ||||
| reload_update | ||||
| reload_pm2 | ||||
| 
 | ||||
| if [[ $AutoStartBot == true ]]; then | ||||
|  |  | |||
|  | @ -1,14 +1,5 @@ | |||
| module.exports = { | ||||
|   apps: [ | ||||
|     { | ||||
|       name: 'update', | ||||
|       max_restarts: 10, | ||||
|       kill_timeout: 15000, | ||||
|       wait_ready: true, | ||||
|       listen_timeout: 10000, | ||||
|       time: true, | ||||
|       script: 'static/build/update.js', | ||||
|     }, | ||||
|     { | ||||
|       name: 'schedule', | ||||
|       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_nginx | ||||
|   check_pm2 | ||||
|   reload_update | ||||
|   reload_pm2 | ||||
|   echo -e "\n=====> 检测结束\n" | ||||
| } | ||||
|  |  | |||
|  | @ -305,6 +305,11 @@ random_range() { | |||
|   echo $((RANDOM % ($end - $beg) + $beg)) | ||||
| } | ||||
| 
 | ||||
| delete_pm2() { | ||||
|   cd $dir_root | ||||
|   pm2 delete ecosystem.config.js | ||||
| } | ||||
| 
 | ||||
| reload_pm2() { | ||||
|   cd $dir_root | ||||
|   restore_env_vars | ||||
|  | @ -312,6 +317,13 @@ reload_pm2() { | |||
|   pm2 startOrGracefulReload ecosystem.config.js | ||||
| } | ||||
| 
 | ||||
| reload_update() { | ||||
|   cd $dir_root | ||||
|   restore_env_vars | ||||
|   pm2 flush &>/dev/null | ||||
|   pm2 startOrGracefulReload other.config.js | ||||
| } | ||||
| 
 | ||||
| diff_time() { | ||||
|   local format="$1" | ||||
|   local begin_time="$2" | ||||
|  |  | |||
|  | @ -231,6 +231,8 @@ usage() { | |||
| } | ||||
| 
 | ||||
| reload_qinglong() { | ||||
|   delete_pm2 | ||||
| 
 | ||||
|   local reload_target="${1}" | ||||
|   local primary_branch="master" | ||||
|   if [[ "${QL_BRANCH}" == "develop" ]]; then | ||||
|  | @ -245,8 +247,8 @@ reload_qinglong() { | |||
|   fi | ||||
| 
 | ||||
|   if [[ "$reload_target" == 'data' ]]; then | ||||
|     rm -rf ${dir_root}/data | ||||
|     cp -rf ${dir_tmp}/data ${dir_root}/ | ||||
|     rm -rf ${dir_root}/data/* | ||||
|     mv -f ${dir_tmp}/data/* ${dir_root}/data/ | ||||
|   fi | ||||
| 
 | ||||
|   reload_pm2 | ||||
|  | @ -310,6 +312,8 @@ check_update_dep() { | |||
|     echo -e "更新包下载成功..." | ||||
| 
 | ||||
|     if [[ "$needRestart" == 'true' ]]; then | ||||
|       delete_pm2 | ||||
| 
 | ||||
|       cp -rf ${dir_tmp}/qinglong-${primary_branch}/* ${dir_root}/ | ||||
|       rm -rf $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 { request } from '@/utils/http'; | ||||
| import WebSocketManager from '@/utils/websocket'; | ||||
| 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; | ||||
| 
 | ||||
|  | @ -220,7 +220,7 @@ const CheckUpdate = ({ systemInfo }: any) => { | |||
|       </Button> | ||||
|       <Button | ||||
|         type="primary" | ||||
|         onClick={() => reloadSystem('system')} | ||||
|         onClick={() => reloadSystem('reload')} | ||||
|         style={{ marginLeft: 8 }} | ||||
|       > | ||||
|         {intl.get('重新启动')} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 whyour
						whyour