perf: 优化内存占用

pull/148/head
xiaojunnuo 2024-08-28 14:40:50 +08:00
parent 42a56b581d
commit db61033633
15 changed files with 98 additions and 80 deletions

View File

@ -16,4 +16,4 @@ run/
/data/db.sqlite /data/db.sqlite
*/node_modules */node_modules
certd-server/tools/windows/ certd-server/tools/windows/
.clinic

View File

@ -16,3 +16,4 @@ run/
/test/setup.js /test/setup.js
/test/setup.ts /test/setup.ts
/data/ /data/
.clinic

View File

@ -15,7 +15,8 @@
"ci": "npm run cov", "ci": "npm run cov",
"build": "mwtsc --cleanOutDir --skipLibCheck", "build": "mwtsc --cleanOutDir --skipLibCheck",
"build-on-docker": "node ./before-build.js && npm run build", "build-on-docker": "node ./before-build.js && npm run build",
"up-mw-deps": "npx midway-version -u -w" "up-mw-deps": "npx midway-version -u -w",
"clinic": "clinic heapprofiler -- node ./bootstrap.js"
}, },
"dependencies": { "dependencies": {
"@alicloud/cs20151215": "^3.0.3", "@alicloud/cs20151215": "^3.0.3",

View File

@ -11,10 +11,10 @@ import { PermissionService } from './permission-service.js';
import { UserRoleService } from './user-role-service.js'; import { UserRoleService } from './user-role-service.js';
import { Constants } from '../../../basic/constants.js'; import { Constants } from '../../../basic/constants.js';
import { UserRoleEntity } from '../entity/user-role.js'; import { UserRoleEntity } from '../entity/user-role.js';
import { randomText } from 'svg-captcha';
import bcrypt from 'bcryptjs'; import bcrypt from 'bcryptjs';
import { SysSettingsService } from '../../system/service/sys-settings-service.js'; import { SysSettingsService } from '../../system/service/sys-settings-service.js';
import { SysInstallInfo } from '../../system/service/models.js'; import { SysInstallInfo } from '../../system/service/models.js';
import { RandomUtil } from '../../../utils/random.js';
/** /**
* *
@ -64,7 +64,7 @@ export class UserService extends BaseService<UserEntity> {
if (!_.isEmpty(exists)) { if (!_.isEmpty(exists)) {
throw new CommonException('用户名已经存在'); throw new CommonException('用户名已经存在');
} }
const plainPassword = param.password ?? randomText(6); const plainPassword = param.password ?? RandomUtil.randomStr(6);
param.passwordVersion = 2; param.passwordVersion = 2;
param.password = await this.genPassword(plainPassword, param.passwordVersion); // 默认密码 建议未改密码不能登陆 param.password = await this.genPassword(plainPassword, param.passwordVersion); // 默认密码 建议未改密码不能登陆
await super.add(param); await super.add(param);
@ -156,7 +156,7 @@ export class UserService extends BaseService<UserEntity> {
passwordVersion: 2, passwordVersion: 2,
}); });
if (!newUser.password) { if (!newUser.password) {
newUser.password = randomText(6); newUser.password = RandomUtil.randomStr(6);
} }
newUser.password = await this.genPassword(newUser.password, newUser.passwordVersion); newUser.password = await this.genPassword(newUser.password, newUser.passwordVersion);

View File

@ -1,6 +1,5 @@
import { Inject, Provide } from '@midwayjs/core'; import { Inject, Provide } from '@midwayjs/core';
import { CacheManager } from '@midwayjs/cache'; import { CacheManager } from '@midwayjs/cache';
import svgCaptcha from 'svg-captcha';
// {data: '<svg.../svg>', text: 'abcd'} // {data: '<svg.../svg>', text: 'abcd'}
/** /**
@ -14,6 +13,7 @@ export class CodeService {
*/ */
async generateCaptcha(randomStr) { async generateCaptcha(randomStr) {
console.assert(randomStr < 10, 'randomStr 过长'); console.assert(randomStr < 10, 'randomStr 过长');
const svgCaptcha = await import('svg-captcha');
const c = svgCaptcha.create(); const c = svgCaptcha.create();
//{data: '<svg.../svg>', text: 'abcd'} //{data: '<svg.../svg>', text: 'abcd'}
const imgCode = c.text; // = RandomUtil.randomStr(4, true); const imgCode = c.text; // = RandomUtil.randomStr(4, true);

View File

@ -2,7 +2,6 @@ import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput,
// @ts-ignore // @ts-ignore
import { ROAClient } from '@alicloud/pop-core'; import { ROAClient } from '@alicloud/pop-core';
import { AliyunAccess } from '../../access/index.js'; import { AliyunAccess } from '../../access/index.js';
import { K8sClient } from '@certd/lib-k8s';
import { appendTimeSuffix } from '../../utils/index.js'; import { appendTimeSuffix } from '../../utils/index.js';
import { CertInfo } from '@certd/plugin-cert'; import { CertInfo } from '@certd/plugin-cert';
@ -105,8 +104,11 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
required: true, required: true,
}) })
accessId!: string; accessId!: string;
K8sClient: any;
async onInstance(): Promise<void> {} async onInstance() {
const sdk = await import('@certd/lib-k8s');
this.K8sClient = sdk.K8sClient;
}
async execute(): Promise<void> { async execute(): Promise<void> {
console.log('开始部署证书到阿里云cdn'); console.log('开始部署证书到阿里云cdn');
const { regionId, ingressClass, clusterId, isPrivateIpAddress, cert } = this; const { regionId, ingressClass, clusterId, isPrivateIpAddress, cert } = this;
@ -115,7 +117,7 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
const kubeConfigStr = await this.getKubeConfig(client, clusterId, isPrivateIpAddress); const kubeConfigStr = await this.getKubeConfig(client, clusterId, isPrivateIpAddress);
this.logger.info('kubeconfig已成功获取'); this.logger.info('kubeconfig已成功获取');
const k8sClient = new K8sClient({ const k8sClient = new this.K8sClient({
kubeConfigStr, kubeConfigStr,
logger: this.logger, logger: this.logger,
}); });
@ -131,7 +133,7 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
// await this.restartIngress({ k8sClient, props }) // await this.restartIngress({ k8sClient, props })
} }
async restartIngress(options: { k8sClient: K8sClient }) { async restartIngress(options: { k8sClient: any }) {
const { k8sClient } = options; const { k8sClient } = options;
const { namespace } = this; const { namespace } = this;
@ -168,7 +170,7 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
} }
} }
async patchNginxCertSecret(options: { cert: CertInfo; k8sClient: K8sClient }) { async patchNginxCertSecret(options: { cert: CertInfo; k8sClient: any }) {
const { cert, k8sClient } = options; const { cert, k8sClient } = options;
const crt = cert.crt; const crt = cert.crt;
const key = cert.key; const key = cert.key;

View File

@ -148,6 +148,7 @@ export class AsyncSsh2Client {
} }
} }
} }
export class SshClient { export class SshClient {
logger: ILogger; logger: ILogger;
constructor(logger: ILogger) { constructor(logger: ILogger) {

View File

@ -1,6 +1,5 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, utils } from '@certd/pipeline'; import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, utils } from '@certd/pipeline';
import { CertInfo } from '@certd/plugin-cert'; import { CertInfo } from '@certd/plugin-cert';
import { K8sClient } from '@certd/lib-k8s';
import { K8sAccess } from '../access/index.js'; import { K8sAccess } from '../access/index.js';
import { appendTimeSuffix } from '../../plugin-aliyun/utils/index.js'; import { appendTimeSuffix } from '../../plugin-aliyun/utils/index.js';
@ -65,10 +64,14 @@ export class K8STestPlugin extends AbstractTaskPlugin {
}) })
cert!: CertInfo; cert!: CertInfo;
async onInstance() {} K8sClient: any;
async onInstance() {
const sdk = await import('@certd/lib-k8s');
this.K8sClient = sdk.K8sClient;
}
async execute(): Promise<void> { async execute(): Promise<void> {
const access: K8sAccess = await this.accessService.getById(this.accessId); const access: K8sAccess = await this.accessService.getById(this.accessId);
const k8sClient = new K8sClient({ const k8sClient = new this.K8sClient({
kubeConfigStr: access.kubeconfig, kubeConfigStr: access.kubeconfig,
logger: this.logger, logger: this.logger,
}); });
@ -76,7 +79,7 @@ export class K8STestPlugin extends AbstractTaskPlugin {
await utils.sleep(3000); // 停留2秒等待secret部署完成 await utils.sleep(3000); // 停留2秒等待secret部署完成
} }
async patchNginxCertSecret(options: { cert: CertInfo; k8sClient: K8sClient }) { async patchNginxCertSecret(options: { cert: CertInfo; k8sClient: any }) {
const { cert, k8sClient } = options; const { cert, k8sClient } = options;
const crt = cert.crt; const crt = cert.crt;
const key = cert.key; const key = cert.key;

View File

@ -1,14 +1,7 @@
import { Autowire, HttpClient, ILogger } from '@certd/pipeline'; import { Autowire, HttpClient, ILogger } from '@certd/pipeline';
import { import { AbstractDnsProvider, CreateRecordOptions, IsDnsProvider, RemoveRecordOptions } from '@certd/plugin-cert';
AbstractDnsProvider,
CreateRecordOptions,
IsDnsProvider,
RemoveRecordOptions,
} from '@certd/plugin-cert';
import { TencentAccess } from '../access/index.js'; import { TencentAccess } from '../access/index.js';
import * as tencentcloud from 'tencentcloud-sdk-nodejs';
const DnspodClient = tencentcloud.dnspod.v20210323.Client;
@IsDnsProvider({ @IsDnsProvider({
name: 'tencent', name: 'tencent',
title: '腾讯云', title: '腾讯云',
@ -38,7 +31,8 @@ export class TencentDnsProvider extends AbstractDnsProvider {
}, },
}, },
}; };
const dnspodSdk: any = await import('tencentcloud-sdk-nodejs/tencentcloud/services/dnspod/v20210323/index.js');
const DnspodClient = dnspodSdk.Client;
// 实例化要请求产品的client对象,clientProfile是可选的 // 实例化要请求产品的client对象,clientProfile是可选的
this.client = new DnspodClient(clientConfig); this.client = new DnspodClient(clientConfig);
} }
@ -58,12 +52,7 @@ export class TencentDnsProvider extends AbstractDnsProvider {
try { try {
const ret = await this.client.CreateRecord(params); const ret = await this.client.CreateRecord(params);
this.logger.info( this.logger.info('添加域名解析成功:', fullRecord, value, JSON.stringify(ret));
'添加域名解析成功:',
fullRecord,
value,
JSON.stringify(ret)
);
/* /*
{ {
"RecordId": 162, "RecordId": 162,

View File

@ -1,5 +1,4 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline'; import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import tencentcloud from 'tencentcloud-sdk-nodejs';
import { TencentAccess } from '../../access/index.js'; import { TencentAccess } from '../../access/index.js';
import { CertInfo } from '@certd/plugin-cert'; import { CertInfo } from '@certd/plugin-cert';
@ -59,17 +58,17 @@ export class DeployToCdnPlugin extends AbstractTaskPlugin {
// }) // })
// endpoint!: string; // endpoint!: string;
async onInstance() {} Client: any;
async execute(): Promise<void> { async onInstance() {
const accessProvider: TencentAccess = (await this.accessService.getById(this.accessId)) as TencentAccess; const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/cdn/v20180606/index.js');
const client = this.getClient(accessProvider); this.Client = sdk.v20180606.Client;
const params = this.buildParams();
await this.doRequest(client, params);
} }
getClient(accessProvider: TencentAccess) { async getClient() {
const CdnClient = tencentcloud.cdn.v20180606.Client; const accessProvider: TencentAccess = (await this.accessService.getById(this.accessId)) as TencentAccess;
const CdnClient = this.Client;
const clientConfig = { const clientConfig = {
credential: { credential: {
@ -87,6 +86,11 @@ export class DeployToCdnPlugin extends AbstractTaskPlugin {
return new CdnClient(clientConfig); return new CdnClient(clientConfig);
} }
async execute(): Promise<void> {
const params = this.buildParams();
await this.doRequest(params);
}
buildParams() { buildParams() {
return { return {
Https: { Https: {
@ -100,7 +104,8 @@ export class DeployToCdnPlugin extends AbstractTaskPlugin {
}; };
} }
async doRequest(client: any, params: any) { async doRequest(params: any) {
const client = await this.getClient();
const ret = await client.UpdateDomainConfig(params); const ret = await client.UpdateDomainConfig(params);
this.checkRet(ret); this.checkRet(ret);
this.logger.info('设置腾讯云CDN证书成功:', ret.RequestId); this.logger.info('设置腾讯云CDN证书成功:', ret.RequestId);

View File

@ -1,5 +1,4 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, utils } from '@certd/pipeline'; import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, utils } from '@certd/pipeline';
import tencentcloud from 'tencentcloud-sdk-nodejs';
import { TencentAccess } from '../../access/index.js'; import { TencentAccess } from '../../access/index.js';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@ -92,11 +91,37 @@ export class DeployToClbPlugin extends AbstractTaskPlugin {
}) })
accessId!: string; accessId!: string;
async onInstance() {} client: any;
async execute(): Promise<void> {
const accessProvider = (await this.accessService.getById(this.accessId)) as TencentAccess;
const client = this.getClient(accessProvider, this.region);
async onInstance() {
this.client = await this.getClient();
}
async getClient() {
const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/clb/index.js');
const ClbClient = sdk.clb.v20180317.Client;
const accessProvider = (await this.accessService.getById(this.accessId)) as TencentAccess;
const region = this.region;
const clientConfig = {
credential: {
secretId: accessProvider.secretId,
secretKey: accessProvider.secretKey,
},
region: region,
profile: {
httpProfile: {
endpoint: 'clb.tencentcloudapi.com',
},
},
};
return new ClbClient(clientConfig);
}
async execute(): Promise<void> {
const client = this.client;
const lastCertId = await this.getCertIdFromProps(client); const lastCertId = await this.getCertIdFromProps(client);
if (!this.domain) { if (!this.domain) {
await this.updateListener(client); await this.updateListener(client);
@ -213,25 +238,6 @@ export class DeployToClbPlugin extends AbstractTaskPlugin {
return ret.Listeners; return ret.Listeners;
} }
getClient(accessProvider: TencentAccess, region: string) {
const ClbClient = tencentcloud.clb.v20180317.Client;
const clientConfig = {
credential: {
secretId: accessProvider.secretId,
secretKey: accessProvider.secretKey,
},
region: region,
profile: {
httpProfile: {
endpoint: 'clb.tencentcloudapi.com',
},
},
};
return new ClbClient(clientConfig);
}
checkRet(ret: any) { checkRet(ret: any) {
if (!ret || ret.Error) { if (!ret || ret.Error) {
throw new Error('执行失败:' + ret.Error.Code + ',' + ret.Error.Message); throw new Error('执行失败:' + ret.Error.Code + ',' + ret.Error.Message);

View File

@ -1,5 +1,4 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline'; import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from '@certd/pipeline';
import tencentcloud from 'tencentcloud-sdk-nodejs-teo';
import { TencentAccess } from '../../access/index.js'; import { TencentAccess } from '../../access/index.js';
@IsTaskPlugin({ @IsTaskPlugin({
@ -71,8 +70,12 @@ export class DeployToEOPlugin extends AbstractTaskPlugin {
// required: true, // required: true,
// }) // })
// endpoint!: string; // endpoint!: string;
Client: any;
async onInstance() {} async onInstance() {
const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/teo/v20220901/index.js');
this.Client = sdk.v20220901.Client;
}
async execute(): Promise<void> { async execute(): Promise<void> {
const accessProvider: TencentAccess = (await this.accessService.getById(this.accessId)) as TencentAccess; const accessProvider: TencentAccess = (await this.accessService.getById(this.accessId)) as TencentAccess;
@ -82,7 +85,7 @@ export class DeployToEOPlugin extends AbstractTaskPlugin {
} }
getClient(accessProvider: TencentAccess) { getClient(accessProvider: TencentAccess) {
const TeoClient = tencentcloud.teo.v20220901.Client; const TeoClient = this.Client;
const clientConfig = { const clientConfig = {
credential: { credential: {

View File

@ -1,6 +1,4 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, utils } from '@certd/pipeline'; import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, utils } from '@certd/pipeline';
import tencentcloud from 'tencentcloud-sdk-nodejs';
import { K8sClient } from '@certd/lib-k8s';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@IsTaskPlugin({ @IsTaskPlugin({
@ -90,14 +88,22 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
}) })
cert!: any; cert!: any;
async onInstance() {} sdk: any;
K8sClient: any;
async onInstance() {
// const TkeClient = this.tencentcloud.tke.v20180525.Client;
this.sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/tke/v20220501/index.js');
const k8sSdk = await import('@certd/lib-k8s');
this.K8sClient = k8sSdk.K8sClient;
}
async execute(): Promise<void> { async execute(): Promise<void> {
const accessProvider = await this.accessService.getById(this.accessId); const accessProvider = await this.accessService.getById(this.accessId);
const tkeClient = this.getTkeClient(accessProvider, this.region); const tkeClient = this.getTkeClient(accessProvider, this.region);
const kubeConfigStr = await this.getTkeKubeConfig(tkeClient, this.clusterId); const kubeConfigStr = await this.getTkeKubeConfig(tkeClient, this.clusterId);
this.logger.info('kubeconfig已成功获取'); this.logger.info('kubeconfig已成功获取');
const k8sClient = new K8sClient({ const k8sClient = new this.K8sClient({
kubeConfigStr, kubeConfigStr,
logger: this.logger, logger: this.logger,
}); });
@ -120,7 +126,6 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
} }
getTkeClient(accessProvider: any, region = 'ap-guangzhou') { getTkeClient(accessProvider: any, region = 'ap-guangzhou') {
const TkeClient = tencentcloud.tke.v20180525.Client;
const clientConfig = { const clientConfig = {
credential: { credential: {
secretId: accessProvider.secretId, secretId: accessProvider.secretId,
@ -134,7 +139,7 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
}, },
}; };
return new TkeClient(clientConfig); return new this.sdk.Client(clientConfig);
} }
async getTkeKubeConfig(client: any, clusterId: string) { async getTkeKubeConfig(client: any, clusterId: string) {

View File

@ -1,5 +1,4 @@
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskOutput } from '@certd/pipeline'; import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput, TaskOutput } from '@certd/pipeline';
import tencentcloud from 'tencentcloud-sdk-nodejs';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@IsTaskPlugin({ @IsTaskPlugin({
@ -43,7 +42,11 @@ export class UploadToTencentPlugin extends AbstractTaskPlugin {
}) })
tencentCertId?: string; tencentCertId?: string;
async onInstance() {} Client: any;
async onInstance() {
const sdk = await import('tencentcloud-sdk-nodejs/tencentcloud/services/ssl/v20191205/index.js');
this.Client = sdk.v20191205.Client;
}
async execute(): Promise<void> { async execute(): Promise<void> {
const { accessId, name, cert } = this; const { accessId, name, cert } = this;
@ -71,7 +74,7 @@ export class UploadToTencentPlugin extends AbstractTaskPlugin {
} }
getClient(accessProvider: any) { getClient(accessProvider: any) {
const SslClient = tencentcloud.ssl.v20191205.Client; const SslClient = this.Client;
const clientConfig = { const clientConfig = {
credential: { credential: {

View File

@ -7,7 +7,7 @@ const specials = '~!@#$%^*()_+-=[]{}|;:,./<>?';
* @param {Number} length * @param {Number} length
* @param {Object} options * @param {Object} options
*/ */
function randomStr(length, options) { function randomStr(length, options?) {
length || (length = 8); length || (length = 8);
options || (options = {}); options || (options = {});
@ -28,8 +28,7 @@ function randomStr(length, options) {
} }
if (options.specials) { if (options.specials) {
chars += chars += typeof options.specials === 'string' ? options.specials : specials;
typeof options.specials === 'string' ? options.specials : specials;
} }
} }