mirror of
https://github.com/certd/certd.git
synced 2026-04-14 12:30:54 +08:00
perf: 修复检查全部某些情况下无效的bug,优化公共触发站点证书检查定时逻辑
This commit is contained in:
@@ -13,13 +13,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import parser from "cron-parser";
|
||||
import { computed, ref } from "vue";
|
||||
import dayjs from "dayjs";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { getCronNextTimes } from "/@/components/cron-editor/utils";
|
||||
|
||||
const { t } = useI18n();
|
||||
import { getCronNextTimes } from "/@/components/cron-editor/utils";
|
||||
defineOptions({
|
||||
name: "CronEditor",
|
||||
});
|
||||
|
||||
@@ -121,7 +121,7 @@ export class SiteInfoController extends CrudController<SiteInfoService> {
|
||||
@Post('/checkAll', { description: Constants.per.authOnly, summary: "检查所有站点监控" })
|
||||
async checkAll() {
|
||||
const { projectId, userId } = await this.getProjectUserIdWrite()
|
||||
await this.service.checkAllByUsers(userId,projectId);
|
||||
this.service.triggerJobOnce(userId,projectId);
|
||||
return this.ok();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import {Autoload, Config, Init, Inject, Scope, ScopeEnum} from '@midwayjs/core';
|
||||
import {PipelineService} from '../pipeline/service/pipeline-service.js';
|
||||
import {logger} from '@certd/basic';
|
||||
import {SysSettingsService, SysSiteInfo} from '@certd/lib-server';
|
||||
import {SiteInfoService} from '../monitor/index.js';
|
||||
import {Cron} from '../cron/cron.js';
|
||||
import {UserSettingsService} from "../mine/service/user-settings-service.js";
|
||||
import {UserSiteMonitorSetting} from "../mine/service/models.js";
|
||||
import {getPlusInfo, isPlus} from "@certd/plus-core";
|
||||
import { logger } from '@certd/basic';
|
||||
import { SysSettingsService, SysSiteInfo } from '@certd/lib-server';
|
||||
import { getPlusInfo, isPlus } from "@certd/plus-core";
|
||||
import { Autoload, Config, Init, Inject, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import dayjs from "dayjs";
|
||||
import {NotificationService} from "../pipeline/service/notification-service.js";
|
||||
import {UserService} from "../sys/authority/service/user-service.js";
|
||||
import {Between} from "typeorm";
|
||||
import { Between } from "typeorm";
|
||||
import { DomainService } from '../cert/service/domain-service.js';
|
||||
import { Cron } from '../cron/cron.js';
|
||||
import { UserSiteMonitorSetting } from "../mine/service/models.js";
|
||||
import { UserSettingsService } from "../mine/service/user-settings-service.js";
|
||||
import { SiteInfoService } from '../monitor/index.js';
|
||||
import { NotificationService } from "../pipeline/service/notification-service.js";
|
||||
import { PipelineService } from '../pipeline/service/pipeline-service.js';
|
||||
import { UserService } from "../sys/authority/service/user-service.js";
|
||||
import { ProjectService } from '../sys/enterprise/service/project-service.js';
|
||||
|
||||
@Autoload()
|
||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||
@@ -47,6 +48,9 @@ export class AutoCRegisterCron {
|
||||
|
||||
@Inject()
|
||||
domainService: DomainService;
|
||||
@Inject()
|
||||
projectService: ProjectService;
|
||||
|
||||
|
||||
|
||||
@Init()
|
||||
@@ -72,9 +76,23 @@ export class AutoCRegisterCron {
|
||||
|
||||
async registerSiteMonitorCron() {
|
||||
//先注册公共job
|
||||
await this.siteInfoService.registerSiteMonitorJob()
|
||||
logger.info(`注册公共站点证书检查定时任务`)
|
||||
const randomMinute = Math.floor(Math.random() * 60)
|
||||
this.cron.register({
|
||||
name: 'siteMonitor',
|
||||
cron: `0 ${randomMinute} 0 * * *`,
|
||||
job:async ()=>{
|
||||
logger.info(`开始公共站点证书检查任务`)
|
||||
await this.siteInfoService.triggerCommonJob()
|
||||
logger.info(`公共站点证书检查任务完成`)
|
||||
},
|
||||
});
|
||||
logger.info(`注册公共站点证书检查定时任务完成`)
|
||||
|
||||
|
||||
|
||||
//注册用户独立的检查时间
|
||||
logger.info(`注册用户独立站点证书检查定时任务`)
|
||||
const monitorSettingList = await this.userSettingsService.list({
|
||||
query:{
|
||||
key: UserSiteMonitorSetting.__key__,
|
||||
@@ -87,10 +105,11 @@ export class AutoCRegisterCron {
|
||||
}
|
||||
await this.siteInfoService.registerSiteMonitorJob(item.userId,item.projectId)
|
||||
}
|
||||
logger.info(`注册用户独立站点证书检查定时任务完成`)
|
||||
|
||||
if (this.immediateTriggerSiteMonitor) {
|
||||
logger.info(`立即触发一次站点证书检查任务`)
|
||||
await this.siteInfoService.triggerJobOnce()
|
||||
logger.info(`立即触发一次公共站点证书检查任务`)
|
||||
await this.siteInfoService.triggerCommonJob()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {Inject, Provide, Scope, ScopeEnum} from "@midwayjs/core";
|
||||
import {BaseService, NeedSuiteException, NeedVIPException, SysSettingsService} from "@certd/lib-server";
|
||||
import {BaseService, Constants, NeedSuiteException, NeedVIPException, SysSettingsService} from "@certd/lib-server";
|
||||
import {InjectEntityModel} from "@midwayjs/typeorm";
|
||||
import {In, Repository} from "typeorm";
|
||||
import {SiteInfoEntity} from "../entity/site-info.js";
|
||||
@@ -19,6 +19,8 @@ import { dnsContainer } from "./dns-custom.js";
|
||||
import { merge } from "lodash-es";
|
||||
import { JobHistoryService } from "./job-history-service.js";
|
||||
import { JobHistoryEntity } from "../entity/job-history.js";
|
||||
import { UserService } from "../../sys/authority/service/user-service.js";
|
||||
import { ProjectService } from "../../sys/enterprise/service/project-service.js";
|
||||
|
||||
@Provide()
|
||||
@Scope(ScopeEnum.Request, {allowDowngrade: true})
|
||||
@@ -44,6 +46,10 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
@Inject()
|
||||
jobHistoryService: JobHistoryService;
|
||||
|
||||
@Inject()
|
||||
userService: UserService;
|
||||
@Inject()
|
||||
projectService: ProjectService;
|
||||
|
||||
@Inject()
|
||||
cron: Cron;
|
||||
@@ -353,18 +359,7 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
}
|
||||
}
|
||||
|
||||
async checkAllByUsers(userId: any,projectId?: number) {
|
||||
if (userId==null) {
|
||||
throw new Error("userId is required");
|
||||
}
|
||||
// const sites = await this.repository.find({
|
||||
// where: {userId,projectId}
|
||||
// });
|
||||
// this.checkList(sites,false);
|
||||
await this.triggerJobOnce(userId,projectId);
|
||||
}
|
||||
|
||||
async checkList(sites: SiteInfoEntity[],isCommon: boolean) {
|
||||
async checkList(sites: SiteInfoEntity[]) {
|
||||
const cache = {}
|
||||
const getFromCache = async (userId: number,projectId?: number) =>{
|
||||
const key = `${userId}_${projectId??""}`
|
||||
@@ -377,13 +372,6 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
}
|
||||
for (const site of sites) {
|
||||
const setting = await getFromCache(site.userId,site.projectId)
|
||||
if (isCommon) {
|
||||
//公共的检查,排除有设置cron的用户
|
||||
if (setting?.cron) {
|
||||
//设置了cron,跳过公共检查
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let retryTimes = setting?.retryTimes
|
||||
this.doCheck(site,true,retryTimes).catch(e => {
|
||||
logger.error(`检查站点证书失败,${site.domain}`, e.message);
|
||||
@@ -492,57 +480,73 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
}
|
||||
|
||||
async registerSiteMonitorJob(userId?: number,projectId?: number) {
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,projectId, UserSiteMonitorSetting);
|
||||
if (!setting.cron) {
|
||||
return;
|
||||
}
|
||||
//注册个人的 或项目的
|
||||
this.cron.register({
|
||||
name: `siteMonitor_${userId}_${projectId||""}`,
|
||||
cron: setting.cron,
|
||||
job: () => this.triggerJobOnce(userId,projectId),
|
||||
});
|
||||
}
|
||||
|
||||
if(userId == null){
|
||||
//注册公共job
|
||||
logger.info(`注册站点证书检查定时任务`)
|
||||
this.cron.register({
|
||||
name: 'siteMonitor',
|
||||
cron: '0 0 0 * * *',
|
||||
job:async ()=>{
|
||||
await this.triggerJobOnce()
|
||||
},
|
||||
});
|
||||
logger.info(`注册站点证书检查定时任务完成`)
|
||||
}else{
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,projectId, UserSiteMonitorSetting);
|
||||
if (!setting.cron) {
|
||||
return;
|
||||
async triggerCommonJob(){
|
||||
//遍历用户
|
||||
const userIds = await this.userService.getAllUserIds()
|
||||
for (const userId of userIds) {
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,null,UserSiteMonitorSetting)
|
||||
if(setting && setting.cron){
|
||||
//该用户有自定义检查时间,跳过公共job
|
||||
continue
|
||||
}
|
||||
//注册个人的 或项目的
|
||||
this.cron.register({
|
||||
name: `siteMonitor_${userId}_${projectId||""}`,
|
||||
cron: setting.cron,
|
||||
job: () => this.triggerJobOnce(userId,projectId),
|
||||
});
|
||||
await this.triggerJobOnce(userId)
|
||||
}
|
||||
|
||||
//遍历项目
|
||||
const projectIds = await this.projectService.getAllProjectIds()
|
||||
for (const projectId of projectIds) {
|
||||
const userId = Constants.enterpriseUserId
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,projectId,UserSiteMonitorSetting)
|
||||
if(setting && setting.cron){
|
||||
//该项目有自定义检查时间,跳过公共job
|
||||
continue
|
||||
}
|
||||
await this.triggerJobOnce(userId,projectId)
|
||||
}
|
||||
}
|
||||
|
||||
async triggerJobOnce(userId?:number,projectId?:number) {
|
||||
logger.info(`站点证书检查开始执行[${userId??'所有用户'}_${projectId??'所有项目'}]`);
|
||||
const query:any = { disabled: false };
|
||||
let jobEntity :Partial<JobHistoryEntity> = null;
|
||||
if(userId!=null){
|
||||
query.userId = userId;
|
||||
if(projectId){
|
||||
query.projectId = projectId;
|
||||
}
|
||||
//判断是否已关闭
|
||||
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(userId,projectId, UserSiteMonitorSetting);
|
||||
if (setting && !setting.cron) {
|
||||
return;
|
||||
}
|
||||
jobEntity = {
|
||||
userId,
|
||||
projectId,
|
||||
type:"siteCertMonitor",
|
||||
title: '站点证书检查',
|
||||
result:"start",
|
||||
startAt:new Date().getTime(),
|
||||
}
|
||||
await this.jobHistoryService.add(jobEntity);
|
||||
if(userId==null){
|
||||
throw new Error("userId is required");
|
||||
}
|
||||
const query:any = { disabled: false };
|
||||
query.userId = userId;
|
||||
if(projectId){
|
||||
query.projectId = projectId;
|
||||
}
|
||||
const siteCount = await this.repository.count({
|
||||
where: query,
|
||||
});
|
||||
if (siteCount === 0) {
|
||||
logger.info(`用户/项目[${userId}_${projectId||""}]没有站点证书需要检查`)
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info(`站点证书检查开始执行[${userId}_${projectId||""}]`);
|
||||
|
||||
let jobEntity :Partial<JobHistoryEntity> = null;
|
||||
|
||||
jobEntity = {
|
||||
userId,
|
||||
projectId,
|
||||
type:"siteCertMonitor",
|
||||
title: '站点证书检查',
|
||||
result:"start",
|
||||
startAt:new Date().getTime(),
|
||||
}
|
||||
await this.jobHistoryService.add(jobEntity);
|
||||
let offset = 0;
|
||||
const limit = 50;
|
||||
let count = 0;
|
||||
@@ -557,21 +561,18 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
|
||||
break;
|
||||
}
|
||||
offset += records.length;
|
||||
const isCommon = !userId;
|
||||
count += records.length;
|
||||
await this.checkList(records,isCommon);
|
||||
await this.checkList(records);
|
||||
}
|
||||
|
||||
logger.info(`站点证书检查完成[${userId??'所有用户'}_${projectId??'所有项目'}]`);
|
||||
if(jobEntity){
|
||||
await this.jobHistoryService.update({
|
||||
id: jobEntity.id,
|
||||
result: "done",
|
||||
content:`共检查${count}个站点`,
|
||||
endAt:new Date().getTime(),
|
||||
updateTime:new Date(),
|
||||
});
|
||||
}
|
||||
logger.info(`站点证书检查完成[${userId}_${projectId||""}]`);
|
||||
await this.jobHistoryService.update({
|
||||
id: jobEntity.id,
|
||||
result: "done",
|
||||
content:`共检查${count}个站点`,
|
||||
endAt:new Date().getTime(),
|
||||
updateTime:new Date(),
|
||||
});
|
||||
}
|
||||
|
||||
async batchDelete(ids: number[], userId: number,projectId?:number): Promise<void> {
|
||||
|
||||
@@ -320,8 +320,6 @@ export class SiteIpService extends BaseService<SiteIpEntity> {
|
||||
for (const item of list) {
|
||||
await this.add(item);
|
||||
}
|
||||
|
||||
// await this.checkAllByUsers(req.userId);
|
||||
};
|
||||
await batchAdd(list);
|
||||
}
|
||||
|
||||
@@ -400,7 +400,15 @@ export class UserService extends BaseService<UserEntity> {
|
||||
id: userId,
|
||||
...body,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
async getAllUserIds() {
|
||||
const users = await this.repository.find({
|
||||
select: ['id'],
|
||||
where: {
|
||||
status: 1,
|
||||
},
|
||||
})
|
||||
return users.map(item => item.id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,4 +284,14 @@ export class ProjectService extends BaseService<ProjectEntity> {
|
||||
return project?.isSystem ?? false;
|
||||
}
|
||||
|
||||
|
||||
async getAllProjectIds() {
|
||||
const projects = await this.repository.find({
|
||||
select: ['id'],
|
||||
where: {
|
||||
disabled: false,
|
||||
},
|
||||
})
|
||||
return projects.map(item => item.id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user