From 2046b4bdfc4062978b3a79ab18ea9913cd436aab Mon Sep 17 00:00:00 2001 From: maslow Date: Tue, 21 Nov 2023 19:00:55 +0800 Subject: [PATCH] feat(server): support request-limit ratio conf of runtime resource in region (#1702) --- server/Dockerfile | 2 +- server/package.json | 1 + .../src/application/application.controller.ts | 4 +-- server/src/application/application.service.ts | 28 +++++++++++++++---- server/src/initializer/initializer.service.ts | 6 +++- server/src/region/entities/region.ts | 6 ++++ 6 files changed, 37 insertions(+), 10 deletions(-) diff --git a/server/Dockerfile b/server/Dockerfile index cec30346c9..1e4a848fd6 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-slim +FROM node:20-slim RUN apt-get update RUN apt-get install -y openssl wget libkrb5-dev diff --git a/server/package.json b/server/package.json index 28e2771be5..4e62acb657 100644 --- a/server/package.json +++ b/server/package.json @@ -11,6 +11,7 @@ "prebuild": "rimraf dist", "build": "nest build", "start": "nest start", + "dev": "nest start --watch --debug", "watch": "nest start --watch", "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", diff --git a/server/src/application/application.controller.ts b/server/src/application/application.controller.ts index 413b6687db..e044bc4daa 100644 --- a/server/src/application/application.controller.ts +++ b/server/src/application/application.controller.ts @@ -104,7 +104,7 @@ export class ApplicationController { return ResponseUtil.error(`runtime ${dto.runtimeId} not found`) } - const regionId = new ObjectId(dto.regionId) + const regionId = region._id // check if trial tier const isTrialTier = await this.resource.isTrialBundle(dto) @@ -143,7 +143,7 @@ export class ApplicationController { // create application const appid = await this.application.tryGenerateUniqueAppid() - await this.application.create(user._id, appid, dto, isTrialTier) + await this.application.create(regionId, user._id, appid, dto, isTrialTier) const app = await this.application.findOne(appid) return ResponseUtil.ok(app) diff --git a/server/src/application/application.service.ts b/server/src/application/application.service.ts index ff3a38e6b8..8f46bb0435 100644 --- a/server/src/application/application.service.ts +++ b/server/src/application/application.service.ts @@ -23,12 +23,18 @@ import { } from './entities/application-bundle' import { GroupService } from 'src/group/group.service' import { GroupMember } from 'src/group/entities/group-member' +import { RegionService } from 'src/region/region.service' +import { assert } from 'console' +import { Region } from 'src/region/entities/region' @Injectable() export class ApplicationService { private readonly logger = new Logger(ApplicationService.name) - constructor(private readonly groupService: GroupService) {} + constructor( + private readonly groupService: GroupService, + readonly regionService: RegionService, + ) {} /** * Create application @@ -37,6 +43,7 @@ export class ApplicationService { * - create application */ async create( + regionId: ObjectId, userid: ObjectId, appid: string, dto: CreateApplicationDto, @@ -45,6 +52,8 @@ export class ApplicationService { const client = SystemDatabase.client const db = client.db() const session = client.startSession() + const region = await this.regionService.findOne(regionId) + assert(region, 'region cannot be empty') try { // start transaction @@ -72,7 +81,7 @@ export class ApplicationService { await db.collection('ApplicationBundle').insertOne( { appid, - resource: this.buildBundleResource(dto), + resource: this.buildBundleResource(region, dto), autoscaling: this.buildAutoscalingConfig(dto), isTrialTier: isTrialTier, createdAt: new Date(), @@ -323,7 +332,10 @@ export class ApplicationService { isTrialTier: boolean, ) { const db = SystemDatabase.db - const resource = this.buildBundleResource(dto) + const region = await this.regionService.findByAppId(appid) + assert(region, 'region cannot be empty') + + const resource = this.buildBundleResource(region, dto) const autoscaling = this.buildAutoscalingConfig(dto) const res = await db @@ -386,9 +398,13 @@ export class ApplicationService { return prefix + nano() } - private buildBundleResource(dto: UpdateApplicationBundleDto) { - const requestCPU = Math.floor(dto.cpu * 0.4) - const requestMemory = Math.floor(dto.memory * 0.4) + private buildBundleResource(region: Region, dto: UpdateApplicationBundleDto) { + const bundleConf = region.bundleConf + const cpuRatio = bundleConf?.cpuRequestLimitRatio || 0.1 + const memoryRatio = bundleConf?.memoryRequestLimitRatio || 0.5 + + const requestCPU = Math.floor(dto.cpu * cpuRatio) + const requestMemory = Math.floor(dto.memory * memoryRatio) const limitCountOfCloudFunction = Math.floor(dto.cpu * 1) const magicNumber = Math.floor(dto.cpu * 0.03) diff --git a/server/src/initializer/initializer.service.ts b/server/src/initializer/initializer.service.ts index 28e8c1ba00..7bd0cb31bb 100644 --- a/server/src/initializer/initializer.service.ts +++ b/server/src/initializer/initializer.service.ts @@ -56,6 +56,10 @@ export class InitializerService { npmInstallFlags: '', runtimeAffinity: {}, }, + bundleConf: { + cpuRequestLimitRatio: 0.1, + memoryRequestLimitRatio: 0.5, + }, databaseConf: { driver: 'mongodb', connectionUri: ServerConfig.DEFAULT_REGION_DATABASE_URL, @@ -284,7 +288,7 @@ export class InitializerService { [ResourceType.StorageCapacity]: { value: 1024 }, [ResourceType.NetworkTraffic]: { value: 0 }, }, - enableFreeTier: true, + enableFreeTier: false, limitCountOfFreeTierPerUser: 20, createdAt: new Date(), updatedAt: new Date(), diff --git a/server/src/region/entities/region.ts b/server/src/region/entities/region.ts index 365d7511ca..231fda532f 100644 --- a/server/src/region/entities/region.ts +++ b/server/src/region/entities/region.ts @@ -19,6 +19,11 @@ export type RegionClusterConf = { runtimeAffinity: any } +export type RegionResourceBundleConf = { + cpuRequestLimitRatio: number + memoryRequestLimitRatio: number +} + export type RegionDatabaseConf = { driver: string connectionUri: string @@ -74,6 +79,7 @@ export class Region { namespaceConf: RegionNamespaceConf clusterConf: RegionClusterConf + bundleConf: RegionResourceBundleConf databaseConf: RegionDatabaseConf gatewayConf: RegionGatewayConf storageConf: RegionStorageConf