You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ti...@apache.org on 2021/12/20 07:03:35 UTC

[servicecomb-service-center] branch master updated: Refactor quota mgr (#1181)

This is an automated email from the ASF dual-hosted git repository.

tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-service-center.git


The following commit(s) were added to refs/heads/master by this push:
     new 52e5386  Refactor quota mgr (#1181)
52e5386 is described below

commit 52e53869eb0f20fdaab86c017a34aadb23f75dce
Author: little-cui <su...@qq.com>
AuthorDate: Mon Dec 20 15:03:31 2021 +0800

    Refactor quota mgr (#1181)
    
    * Refactor quota mgr
    
    * Add UTs
---
 datasource/engine.go                               |   3 -
 datasource/engine_test.go                          |  30 -----
 datasource/etcd/engine.go                          |  96 ----------------
 datasource/etcd/etcd_suite_test.go                 |  10 --
 datasource/etcd/event/instance_event_handler.go    |   4 +-
 datasource/etcd/ms.go                              |  28 +----
 datasource/etcd/util/microservice_util.go          |   9 --
 datasource/etcd/util/util_test.go                  |   5 -
 datasource/mongo/engine.go                         | 120 --------------------
 datasource/mongo/mongo_test.go                     |  11 --
 datasource/mongo/ms.go                             |  25 +----
 datasource/ms.go                                   |   2 -
 datasource/schema_test.go                          |   7 +-
 datasource/service_test.go                         |   4 +-
 datasource/tag_test.go                             |   4 +-
 server/metrics/meta_reporter.go                    |   6 +-
 server/metrics/meta_reporter_test.go               |  24 ++--
 .../plugin/quota/buildin/account.go                |  19 ++--
 server/plugin/quota/buildin/buildin.go             |  89 +++++++++++----
 server/plugin/quota/buildin/buildin_test.go        |  85 --------------
 .../plugin/quota/buildin/instance.go               |  20 ++--
 .../quota/buildin/instance_test.go}                |  55 ++-------
 .../plugin/quota/buildin/role.go                   |  19 ++--
 .../quota.go => plugin/quota/buildin/schema.go}    |  34 +-----
 .../plugin/quota/buildin/service.go                |  20 ++--
 server/plugin/quota/buildin/service_test.go        |  60 ++++++++++
 server/plugin/quota/quota.go                       | 125 +++------------------
 .../engine.go => server/plugin/quota/request.go    |  23 ++--
 server/service/disco/instance.go                   |  11 +-
 server/service/disco/microservice.go               |  11 +-
 server/service/disco/microservice_test.go          |   4 +-
 server/service/disco/schema.go                     |   5 +-
 server/service/disco/schema_test.go                |   9 +-
 server/service/disco/tag_test.go                   |  24 ++--
 .../engine.go => server/service/quota/account.go   |  23 ++--
 .../service/quota/instance.go                      |  30 ++---
 server/service/quota/instance_test.go              |  71 ++++++++++++
 .../engine.go => server/service/quota/role.go      |  23 ++--
 .../service/quota/schema.go                        |  27 +++--
 .../service/quota/service.go                       |  30 ++---
 .../service/quota/service_test.go                  |  25 +++--
 .../engine.go => server/service/quota/tag.go       |  17 +--
 server/service/rbac/account_service.go             |   6 +-
 server/service/rbac/role_service.go                |   6 +-
 server/service/validator/microservice_validator.go |   6 +-
 server/service/validator/schema_validator.go       |   6 +-
 server/service/validator/tag_validator.go          |   8 +-
 test/test.go                                       |   2 +-
 48 files changed, 438 insertions(+), 843 deletions(-)

diff --git a/datasource/engine.go b/datasource/engine.go
index 667d0db..d2c3265 100644
--- a/datasource/engine.go
+++ b/datasource/engine.go
@@ -19,7 +19,6 @@ package datasource
 
 import (
 	"context"
-	"time"
 
 	"github.com/little-cui/etcdadpt"
 )
@@ -28,8 +27,6 @@ import (
 type SCManager interface {
 	SelfRegister(ctx context.Context) error
 	SelfUnregister(ctx context.Context) error
-	// OPS
-	ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error
 	UpgradeVersion(ctx context.Context) error
 	GetClusters(ctx context.Context) (etcdadpt.Clusters, error)
 }
diff --git a/datasource/engine_test.go b/datasource/engine_test.go
index 5a828bd..cc3a048 100644
--- a/datasource/engine_test.go
+++ b/datasource/engine_test.go
@@ -20,11 +20,9 @@ package datasource_test
 import (
 	"context"
 	"fmt"
-	"time"
 
 	"github.com/apache/servicecomb-service-center/datasource/etcd/path"
 
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	apt "github.com/apache/servicecomb-service-center/server/core"
 	pb "github.com/go-chassis/cari/discovery"
@@ -98,31 +96,3 @@ func checkServiceCleared(domain string, project string) {
 		Expect(getSvcResp.Response.GetCode() == pb.ResponseSuccess).To(Equal(!v.ShouldClear))
 	}
 }
-
-func serviceClearCheckFunc(domain string, project string) func() {
-	return func() {
-		var err error
-		It("should run clear task success", func() {
-			withInstance := true
-			withNoInstance := false
-			shouldClear := true
-			shouldNotClear := false
-
-			createService(domain, project, "svc1", withNoInstance, shouldClear)
-			createService(domain, project, "svc2", withInstance, shouldNotClear)
-			time.Sleep(2 * time.Second)
-			createService(domain, project, "svc3", withNoInstance, shouldNotClear)
-			createService(domain, project, "svc4", withInstance, shouldNotClear)
-
-			err = datasource.GetSCManager().ClearNoInstanceServices(context.Background(), 2*time.Second)
-			Expect(err).To(BeNil())
-
-			checkServiceCleared(domain, project)
-		})
-	}
-}
-
-var _ = Describe("clear service", func() {
-	Describe("domain project 1", serviceClearCheckFunc("default1", "default"))
-	Describe("domain project 2", serviceClearCheckFunc("default2", "default"))
-})
diff --git a/datasource/etcd/engine.go b/datasource/etcd/engine.go
index 0ddb226..3666aa3 100644
--- a/datasource/etcd/engine.go
+++ b/datasource/etcd/engine.go
@@ -23,16 +23,12 @@ import (
 	"errors"
 	"fmt"
 	"os"
-	"strconv"
-	"strings"
 	"time"
 
 	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/etcd/mux"
 	"github.com/apache/servicecomb-service-center/datasource/etcd/path"
-	serviceUtil "github.com/apache/servicecomb-service-center/datasource/etcd/util"
 	"github.com/apache/servicecomb-service-center/pkg/log"
-	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/config"
 	"github.com/apache/servicecomb-service-center/server/core"
 	discosvc "github.com/apache/servicecomb-service-center/server/service/disco"
@@ -176,98 +172,6 @@ func (sm *SCManager) SelfUnregister(pCtx context.Context) error {
 	return nil
 }
 
-// ClearNoInstanceService clears services which have no instance
-func (sm *SCManager) ClearNoInstanceServices(ctx context.Context, serviceTTL time.Duration) error {
-	services, err := serviceUtil.GetAllServicesAcrossDomainProject(ctx)
-	if err != nil {
-		return err
-	}
-	if len(services) == 0 {
-		log.Info("no service found, no need to clear")
-		return nil
-	}
-	timeLimit := time.Now().Add(0 - serviceTTL)
-	log.Info(fmt.Sprintf("clear no-instance services created before %s", timeLimit))
-	timeLimitStamp := strconv.FormatInt(timeLimit.Unix(), 10)
-
-	for domainProject, svcList := range services {
-		if len(svcList) == 0 {
-			continue
-		}
-		ctx, err := ctxFromDomainProject(ctx, domainProject)
-		if err != nil {
-			log.Error("get domain project context failed", err)
-			continue
-		}
-		for _, svc := range svcList {
-			if svc == nil {
-				continue
-			}
-			ok, err := shouldClear(ctx, timeLimitStamp, svc)
-			if err != nil {
-				log.Error("check service clear necessity failed", err)
-				continue
-			}
-			if !ok {
-				continue
-			}
-			//delete this service
-			svcCtxStr := "domainProject: " + domainProject + ", " +
-				"env: " + svc.Environment + ", " +
-				"service: " + util.StringJoin([]string{svc.AppId, svc.ServiceName, svc.Version}, path.SPLIT)
-			delSvcReq := &pb.DeleteServiceRequest{
-				ServiceId: svc.ServiceId,
-				Force:     true, //force delete
-			}
-			delSvcResp, err := core.ServiceAPI.Delete(ctx, delSvcReq)
-			if err != nil {
-				log.Error(fmt.Sprintf("clear service failed, %s", svcCtxStr), err)
-				continue
-			}
-			if delSvcResp.Response.GetCode() != pb.ResponseSuccess {
-				log.Error(fmt.Sprintf("clear service failed, %s, %s", delSvcResp.Response.GetMessage(), svcCtxStr), err)
-				continue
-			}
-			log.Warn(fmt.Sprintf("clear service success, %s", svcCtxStr))
-		}
-	}
-	return nil
-}
-
-func ctxFromDomainProject(pCtx context.Context, domainProject string) (ctx context.Context, err error) {
-	splitIndex := strings.Index(domainProject, path.SPLIT)
-	if splitIndex == -1 {
-		return nil, errors.New("invalid domainProject: " + domainProject)
-	}
-	domain := domainProject[:splitIndex]
-	project := domainProject[splitIndex+1:]
-	return util.SetDomainProject(pCtx, domain, project), nil
-}
-
-//check whether a service should be cleared
-func shouldClear(ctx context.Context, timeLimitStamp string, svc *pb.MicroService) (bool, error) {
-	//ignore a service if it is created after timeLimitStamp
-	if svc.Timestamp > timeLimitStamp {
-		return false, nil
-	}
-	getInstsReq := &pb.GetInstancesRequest{
-		ConsumerServiceId: svc.ServiceId,
-		ProviderServiceId: svc.ServiceId,
-	}
-	getInstsResp, err := discosvc.GetInstances(ctx, getInstsReq)
-	if err != nil {
-		return false, err
-	}
-	if getInstsResp.Response.GetCode() != pb.ResponseSuccess {
-		return false, errors.New("get instance failed: " + getInstsResp.Response.GetMessage())
-	}
-	//ignore a service if it has instances
-	if len(getInstsResp.Instances) > 0 {
-		return false, nil
-	}
-	return true, nil
-}
-
 func (sm *SCManager) GetClusters(ctx context.Context) (etcdadpt.Clusters, error) {
 	return etcdadpt.ListCluster(ctx)
 }
diff --git a/datasource/etcd/etcd_suite_test.go b/datasource/etcd/etcd_suite_test.go
index 02a0304..c6dddb3 100644
--- a/datasource/etcd/etcd_suite_test.go
+++ b/datasource/etcd/etcd_suite_test.go
@@ -20,25 +20,15 @@ package etcd_test
 import (
 	"context"
 	"testing"
-	"time"
 
 	_ "github.com/apache/servicecomb-service-center/test"
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
 
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/onsi/ginkgo/reporters"
 )
 
-var timeLimit = 2 * time.Second
-
-var _ = BeforeSuite(func() {
-	//clear service created in last test
-	time.Sleep(timeLimit)
-	_ = datasource.GetSCManager().ClearNoInstanceServices(context.Background(), timeLimit)
-})
-
 func TestEtcd(t *testing.T) {
 	RegisterFailHandler(Fail)
 	junitReporter := reporters.NewJUnitReporter("etcd.junit.xml")
diff --git a/datasource/etcd/event/instance_event_handler.go b/datasource/etcd/event/instance_event_handler.go
index 8310910..5e35643 100644
--- a/datasource/etcd/event/instance_event_handler.go
+++ b/datasource/etcd/event/instance_event_handler.go
@@ -31,6 +31,7 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/event"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	"github.com/apache/servicecomb-service-center/server/syncernotify"
 	pb "github.com/go-chassis/cari/discovery"
 )
@@ -68,8 +69,7 @@ func (h *InstanceEventHandler) OnEvent(evt kvstore.Event) {
 
 	if action == pb.EVT_DELETE && !datasource.IsDefaultDomainProject(domainProject) {
 		domain, project := path.SplitDomainProject(domainProject)
-		serviceUtil.RemandInstanceQuota(
-			util.SetDomainProject(context.Background(), domain, project))
+		quotasvc.RemandInstance(util.SetDomainProject(context.Background(), domain, project))
 	}
 
 	// 查询服务版本信息
diff --git a/datasource/etcd/ms.go b/datasource/etcd/ms.go
index d0b129f..6d5483b 100644
--- a/datasource/etcd/ms.go
+++ b/datasource/etcd/ms.go
@@ -34,8 +34,8 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/core"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 	"github.com/apache/servicecomb-service-center/server/plugin/uuid"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	pb "github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/cari/pkg/errsvc"
 	"github.com/go-chassis/foundation/gopool"
@@ -1759,8 +1759,7 @@ func (ds *MetadataManager) modifySchemas(ctx context.Context, domainProject stri
 	pluginOps := make([]etcdadpt.OpOptions, 0)
 	if !ds.isSchemaEditable() {
 		if len(service.Schemas) == 0 {
-			res := quota.NewApplyQuotaResource(quota.TypeSchema, domainProject, serviceID, int64(len(nonExistSchemaIds)))
-			errQuota := quota.Apply(ctx, res)
+			errQuota := quotasvc.ApplySchema(ctx, serviceID, int64(len(nonExistSchemaIds)))
 			if errQuota != nil {
 				log.Error(fmt.Sprintf("modify service[%s] schemas failed, operator: %s", serviceID, remoteIP), errQuota)
 				return errQuota
@@ -1803,8 +1802,7 @@ func (ds *MetadataManager) modifySchemas(ctx context.Context, domainProject stri
 	} else {
 		quotaSize := len(needAddSchemas) - len(needDeleteSchemas)
 		if quotaSize > 0 {
-			res := quota.NewApplyQuotaResource(quota.TypeSchema, domainProject, serviceID, int64(quotaSize))
-			errQuota := quota.Apply(ctx, res)
+			errQuota := quotasvc.ApplySchema(ctx, serviceID, int64(quotaSize))
 			if errQuota != nil {
 				log.Error(fmt.Sprintf("modify service[%s] schemas failed, operator: %s", serviceID, remoteIP), errQuota)
 				return errQuota
@@ -2073,26 +2071,8 @@ func (ds *MetadataManager) DeleteServicePri(ctx context.Context, serviceID strin
 		return pb.CreateResponse(pb.ErrServiceNotExists, "Service does not exist."), nil
 	}
 
-	serviceUtil.RemandServiceQuota(ctx)
+	quotasvc.RemandService(ctx)
 
 	log.Info(fmt.Sprintf("%s micro-service[%s] successfully, operator: %s", title, serviceID, remoteIP))
 	return pb.CreateResponse(pb.ResponseSuccess, "Unregister service successfully."), nil
 }
-
-func (ds *MetadataManager) GetDeleteServiceFunc(ctx context.Context, serviceID string, force bool,
-	serviceRespChan chan<- *pb.DelServicesRspInfo) func(context.Context) {
-	return func(_ context.Context) {
-		serviceRst := &pb.DelServicesRspInfo{
-			ServiceId:  serviceID,
-			ErrMessage: "",
-		}
-		resp, err := ds.DeleteServicePri(ctx, serviceID, force)
-		if err != nil {
-			serviceRst.ErrMessage = err.Error()
-		} else if resp.GetCode() != pb.ResponseSuccess {
-			serviceRst.ErrMessage = resp.GetMessage()
-		}
-
-		serviceRespChan <- serviceRst
-	}
-}
diff --git a/datasource/etcd/util/microservice_util.go b/datasource/etcd/util/microservice_util.go
index 6ae8d11..997a6f5 100644
--- a/datasource/etcd/util/microservice_util.go
+++ b/datasource/etcd/util/microservice_util.go
@@ -30,7 +30,6 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/config"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 	pb "github.com/go-chassis/cari/discovery"
 	"github.com/little-cui/etcdadpt"
 )
@@ -238,14 +237,6 @@ func GetAllServiceUtil(ctx context.Context) ([]*pb.MicroService, error) {
 	return services, nil
 }
 
-func RemandServiceQuota(ctx context.Context) {
-	quota.Remand(ctx, quota.TypeService)
-}
-
-func RemandInstanceQuota(ctx context.Context) {
-	quota.Remand(ctx, quota.TypeInstance)
-}
-
 func UpdateService(domainProject string, serviceID string, service *pb.MicroService) (opt etcdadpt.OpOptions, err error) {
 	opt = etcdadpt.OpOptions{}
 	key := path.GenerateServiceKey(domainProject, serviceID)
diff --git a/datasource/etcd/util/util_test.go b/datasource/etcd/util/util_test.go
index 50c0eb0..84a8e38 100644
--- a/datasource/etcd/util/util_test.go
+++ b/datasource/etcd/util/util_test.go
@@ -169,8 +169,3 @@ func TestFromContext(t *testing.T) {
 		t.Fatalf("TestFromContext failed")
 	}
 }
-
-func TestRemandQuota(t *testing.T) {
-	serviceUtil.RemandServiceQuota(context.Background())
-	serviceUtil.RemandInstanceQuota(context.Background())
-}
diff --git a/datasource/mongo/engine.go b/datasource/mongo/engine.go
index 900bec0..a5eb730 100644
--- a/datasource/mongo/engine.go
+++ b/datasource/mongo/engine.go
@@ -20,17 +20,11 @@ package mongo
 import (
 	"context"
 	"fmt"
-	"strconv"
-	"strings"
 	"time"
 
 	"github.com/apache/servicecomb-service-center/datasource"
-	"github.com/apache/servicecomb-service-center/datasource/etcd/path"
-	"github.com/apache/servicecomb-service-center/datasource/mongo/client"
-	"github.com/apache/servicecomb-service-center/datasource/mongo/client/model"
 	mutil "github.com/apache/servicecomb-service-center/datasource/mongo/util"
 	"github.com/apache/servicecomb-service-center/pkg/log"
-	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/core"
 	"github.com/apache/servicecomb-service-center/server/metrics"
 	discosvc "github.com/apache/servicecomb-service-center/server/service/disco"
@@ -79,64 +73,6 @@ func (ds *SCManager) SelfUnregister(ctx context.Context) error {
 	return nil
 }
 
-// OPS
-func (ds *SCManager) ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error {
-	services, err := GetAllServicesAcrossDomainProject(ctx)
-	if err != nil {
-		return err
-	}
-	if len(services) == 0 {
-		log.Info("no service found, no need to clear")
-		return nil
-	}
-
-	timeLimit := time.Now().Add(0 - ttl)
-	log.Info(fmt.Sprintf("clear no-instance services created before %s", timeLimit))
-	timeLimitStamp := strconv.FormatInt(timeLimit.Unix(), 10)
-
-	for domainProject, svcList := range services {
-		if len(svcList) == 0 {
-			continue
-		}
-		ctx, err := ctxFromDomainProject(ctx, domainProject)
-		if err != nil {
-			log.Error("get domain project context failed", err)
-			continue
-		}
-		for _, svc := range svcList {
-			if svc == nil {
-				continue
-			}
-			ok, err := shouldClear(ctx, timeLimitStamp, svc)
-			if err != nil {
-				log.Error("check service clear necessity failed", err)
-				continue
-			}
-			if !ok {
-				continue
-			}
-			svcCtxStr := "domainProject: " + domainProject + ", " +
-				"env: " + svc.Environment + ", " +
-				"service: " + util.StringJoin([]string{svc.AppId, svc.ServiceName, svc.Version}, path.SPLIT)
-			delSvcReq := &pb.DeleteServiceRequest{
-				ServiceId: svc.ServiceId,
-				Force:     true, //force delete
-			}
-			delSvcResp, err := datasource.GetMetadataManager().UnregisterService(ctx, delSvcReq)
-			if err != nil {
-				log.Error(fmt.Sprintf("clear service failed, %s", svcCtxStr), err)
-				continue
-			}
-			if delSvcResp.Response.GetCode() != pb.ResponseSuccess {
-				log.Error(fmt.Sprintf("clear service failed %s %s", delSvcResp.Response.GetMessage(), svcCtxStr), err)
-				continue
-			}
-			log.Warn(fmt.Sprintf("clear service success, %s", svcCtxStr))
-		}
-	}
-	return nil
-}
-
 func (ds *SCManager) UpgradeVersion(ctx context.Context) error {
 	return nil
 }
@@ -235,59 +171,3 @@ func (ds *SCManager) autoSelfHeartBeat() {
 		}
 	})
 }
-
-func GetAllServicesAcrossDomainProject(ctx context.Context) (map[string][]*pb.MicroService, error) {
-	filter := mutil.NewBasicFilter(ctx)
-
-	findRes, err := client.GetMongoClient().Find(ctx, model.CollectionService, filter)
-	if err != nil {
-		return nil, err
-	}
-
-	services := make(map[string][]*pb.MicroService)
-
-	for findRes.Next(ctx) {
-		var mongoService model.Service
-		err := findRes.Decode(&mongoService)
-		if err != nil {
-			return nil, err
-		}
-		domainProject := mongoService.Domain + "/" + mongoService.Project
-		services[domainProject] = append(services[domainProject], mongoService.Service)
-	}
-	return services, nil
-}
-
-func ctxFromDomainProject(pCtx context.Context, domainProject string) (ctx context.Context, err error) {
-	splitIndex := strings.Index(domainProject, path.SPLIT)
-	if splitIndex == -1 {
-		return nil, mutil.NewError("invalid domainProject: ", domainProject)
-	}
-	domain := domainProject[:splitIndex]
-	project := domainProject[splitIndex+1:]
-	return util.SetDomainProject(pCtx, domain, project), nil
-}
-
-func shouldClear(ctx context.Context, timeLimitStamp string, svc *pb.MicroService) (bool, error) {
-	if svc.Timestamp > timeLimitStamp {
-		return false, nil
-	}
-
-	getInstsReq := &pb.GetInstancesRequest{
-		ConsumerServiceId: svc.ServiceId,
-		ProviderServiceId: svc.ServiceId,
-	}
-
-	getInstsResp, err := datasource.GetMetadataManager().GetInstances(ctx, getInstsReq)
-	if err != nil {
-		return false, err
-	}
-	if getInstsResp.Response.GetCode() != pb.ResponseSuccess {
-		return false, mutil.NewError("get instance failed: ", getInstsResp.Response.GetMessage())
-	}
-	//ignore a service if it has instances
-	if len(getInstsResp.Instances) > 0 {
-		return false, nil
-	}
-	return true, nil
-}
diff --git a/datasource/mongo/mongo_test.go b/datasource/mongo/mongo_test.go
index c573034..d11f6e9 100644
--- a/datasource/mongo/mongo_test.go
+++ b/datasource/mongo/mongo_test.go
@@ -20,23 +20,12 @@ package mongo_test
 // initialize
 import (
 	"context"
-	"testing"
-	"time"
 
 	_ "github.com/apache/servicecomb-service-center/test"
 
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 )
 
-var timeLimit = 2 * time.Second
-
 func getContext() context.Context {
 	return util.WithNoCache(util.SetDomainProject(context.Background(), "default", "default"))
 }
-
-func TestMongo(t *testing.T) {
-	//clear service created in last test
-	time.Sleep(timeLimit)
-	_ = datasource.GetSCManager().ClearNoInstanceServices(getContext(), timeLimit)
-}
diff --git a/datasource/mongo/ms.go b/datasource/mongo/ms.go
index d489327..c85620d 100644
--- a/datasource/mongo/ms.go
+++ b/datasource/mongo/ms.go
@@ -38,8 +38,8 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	apt "github.com/apache/servicecomb-service-center/server/core"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 	"github.com/apache/servicecomb-service-center/server/plugin/uuid"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	"github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/cari/pkg/errsvc"
 	"github.com/go-chassis/foundation/gopool"
@@ -378,23 +378,6 @@ func (ds *MetadataManager) UpdateService(ctx context.Context, request *discovery
 	}, nil
 }
 
-func (ds *MetadataManager) GetDeleteServiceFunc(ctx context.Context, serviceID string, force bool, serviceRespChan chan<- *discovery.DelServicesRspInfo) func(context.Context) {
-	return func(_ context.Context) {
-		serviceRst := &discovery.DelServicesRspInfo{
-			ServiceId:  serviceID,
-			ErrMessage: "",
-		}
-		resp, err := ds.DelServicePri(ctx, serviceID, force)
-		if err != nil {
-			serviceRst.ErrMessage = err.Error()
-		} else if resp.GetCode() != discovery.ResponseSuccess {
-			serviceRst.ErrMessage = resp.GetMessage()
-		}
-
-		serviceRespChan <- serviceRst
-	}
-}
-
 func (ds *MetadataManager) GetServiceDetail(ctx context.Context, request *discovery.GetServiceRequest) (
 	*discovery.ServiceDetail, error) {
 	mgSvc, err := GetServiceByID(ctx, request.ServiceId)
@@ -831,8 +814,7 @@ func (ds *MetadataManager) modifySchemas(ctx context.Context, service *discovery
 	var serviceOps []mongo.WriteModel
 	if !ds.isSchemaEditable() {
 		if len(service.Schemas) == 0 {
-			res := quota.NewApplyQuotaResource(quota.TypeSchema, util.ParseDomainProject(ctx), serviceID, int64(len(nonExistSchemaIds)))
-			errQuota := quota.Apply(ctx, res)
+			errQuota := quotasvc.ApplySchema(ctx, serviceID, int64(len(nonExistSchemaIds)))
 			if errQuota != nil {
 				log.Error(fmt.Sprintf("modify service[%s] schemas failed, operator: %s", serviceID, remoteIP), errQuota)
 				return errQuota
@@ -883,8 +865,7 @@ func (ds *MetadataManager) modifySchemas(ctx context.Context, service *discovery
 	} else {
 		quotaSize := len(needAddSchemas) - len(needDeleteSchemas)
 		if quotaSize > 0 {
-			res := quota.NewApplyQuotaResource(quota.TypeSchema, util.ParseDomainProject(ctx), serviceID, int64(quotaSize))
-			errQuota := quota.Apply(ctx, res)
+			errQuota := quotasvc.ApplySchema(ctx, serviceID, int64(quotaSize))
 			if errQuota != nil {
 				log.Error(fmt.Sprintf("modify service[%s] schemas failed, operator: %s", serviceID, remoteIP), errQuota)
 				return errQuota
diff --git a/datasource/ms.go b/datasource/ms.go
index 0e1f481..1907939 100644
--- a/datasource/ms.go
+++ b/datasource/ms.go
@@ -55,8 +55,6 @@ type MetadataManager interface {
 	ExistService(ctx context.Context, request *pb.GetExistenceRequest) (*pb.GetExistenceResponse, error)
 	UpdateService(ctx context.Context, request *pb.UpdateServicePropsRequest) (*pb.UpdateServicePropsResponse, error)
 	UnregisterService(ctx context.Context, request *pb.DeleteServiceRequest) (*pb.DeleteServiceResponse, error)
-	GetDeleteServiceFunc(ctx context.Context, serviceID string, force bool,
-		serviceRespChan chan<- *pb.DelServicesRspInfo) func(context.Context)
 	GetServiceCount(ctx context.Context,
 		request *pb.GetServiceCountRequest) (*pb.GetServiceCountResponse, error)
 
diff --git a/datasource/schema_test.go b/datasource/schema_test.go
index 15a9d5c..088601c 100644
--- a/datasource/schema_test.go
+++ b/datasource/schema_test.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/servicecomb-service-center/datasource/etcd"
 	"github.com/apache/servicecomb-service-center/datasource/mongo"
 	"github.com/apache/servicecomb-service-center/pkg/log"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	pb "github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/cari/pkg/errsvc"
 	"github.com/go-chassis/go-archaius"
@@ -72,7 +72,8 @@ func TestSchema_Create(t *testing.T) {
 
 	t.Run("create schemas out of gauge", func(t *testing.T) {
 		log.Info("create schemas out of gauge")
-		size := quota.DefaultSchemaQuota + 1
+		max := int(quotasvc.SchemaQuota())
+		size := max + 1
 		schemaIds := make([]string, 0, size)
 		schemas := make([]*pb.Schema, 0, size)
 		for i := 0; i < size; i++ {
@@ -98,7 +99,7 @@ func TestSchema_Create(t *testing.T) {
 		log.Info("batch modify schemas 2")
 		resp, err = datasource.GetMetadataManager().ModifySchemas(getContext(), &pb.ModifySchemasRequest{
 			ServiceId: serviceIdDev,
-			Schemas:   schemas[:quota.DefaultSchemaQuota],
+			Schemas:   schemas[:max],
 		})
 		assert.NoError(t, err)
 		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
diff --git a/datasource/service_test.go b/datasource/service_test.go
index 99fa162..e3e78db 100644
--- a/datasource/service_test.go
+++ b/datasource/service_test.go
@@ -24,19 +24,19 @@ import (
 	"testing"
 	"time"
 
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	"github.com/go-chassis/cari/pkg/errsvc"
 
 	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 	pb "github.com/go-chassis/cari/discovery"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestService_Register(t *testing.T) {
 	t.Run("Register service after init & install, should pass", func(t *testing.T) {
-		size := quota.DefaultSchemaQuota + 1
+		size := int(quotasvc.SchemaQuota()) + 1
 		paths := make([]*pb.ServicePath, 0, size)
 		properties := make(map[string]string, size)
 		for i := 0; i < size; i++ {
diff --git a/datasource/tag_test.go b/datasource/tag_test.go
index a2b42c6..204c717 100644
--- a/datasource/tag_test.go
+++ b/datasource/tag_test.go
@@ -23,9 +23,9 @@ import (
 	"testing"
 
 	"github.com/apache/servicecomb-service-center/datasource"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 
 	"github.com/apache/servicecomb-service-center/pkg/log"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 	pb "github.com/go-chassis/cari/discovery"
 	"github.com/stretchr/testify/assert"
 )
@@ -66,7 +66,7 @@ func TestTags_Add(t *testing.T) {
 
 	t.Run("the request is valid", func(t *testing.T) {
 		log.Info("tag quota is equal to the default value and should be paas")
-		defaultQuota := quota.DefaultTagQuota
+		defaultQuota := int(quotasvc.TagQuota())
 		tags := make(map[string]string, defaultQuota)
 		for i := 0; i < defaultQuota; i++ {
 			s := "tag" + strconv.Itoa(i)
diff --git a/server/metrics/meta_reporter.go b/server/metrics/meta_reporter.go
index 97ef861..4463d10 100644
--- a/server/metrics/meta_reporter.go
+++ b/server/metrics/meta_reporter.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	metricsvc "github.com/apache/servicecomb-service-center/pkg/metrics"
 	promutil "github.com/apache/servicecomb-service-center/pkg/prometheus"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	"github.com/go-chassis/go-chassis/v2/pkg/metrics"
 )
 
@@ -61,7 +61,7 @@ func (m *MetaReporter) ServiceUsageSet() {
 		"instance": instance,
 	}
 	used := promutil.GaugeValue(KeyServiceTotal, labels)
-	total := float64(quota.DefaultServiceQuota)
+	total := float64(quotasvc.ServiceQuota())
 	if total <= 0 {
 		return
 	}
@@ -88,7 +88,7 @@ func (m *MetaReporter) InstanceUsageSet() {
 		"instance": instance,
 	}
 	used := promutil.GaugeValue(KeyInstanceTotal, labels)
-	total := float64(quota.DefaultInstanceQuota)
+	total := float64(quotasvc.InstanceQuota())
 	if total <= 0 {
 		return
 	}
diff --git a/server/metrics/meta_reporter_test.go b/server/metrics/meta_reporter_test.go
index 29639da..bdc5a9b 100644
--- a/server/metrics/meta_reporter_test.go
+++ b/server/metrics/meta_reporter_test.go
@@ -23,9 +23,11 @@ import (
 	_ "github.com/apache/servicecomb-service-center/test"
 
 	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/pkg/plugin"
 	promutil "github.com/apache/servicecomb-service-center/pkg/prometheus"
 	"github.com/apache/servicecomb-service-center/server/metrics"
 	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	"github.com/apache/servicecomb-service-center/server/plugin/quota/buildin"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -35,20 +37,21 @@ func TestMetaReporter_ServiceUsageSet(t *testing.T) {
 	reporter := metrics.MetaReporter{}
 	assert.Equal(t, float64(0), promutil.GaugeValue(metrics.KeyServiceUsage, labels))
 
-	old := quota.DefaultServiceQuota
-	quota.DefaultServiceQuota = 0
+	inst := plugin.Plugins().Instance(quota.QUOTA).(*buildin.Quota)
+	old := inst.ServiceQuota
+	inst.ServiceQuota = 0
 	reporter.ServiceUsageSet()
 	assert.Equal(t, float64(0), promutil.GaugeValue(metrics.KeyServiceUsage, labels))
-	quota.DefaultServiceQuota = old
+	inst.ServiceQuota = old
 
 	reporter.ServiceAdd(1, datasource.MetricsLabels{Domain: "D1", Project: "P1"})
 	reporter.ServiceUsageSet()
-	assert.Equal(t, 1/float64(quota.DefaultServiceQuota), promutil.GaugeValue(metrics.KeyServiceUsage, labels))
+	assert.Equal(t, 1/float64(inst.ServiceQuota), promutil.GaugeValue(metrics.KeyServiceUsage, labels))
 
 	reporter.ServiceAdd(1, datasource.MetricsLabels{Domain: "D1", Project: "P2"})
 	reporter.ServiceAdd(1, datasource.MetricsLabels{Domain: "D2", Project: "P3"})
 	reporter.ServiceUsageSet()
-	assert.Equal(t, 3/float64(quota.DefaultServiceQuota), promutil.GaugeValue(metrics.KeyServiceUsage, labels))
+	assert.Equal(t, 3/float64(inst.ServiceQuota), promutil.GaugeValue(metrics.KeyServiceUsage, labels))
 }
 
 func TestMetaReporter_InstanceUsageSet(t *testing.T) {
@@ -57,18 +60,19 @@ func TestMetaReporter_InstanceUsageSet(t *testing.T) {
 	reporter := metrics.MetaReporter{}
 	assert.Equal(t, float64(0), promutil.GaugeValue(metrics.KeyInstanceUsage, labels))
 
-	old := quota.DefaultInstanceQuota
-	quota.DefaultInstanceQuota = 0
+	inst := plugin.Plugins().Instance(quota.QUOTA).(*buildin.Quota)
+	old := inst.InstanceQuota
+	inst.InstanceQuota = 0
 	reporter.InstanceUsageSet()
 	assert.Equal(t, float64(0), promutil.GaugeValue(metrics.KeyInstanceUsage, labels))
-	quota.DefaultInstanceQuota = old
+	inst.InstanceQuota = old
 
 	reporter.InstanceAdd(1, datasource.MetricsLabels{Domain: "D1", Project: "P1"})
 	reporter.InstanceUsageSet()
-	assert.Equal(t, 1/float64(quota.DefaultInstanceQuota), promutil.GaugeValue(metrics.KeyInstanceUsage, labels))
+	assert.Equal(t, 1/float64(inst.InstanceQuota), promutil.GaugeValue(metrics.KeyInstanceUsage, labels))
 
 	reporter.InstanceAdd(1, datasource.MetricsLabels{Domain: "D1", Project: "P2"})
 	reporter.InstanceAdd(1, datasource.MetricsLabels{Domain: "D2", Project: "P3"})
 	reporter.InstanceUsageSet()
-	assert.Equal(t, 3/float64(quota.DefaultInstanceQuota), promutil.GaugeValue(metrics.KeyInstanceUsage, labels))
+	assert.Equal(t, 3/float64(inst.InstanceQuota), promutil.GaugeValue(metrics.KeyInstanceUsage, labels))
 }
diff --git a/datasource/engine.go b/server/plugin/quota/buildin/account.go
similarity index 66%
copy from datasource/engine.go
copy to server/plugin/quota/buildin/account.go
index 667d0db..3fa5f42 100644
--- a/datasource/engine.go
+++ b/server/plugin/quota/buildin/account.go
@@ -15,21 +15,18 @@
  * limitations under the License.
  */
 
-package datasource
+package buildin
 
 import (
 	"context"
-	"time"
 
-	"github.com/little-cui/etcdadpt"
+	"github.com/apache/servicecomb-service-center/datasource"
 )
 
-// SCManager contains the APIs of registration of SC itself
-type SCManager interface {
-	SelfRegister(ctx context.Context) error
-	SelfUnregister(ctx context.Context) error
-	// OPS
-	ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error
-	UpgradeVersion(ctx context.Context) error
-	GetClusters(ctx context.Context) (etcdadpt.Clusters, error)
+func AccountUsage(ctx context.Context) (int64, error) {
+	_, used, err := datasource.GetAccountManager().ListAccount(ctx)
+	if err != nil {
+		return 0, err
+	}
+	return used, nil
 }
diff --git a/server/plugin/quota/buildin/buildin.go b/server/plugin/quota/buildin/buildin.go
index 3a6b1c7..5068687 100644
--- a/server/plugin/quota/buildin/buildin.go
+++ b/server/plugin/quota/buildin/buildin.go
@@ -23,7 +23,20 @@ import (
 
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/plugin"
+	"github.com/apache/servicecomb-service-center/pkg/util"
+	"github.com/apache/servicecomb-service-center/server/config"
 	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
+	pb "github.com/go-chassis/cari/discovery"
+)
+
+const (
+	defaultServiceLimit  int64 = 50000
+	defaultInstanceLimit int64 = 150000
+	defaultSchemaLimit   int64 = 100
+	defaultTagLimit      int64 = 100
+	defaultAccountLimit  int64 = 1000
+	defaultRoleLimit     int64 = 100
 )
 
 func init() {
@@ -31,42 +44,80 @@ func init() {
 }
 
 func New() plugin.Instance {
-	quota.Init()
+	q := &Quota{
+		ServiceQuota:  config.GetInt64("quota.cap.service.limit", defaultServiceLimit, config.WithENV("QUOTA_SERVICE")),
+		InstanceQuota: config.GetInt64("quota.cap.instance.limit", defaultInstanceLimit, config.WithENV("QUOTA_INSTANCE")),
+		SchemaQuota:   config.GetInt64("quota.cap.schema.limit", defaultSchemaLimit, config.WithENV("QUOTA_SCHEMA")),
+		TagQuota:      config.GetInt64("quota.cap.tag.limit", defaultTagLimit, config.WithENV("QUOTA_TAG")),
+		AccountQuota:  config.GetInt64("quota.cap.account.limit", defaultAccountLimit, config.WithENV("QUOTA_ACCOUNT")),
+		RoleQuota:     config.GetInt64("quota.cap.role.limit", defaultRoleLimit, config.WithENV("QUOTA_ROLE")),
+	}
 	log.Info(fmt.Sprintf("quota init, service: %d, instance: %d, schema: %d/service, tag: %d/service"+
 		", account: %d, role: %d",
-		quota.DefaultServiceQuota, quota.DefaultInstanceQuota,
-		quota.DefaultSchemaQuota, quota.DefaultTagQuota,
-		quota.DefaultAccountQuota, quota.DefaultRoleQuota))
-	return &Quota{}
+		q.ServiceQuota, q.InstanceQuota, q.SchemaQuota, q.TagQuota,
+		q.AccountQuota, q.RoleQuota))
+	return q
 }
 
 type Quota struct {
+	ServiceQuota  int64
+	InstanceQuota int64
+	SchemaQuota   int64
+	TagQuota      int64
+	AccountQuota  int64
+	RoleQuota     int64
 }
 
 func (q *Quota) GetQuota(ctx context.Context, t quota.ResourceType) int64 {
 	switch t {
-	case quota.TypeInstance:
-		return int64(quota.DefaultInstanceQuota)
-	case quota.TypeService:
-		return int64(quota.DefaultServiceQuota)
-	case quota.TypeSchema:
-		return int64(quota.DefaultSchemaQuota)
-	case quota.TypeTag:
-		return int64(quota.DefaultTagQuota)
-	case quota.TypeAccount:
-		return int64(quota.DefaultAccountQuota)
-	case quota.TypeRole:
-		return int64(quota.DefaultRoleQuota)
+	case quotasvc.TypeInstance:
+		return q.InstanceQuota
+	case quotasvc.TypeService:
+		return q.ServiceQuota
+	case quotasvc.TypeSchema:
+		return q.SchemaQuota
+	case quotasvc.TypeTag:
+		return q.TagQuota
+	case quotasvc.TypeAccount:
+		return q.AccountQuota
+	case quotasvc.TypeRole:
+		return q.RoleQuota
 	default:
 		return 0
 	}
 }
 
 //向配额中心上报配额使用量
-func (q *Quota) RemandQuotas(ctx context.Context, quotaType quota.ResourceType) {
+func (q *Quota) RemandQuotas(ctx context.Context, resourceType quota.ResourceType) {
 	df, ok := plugin.DynamicPluginFunc(quota.QUOTA, "RemandQuotas").(func(context.Context, quota.ResourceType))
 	if ok {
-		df(ctx, quotaType)
+		df(ctx, resourceType)
 		return
 	}
 }
+
+func (q *Quota) Usage(ctx context.Context, req *quota.Request) (int64, error) {
+	switch req.QuotaType {
+	case quotasvc.TypeInstance:
+		return InstanceUsage(ctx, &pb.GetServiceCountRequest{
+			Domain:  util.ParseDomain(ctx),
+			Project: util.ParseProject(ctx),
+		})
+	case quotasvc.TypeService:
+		return ServiceUsage(ctx, &pb.GetServiceCountRequest{
+			Domain:  util.ParseDomain(ctx),
+			Project: util.ParseProject(ctx),
+		})
+	case quotasvc.TypeSchema:
+		return SchemaUsage(ctx, req.ServiceID)
+	case quotasvc.TypeTag:
+		// always re-create the service old tags
+		return 0, nil
+	case quotasvc.TypeAccount:
+		return AccountUsage(ctx)
+	case quotasvc.TypeRole:
+		return RoleUsage(ctx)
+	default:
+		return 0, nil
+	}
+}
diff --git a/server/plugin/quota/buildin/buildin_test.go b/server/plugin/quota/buildin/buildin_test.go
deleted file mode 100644
index f8c2936..0000000
--- a/server/plugin/quota/buildin/buildin_test.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one or more
-// contributor license agreements.  See the NOTICE file distributed with
-// this work for additional information regarding copyright ownership.
-// The ASF licenses this file to You under the Apache License, Version 2.0
-// (the "License"); you may not use this file except in compliance with
-// the License.  You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package buildin_test
-
-import (
-	"context"
-	"testing"
-
-	_ "github.com/apache/servicecomb-service-center/server/init"
-
-	_ "github.com/apache/servicecomb-service-center/server/bootstrap"
-
-	"github.com/apache/servicecomb-service-center/datasource"
-	"github.com/apache/servicecomb-service-center/pkg/util"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
-	discosvc "github.com/apache/servicecomb-service-center/server/service/disco"
-	pb "github.com/go-chassis/cari/discovery"
-	"github.com/go-chassis/go-archaius"
-	"github.com/little-cui/etcdadpt"
-	"github.com/stretchr/testify/assert"
-)
-
-func init() {
-	archaius.Set("registry.cache.mode", 0)
-	archaius.Set("discovery.kind", "etcd")
-	archaius.Set("registry.kind", "etcd")
-	err := datasource.Init(datasource.Options{Config: etcdadpt.Config{Kind: "etcd"}})
-	if err != nil {
-		panic(err)
-	}
-}
-func TestGetResourceLimit(t *testing.T) {
-	//var id string
-	ctx := context.TODO()
-	ctx = util.SetDomainProject(ctx, "quota", "quota")
-	t.Run("create service,should success", func(t *testing.T) {
-		res := quota.NewApplyQuotaResource(quota.TypeService, "quota/quota", "", 1)
-		err := quota.Apply(ctx, res)
-		assert.Nil(t, err)
-	})
-	t.Run("create 1 instance,should success", func(t *testing.T) {
-		resp, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{
-			Service: &pb.MicroService{
-				ServiceName: "quota",
-			},
-		})
-		assert.NoError(t, err)
-		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
-
-		res := quota.NewApplyQuotaResource(quota.TypeInstance, "quota/quota", resp.ServiceId, 1)
-		err = quota.Apply(ctx, res)
-		assert.Nil(t, err)
-
-		res = quota.NewApplyQuotaResource(quota.TypeInstance, "quota/quota", resp.ServiceId, 150001)
-		err = quota.Apply(ctx, res)
-		assert.NotNil(t, err)
-	})
-	t.Run("create 150001 instance,should failed", func(t *testing.T) {
-		resp, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{
-			Service: &pb.MicroService{
-				ServiceName: "quota2",
-			},
-		})
-		assert.NoError(t, err)
-		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
-
-		res := quota.NewApplyQuotaResource(quota.TypeInstance, "quota/quota", resp.ServiceId, 150001)
-		err = quota.Apply(ctx, res)
-		assert.NotNil(t, err)
-	})
-
-}
diff --git a/datasource/engine.go b/server/plugin/quota/buildin/instance.go
similarity index 66%
copy from datasource/engine.go
copy to server/plugin/quota/buildin/instance.go
index 667d0db..674310a 100644
--- a/datasource/engine.go
+++ b/server/plugin/quota/buildin/instance.go
@@ -15,21 +15,19 @@
  * limitations under the License.
  */
 
-package datasource
+package buildin
 
 import (
 	"context"
-	"time"
 
-	"github.com/little-cui/etcdadpt"
+	"github.com/apache/servicecomb-service-center/datasource"
+	pb "github.com/go-chassis/cari/discovery"
 )
 
-// SCManager contains the APIs of registration of SC itself
-type SCManager interface {
-	SelfRegister(ctx context.Context) error
-	SelfUnregister(ctx context.Context) error
-	// OPS
-	ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error
-	UpgradeVersion(ctx context.Context) error
-	GetClusters(ctx context.Context) (etcdadpt.Clusters, error)
+func InstanceUsage(ctx context.Context, request *pb.GetServiceCountRequest) (int64, error) {
+	resp, err := datasource.GetMetadataManager().GetInstanceCount(ctx, request)
+	if err != nil {
+		return 0, err
+	}
+	return resp.Count, nil
 }
diff --git a/server/service/quota/quota_test.go b/server/plugin/quota/buildin/instance_test.go
similarity index 53%
rename from server/service/quota/quota_test.go
rename to server/plugin/quota/buildin/instance_test.go
index b709248..6352c59 100644
--- a/server/service/quota/quota_test.go
+++ b/server/plugin/quota/buildin/instance_test.go
@@ -15,59 +15,24 @@
  * limitations under the License.
  */
 
-package quota_test
+package buildin_test
 
 import (
-	_ "github.com/apache/servicecomb-service-center/test"
-
 	"context"
 	"testing"
 
+	_ "github.com/apache/servicecomb-service-center/test"
+
 	"github.com/apache/servicecomb-service-center/pkg/util"
+	"github.com/apache/servicecomb-service-center/server/plugin/quota/buildin"
 	"github.com/apache/servicecomb-service-center/server/service/disco"
-	"github.com/apache/servicecomb-service-center/server/service/quota"
 	pb "github.com/go-chassis/cari/discovery"
 	"github.com/stretchr/testify/assert"
 )
 
-func getContext() context.Context {
-	return util.WithNoCache(util.SetDomainProject(context.Background(), "default", "default"))
-}
-
-func TestServiceUsage(t *testing.T) {
-	t.Run("get domain/project without service usage, should return 0", func(t *testing.T) {
-		usage, err := quota.ServiceUsage(context.Background(), &pb.GetServiceCountRequest{
-			Domain:  "domain_without_service",
-			Project: "project_without_service",
-		})
-		assert.NoError(t, err)
-		assert.Equal(t, int64(0), usage)
-	})
-
-	t.Run("get domain/project with 1 service usage, should return 1", func(t *testing.T) {
-		ctx := util.SetDomainProject(context.Background(), "domain_with_service", "project_with_service")
-		service, err := disco.RegisterService(ctx, &pb.CreateServiceRequest{
-			Service: &pb.MicroService{
-				ServiceName: "test",
-			},
-		})
-		assert.NoError(t, err)
-
-		usage, err := quota.ServiceUsage(context.Background(), &pb.GetServiceCountRequest{
-			Domain:  "domain_with_service",
-			Project: "project_with_service",
-		})
-		assert.NoError(t, err)
-		assert.Equal(t, int64(1), usage)
-
-		_, err = disco.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: service.ServiceId})
-		assert.NoError(t, err)
-	})
-}
-
 func TestInstanceUsage(t *testing.T) {
 	t.Run("get domain/project without instance usage, should return 0", func(t *testing.T) {
-		usage, err := quota.InstanceUsage(context.Background(), &pb.GetServiceCountRequest{
+		usage, err := buildin.InstanceUsage(context.Background(), &pb.GetServiceCountRequest{
 			Domain:  "domain_without_service",
 			Project: "project_without_service",
 		})
@@ -77,27 +42,25 @@ func TestInstanceUsage(t *testing.T) {
 
 	t.Run("get domain/project with 1 instance usage, should return 1", func(t *testing.T) {
 		ctx := util.SetDomainProject(context.Background(), "domain_with_service", "project_with_service")
-		service, err := disco.RegisterService(ctx, &pb.CreateServiceRequest{
+		resp, err := disco.RegisterService(ctx, &pb.CreateServiceRequest{
 			Service: &pb.MicroService{
 				ServiceName: "test",
 			},
 		})
 		assert.NoError(t, err)
+		defer disco.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
 
 		_, err = disco.RegisterInstance(ctx, &pb.RegisterInstanceRequest{Instance: &pb.MicroServiceInstance{
-			ServiceId: service.ServiceId,
+			ServiceId: resp.ServiceId,
 			HostName:  "test",
 		}})
 		assert.NoError(t, err)
 
-		usage, err := quota.InstanceUsage(context.Background(), &pb.GetServiceCountRequest{
+		usage, err := buildin.InstanceUsage(context.Background(), &pb.GetServiceCountRequest{
 			Domain:  "domain_with_service",
 			Project: "project_with_service",
 		})
 		assert.NoError(t, err)
 		assert.Equal(t, int64(1), usage)
-
-		_, err = disco.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: service.ServiceId, Force: true})
-		assert.NoError(t, err)
 	})
 }
diff --git a/datasource/engine.go b/server/plugin/quota/buildin/role.go
similarity index 66%
copy from datasource/engine.go
copy to server/plugin/quota/buildin/role.go
index 667d0db..f771d14 100644
--- a/datasource/engine.go
+++ b/server/plugin/quota/buildin/role.go
@@ -15,21 +15,18 @@
  * limitations under the License.
  */
 
-package datasource
+package buildin
 
 import (
 	"context"
-	"time"
 
-	"github.com/little-cui/etcdadpt"
+	"github.com/apache/servicecomb-service-center/datasource"
 )
 
-// SCManager contains the APIs of registration of SC itself
-type SCManager interface {
-	SelfRegister(ctx context.Context) error
-	SelfUnregister(ctx context.Context) error
-	// OPS
-	ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error
-	UpgradeVersion(ctx context.Context) error
-	GetClusters(ctx context.Context) (etcdadpt.Clusters, error)
+func RoleUsage(ctx context.Context) (int64, error) {
+	_, used, err := datasource.GetRoleManager().ListRole(ctx)
+	if err != nil {
+		return 0, err
+	}
+	return used, nil
 }
diff --git a/server/service/quota/quota.go b/server/plugin/quota/buildin/schema.go
similarity index 59%
rename from server/service/quota/quota.go
rename to server/plugin/quota/buildin/schema.go
index 036b0ff..3a860bb 100644
--- a/server/service/quota/quota.go
+++ b/server/plugin/quota/buildin/schema.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package quota
+package buildin
 
 import (
 	"context"
@@ -24,22 +24,6 @@ import (
 	"github.com/go-chassis/cari/discovery"
 )
 
-func ServiceUsage(ctx context.Context, request *discovery.GetServiceCountRequest) (int64, error) {
-	resp, err := datasource.GetMetadataManager().GetServiceCount(ctx, request)
-	if err != nil {
-		return 0, err
-	}
-	return resp.Count, nil
-}
-
-func InstanceUsage(ctx context.Context, request *discovery.GetServiceCountRequest) (int64, error) {
-	resp, err := datasource.GetMetadataManager().GetInstanceCount(ctx, request)
-	if err != nil {
-		return 0, err
-	}
-	return resp.Count, nil
-}
-
 func SchemaUsage(ctx context.Context, serviceID string) (int64, error) {
 	resp, err := datasource.GetMetadataManager().GetAllSchemas(ctx, &discovery.GetAllSchemaRequest{
 		ServiceId:  serviceID,
@@ -50,19 +34,3 @@ func SchemaUsage(ctx context.Context, serviceID string) (int64, error) {
 	}
 	return int64(len(resp.Schemas)), nil
 }
-
-func RoleUsage(ctx context.Context) (int64, error) {
-	_, used, err := datasource.GetRoleManager().ListRole(ctx)
-	if err != nil {
-		return 0, err
-	}
-	return used, nil
-}
-
-func AccountUsage(ctx context.Context) (int64, error) {
-	_, used, err := datasource.GetAccountManager().ListAccount(ctx)
-	if err != nil {
-		return 0, err
-	}
-	return used, nil
-}
diff --git a/datasource/engine.go b/server/plugin/quota/buildin/service.go
similarity index 66%
copy from datasource/engine.go
copy to server/plugin/quota/buildin/service.go
index 667d0db..159e029 100644
--- a/datasource/engine.go
+++ b/server/plugin/quota/buildin/service.go
@@ -15,21 +15,19 @@
  * limitations under the License.
  */
 
-package datasource
+package buildin
 
 import (
 	"context"
-	"time"
 
-	"github.com/little-cui/etcdadpt"
+	"github.com/apache/servicecomb-service-center/datasource"
+	pb "github.com/go-chassis/cari/discovery"
 )
 
-// SCManager contains the APIs of registration of SC itself
-type SCManager interface {
-	SelfRegister(ctx context.Context) error
-	SelfUnregister(ctx context.Context) error
-	// OPS
-	ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error
-	UpgradeVersion(ctx context.Context) error
-	GetClusters(ctx context.Context) (etcdadpt.Clusters, error)
+func ServiceUsage(ctx context.Context, request *pb.GetServiceCountRequest) (int64, error) {
+	resp, err := datasource.GetMetadataManager().GetServiceCount(ctx, request)
+	if err != nil {
+		return 0, err
+	}
+	return resp.Count, nil
 }
diff --git a/server/plugin/quota/buildin/service_test.go b/server/plugin/quota/buildin/service_test.go
new file mode 100644
index 0000000..11ffa66
--- /dev/null
+++ b/server/plugin/quota/buildin/service_test.go
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package buildin_test
+
+import (
+	"context"
+	"testing"
+
+	_ "github.com/apache/servicecomb-service-center/test"
+
+	"github.com/apache/servicecomb-service-center/pkg/util"
+	"github.com/apache/servicecomb-service-center/server/plugin/quota/buildin"
+	"github.com/apache/servicecomb-service-center/server/service/disco"
+	pb "github.com/go-chassis/cari/discovery"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestServiceUsage(t *testing.T) {
+	t.Run("get domain/project without service usage, should return 0", func(t *testing.T) {
+		usage, err := buildin.ServiceUsage(context.Background(), &pb.GetServiceCountRequest{
+			Domain:  "domain_without_service",
+			Project: "project_without_service",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, int64(0), usage)
+	})
+
+	t.Run("get domain/project with 1 service usage, should return 1", func(t *testing.T) {
+		ctx := util.SetDomainProject(context.Background(), "domain_with_service", "project_with_service")
+		resp, err := disco.RegisterService(ctx, &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceName: "test",
+			},
+		})
+		assert.NoError(t, err)
+		defer disco.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+		usage, err := buildin.ServiceUsage(context.Background(), &pb.GetServiceCountRequest{
+			Domain:  "domain_with_service",
+			Project: "project_with_service",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, int64(1), usage)
+	})
+}
diff --git a/server/plugin/quota/quota.go b/server/plugin/quota/quota.go
index 38865ca..e24601b 100644
--- a/server/plugin/quota/quota.go
+++ b/server/plugin/quota/quota.go
@@ -21,145 +21,52 @@ import (
 	"context"
 	"errors"
 	"fmt"
-	"strconv"
 
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/plugin"
-	"github.com/apache/servicecomb-service-center/pkg/util"
-	"github.com/apache/servicecomb-service-center/server/config"
-	"github.com/apache/servicecomb-service-center/server/service/quota"
 	pb "github.com/go-chassis/cari/discovery"
 )
 
 const QUOTA plugin.Kind = "quota"
 
-const (
-	defaultServiceLimit  = 50000
-	defaultInstanceLimit = 150000
-	defaultSchemaLimit   = 100
-	defaultTagLimit      = 100
-	defaultAccountLimit  = 1000
-	defaultRoleLimit     = 100
-)
-
-const (
-	TypeSchema ResourceType = iota
-	TypeTag
-	TypeService
-	TypeInstance
-	TypeAccount
-	TypeRole
-)
-
-var (
-	DefaultServiceQuota  = defaultServiceLimit
-	DefaultInstanceQuota = defaultInstanceLimit
-	DefaultSchemaQuota   = defaultSchemaLimit
-	DefaultTagQuota      = defaultTagLimit
-	DefaultAccountQuota  = defaultAccountLimit
-	DefaultRoleQuota     = defaultRoleLimit
-)
-
-func Init() {
-	DefaultServiceQuota = config.GetInt("quota.cap.service.limit", defaultServiceLimit, config.WithENV("QUOTA_SERVICE"))
-	DefaultInstanceQuota = config.GetInt("quota.cap.instance.limit", defaultInstanceLimit, config.WithENV("QUOTA_INSTANCE"))
-	DefaultSchemaQuota = config.GetInt("quota.cap.schema.limit", defaultSchemaLimit, config.WithENV("QUOTA_SCHEMA"))
-	DefaultTagQuota = config.GetInt("quota.cap.tag.limit", defaultTagLimit, config.WithENV("QUOTA_TAG"))
-	DefaultAccountQuota = config.GetInt("quota.cap.account.limit", defaultAccountLimit, config.WithENV("QUOTA_ACCOUNT"))
-	DefaultRoleQuota = config.GetInt("quota.cap.role.limit", defaultRoleLimit, config.WithENV("QUOTA_ROLE"))
+type Manager interface {
+	RemandQuotas(ctx context.Context, t ResourceType)
+	GetQuota(ctx context.Context, t ResourceType) int64
+	Usage(ctx context.Context, req *Request) (int64, error)
 }
 
-type ApplyQuotaResource struct {
-	QuotaType     ResourceType
-	DomainProject string
-	ServiceID     string
-	QuotaSize     int64
+func GetQuota(ctx context.Context, resourceType ResourceType) int64 {
+	return plugin.Plugins().Instance(QUOTA).(Manager).GetQuota(ctx, resourceType)
 }
 
-func NewApplyQuotaResource(quotaType ResourceType, domainProject, serviceID string, quotaSize int64) *ApplyQuotaResource {
-	return &ApplyQuotaResource{
-		quotaType,
-		domainProject,
-		serviceID,
-		quotaSize,
-	}
+func Remand(ctx context.Context, resourceType ResourceType) {
+	plugin.Plugins().Instance(QUOTA).(Manager).RemandQuotas(ctx, resourceType)
 }
 
-type Manager interface {
-	RemandQuotas(ctx context.Context, quotaType ResourceType)
-	GetQuota(ctx context.Context, t ResourceType) int64
-}
-
-type ResourceType int
-
-func (r ResourceType) String() string {
-	switch r {
-	case TypeSchema:
-		return "SCHEMA"
-	case TypeTag:
-		return "TAG"
-	case TypeService:
-		return "SERVICE"
-	case TypeInstance:
-		return "INSTANCE"
-	case TypeAccount:
-		return "ACCOUNT"
-	case TypeRole:
-		return "ROLE"
-	default:
-		return "RESOURCE" + strconv.Itoa(int(r))
-	}
+func Usage(ctx context.Context, req *Request) (int64, error) {
+	return plugin.Plugins().Instance(QUOTA).(Manager).Usage(ctx, req)
 }
 
 // Apply 申请配额sourceType serviceinstance servicetype
-func Apply(ctx context.Context, res *ApplyQuotaResource) error {
+func Apply(ctx context.Context, res *Request) error {
 	if res == nil {
 		err := errors.New("invalid parameters")
 		log.Error("quota check failed", err)
 		return pb.NewError(pb.ErrInternal, err.Error())
 	}
 
-	limitQuota := plugin.Plugins().Instance(QUOTA).(Manager).GetQuota(ctx, res.QuotaType)
-	curNum, err := GetResourceUsage(ctx, res)
+	resourceType := res.QuotaType
+	limitQuota := GetQuota(ctx, resourceType)
+	curNum, err := Usage(ctx, res)
 	if err != nil {
-		log.Error(fmt.Sprintf("%s quota check failed", res.QuotaType), err)
+		log.Error(fmt.Sprintf("%s quota check failed", resourceType), err)
 		return err
 	}
 	if curNum+res.QuotaSize > limitQuota {
 		mes := fmt.Sprintf("no quota to create %s, max num is %d, curNum is %d, apply num is %d",
-			res.QuotaType, limitQuota, curNum, res.QuotaSize)
+			resourceType, limitQuota, curNum, res.QuotaSize)
 		log.Error(mes, nil)
 		return pb.NewError(pb.ErrNotEnoughQuota, mes)
 	}
 	return nil
 }
-
-func Remand(ctx context.Context, quotaType ResourceType) {
-	plugin.Plugins().Instance(QUOTA).(Manager).RemandQuotas(ctx, quotaType)
-}
-func GetResourceUsage(ctx context.Context, res *ApplyQuotaResource) (int64, error) {
-	serviceID := res.ServiceID
-	switch res.QuotaType {
-	case TypeService:
-		return quota.ServiceUsage(ctx, &pb.GetServiceCountRequest{
-			Domain:  util.ParseDomain(ctx),
-			Project: util.ParseProject(ctx),
-		})
-	case TypeInstance:
-		return quota.InstanceUsage(ctx, &pb.GetServiceCountRequest{
-			Domain:  util.ParseDomain(ctx),
-			Project: util.ParseProject(ctx),
-		})
-	case TypeSchema:
-		return quota.SchemaUsage(ctx, serviceID)
-	case TypeTag:
-		// always re-create the service old tags
-		return 0, nil
-	case TypeRole:
-		return quota.RoleUsage(ctx)
-	case TypeAccount:
-		return quota.AccountUsage(ctx)
-	default:
-		return 0, fmt.Errorf("not define quota type '%s'", res.QuotaType)
-	}
-}
diff --git a/datasource/engine.go b/server/plugin/quota/request.go
similarity index 64%
copy from datasource/engine.go
copy to server/plugin/quota/request.go
index 667d0db..93b56a2 100644
--- a/datasource/engine.go
+++ b/server/plugin/quota/request.go
@@ -15,21 +15,14 @@
  * limitations under the License.
  */
 
-package datasource
+package quota
 
-import (
-	"context"
-	"time"
+type ResourceType string
 
-	"github.com/little-cui/etcdadpt"
-)
-
-// SCManager contains the APIs of registration of SC itself
-type SCManager interface {
-	SelfRegister(ctx context.Context) error
-	SelfUnregister(ctx context.Context) error
-	// OPS
-	ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error
-	UpgradeVersion(ctx context.Context) error
-	GetClusters(ctx context.Context) (etcdadpt.Clusters, error)
+type Request struct {
+	QuotaType ResourceType
+	Domain    string
+	Project   string
+	ServiceID string
+	QuotaSize int64
 }
diff --git a/server/service/disco/instance.go b/server/service/disco/instance.go
index 36ea884..4a57a9d 100644
--- a/server/service/disco/instance.go
+++ b/server/service/disco/instance.go
@@ -30,7 +30,7 @@ import (
 	"github.com/apache/servicecomb-service-center/server/config"
 	apt "github.com/apache/servicecomb-service-center/server/core"
 	"github.com/apache/servicecomb-service-center/server/health"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	"github.com/apache/servicecomb-service-center/server/service/validator"
 	pb "github.com/go-chassis/cari/discovery"
 )
@@ -49,8 +49,7 @@ func RegisterInstance(ctx context.Context, in *pb.RegisterInstanceRequest) (*pb.
 		}, nil
 	}
 	remoteIP := util.GetIPFromContext(ctx)
-	domainProject := util.ParseDomainProject(ctx)
-	if quotaErr := checkInstanceQuota(ctx, domainProject, in.Instance.ServiceId); quotaErr != nil {
+	if quotaErr := checkInstanceQuota(ctx); quotaErr != nil {
 		log.Error(fmt.Sprintf("register instance failed, endpoints %v, host '%s', serviceID %s, operator %s",
 			in.Instance.Endpoints, in.Instance.HostName, in.Instance.ServiceId, remoteIP), quotaErr)
 		response, err := datasource.WrapErrResponse(quotaErr)
@@ -269,11 +268,9 @@ func ClusterHealth(ctx context.Context) (*pb.GetInstancesResponse, error) {
 	}, nil
 }
 
-func checkInstanceQuota(ctx context.Context, domainProject string, serviceID string) error {
+func checkInstanceQuota(ctx context.Context) error {
 	if !apt.IsSCInstance(ctx) {
-		res := quota.NewApplyQuotaResource(quota.TypeInstance,
-			domainProject, serviceID, 1)
-		return quota.Apply(ctx, res)
+		return quotasvc.ApplyInstance(ctx, 1)
 	}
 	return nil
 }
diff --git a/server/service/disco/microservice.go b/server/service/disco/microservice.go
index 40215c3..f3735bf 100644
--- a/server/service/disco/microservice.go
+++ b/server/service/disco/microservice.go
@@ -25,7 +25,7 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/core"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	"github.com/apache/servicecomb-service-center/server/service/validator"
 	pb "github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/foundation/gopool"
@@ -61,8 +61,6 @@ func (s *MicroServiceService) CreateServicePri(ctx context.Context, in *pb.Creat
 	service := in.Service
 	serviceFlag := util.StringJoin([]string{
 		service.Environment, service.AppId, service.ServiceName, service.Version}, "/")
-	domainProject := util.ParseDomainProject(ctx)
-
 	datasource.SetServiceDefaultValue(service)
 	if err := validator.Validate(in); err != nil {
 		log.Error(fmt.Sprintf("create micro-service[%s] failed, operator: %s",
@@ -71,7 +69,7 @@ func (s *MicroServiceService) CreateServicePri(ctx context.Context, in *pb.Creat
 			Response: pb.CreateResponse(pb.ErrInvalidParams, err.Error()),
 		}, nil
 	}
-	if quotaErr := checkServiceQuota(ctx, domainProject); quotaErr != nil {
+	if quotaErr := checkServiceQuota(ctx); quotaErr != nil {
 		log.Error(fmt.Sprintf("create micro-service[%s] failed, operator: %s",
 			serviceFlag, remoteIP), quotaErr)
 		response, err := datasource.WrapErrResponse(quotaErr)
@@ -334,11 +332,10 @@ func (s *MicroServiceService) isCreateServiceEx(in *pb.CreateServiceRequest) boo
 	return true
 }
 
-func checkServiceQuota(ctx context.Context, domainProject string) error {
+func checkServiceQuota(ctx context.Context) error {
 	if core.IsSCInstance(ctx) {
 		log.Debug("skip quota check")
 		return nil
 	}
-	res := quota.NewApplyQuotaResource(quota.TypeService, domainProject, "", 1)
-	return quota.Apply(ctx, res)
+	return quotasvc.ApplyService(ctx, 1)
 }
diff --git a/server/service/disco/microservice_test.go b/server/service/disco/microservice_test.go
index 9230ffc..41f2b19 100644
--- a/server/service/disco/microservice_test.go
+++ b/server/service/disco/microservice_test.go
@@ -24,8 +24,8 @@ import (
 	. "github.com/onsi/gomega"
 
 	"github.com/apache/servicecomb-service-center/server/core"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 	"github.com/apache/servicecomb-service-center/server/service/disco"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	pb "github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/cari/pkg/errsvc"
 )
@@ -55,7 +55,7 @@ var _ = Describe("'Micro-service' service", func() {
 
 		Context("all max", func() {
 			It("should be passed", func() {
-				size := quota.DefaultSchemaQuota + 1
+				size := int(quotasvc.SchemaQuota()) + 1
 				paths := make([]*pb.ServicePath, 0, size)
 				properties := make(map[string]string, size)
 				for i := 0; i < size; i++ {
diff --git a/server/service/disco/schema.go b/server/service/disco/schema.go
index a9275ae..3b3bc35 100644
--- a/server/service/disco/schema.go
+++ b/server/service/disco/schema.go
@@ -24,7 +24,7 @@ import (
 	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	"github.com/apache/servicecomb-service-center/server/service/validator"
 	pb "github.com/go-chassis/cari/discovery"
 )
@@ -117,8 +117,7 @@ func canModifySchema(ctx context.Context, domainProject string, in *pb.ModifySch
 		return pb.NewError(pb.ErrInvalidParams, err.Error())
 	}
 
-	res := quota.NewApplyQuotaResource(quota.TypeSchema, domainProject, serviceID, 1)
-	if errQuota := quota.Apply(ctx, res); errQuota != nil {
+	if errQuota := quotasvc.ApplySchema(ctx, serviceID, 1); errQuota != nil {
 		log.Error(fmt.Sprintf("update schema[%s/%s] failed, operator: %s", serviceID, schemaID, remoteIP), errQuota)
 		return errQuota
 	}
diff --git a/server/service/disco/schema_test.go b/server/service/disco/schema_test.go
index 5c64a8d..6e7f3f8 100644
--- a/server/service/disco/schema_test.go
+++ b/server/service/disco/schema_test.go
@@ -22,8 +22,8 @@ import (
 	"testing"
 
 	"github.com/apache/servicecomb-service-center/datasource"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 	"github.com/apache/servicecomb-service-center/server/service/disco"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	pb "github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/cari/pkg/errsvc"
 	"github.com/stretchr/testify/assert"
@@ -226,7 +226,8 @@ func TestPutSchema(t *testing.T) {
 		serviceIdDev = old
 	})
 
-	size := quota.DefaultSchemaQuota + 1
+	max := int(quotasvc.SchemaQuota())
+	size := max + 1
 	schemaIds := make([]string, 0, size)
 	schemas := make([]*pb.Schema, 0, size)
 	for i := 0; i < size; i++ {
@@ -251,11 +252,11 @@ func TestPutSchema(t *testing.T) {
 
 		_, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
 			ServiceId: serviceIdDev,
-			Schemas:   schemas[:quota.DefaultSchemaQuota],
+			Schemas:   schemas[:max],
 		})
 		assert.NoError(t, err)
 
-		schema := schemas[quota.DefaultSchemaQuota]
+		schema := schemas[max]
 		_, err = disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
 			ServiceId: serviceIdDev,
 			SchemaId:  schema.SchemaId,
diff --git a/server/service/disco/tag_test.go b/server/service/disco/tag_test.go
index 9b2193c..a789627 100644
--- a/server/service/disco/tag_test.go
+++ b/server/service/disco/tag_test.go
@@ -21,12 +21,12 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/apache/servicecomb-service-center/server/service/disco"
-
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
-	pb "github.com/go-chassis/cari/discovery"
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
+
+	"github.com/apache/servicecomb-service-center/server/service/disco"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
+	pb "github.com/go-chassis/cari/discovery"
 )
 
 var (
@@ -34,6 +34,8 @@ var (
 )
 
 var _ = Describe("'Tag' service", func() {
+	max := int(quotasvc.TagQuota())
+
 	Describe("execute 'create' operation", func() {
 		var (
 			serviceId1 string
@@ -102,9 +104,8 @@ var _ = Describe("'Tag' service", func() {
 		Context("when request is valid", func() {
 			It("should be passed", func() {
 				By("all max")
-				size := quota.DefaultTagQuota
-				tags := make(map[string]string, size)
-				for i := 0; i < size; i++ {
+				tags := make(map[string]string, max)
+				for i := 0; i < max; i++ {
 					s := "tag" + strconv.Itoa(i)
 					tags[s] = s
 				}
@@ -128,7 +129,7 @@ var _ = Describe("'Tag' service", func() {
 
 		Context("when create tag out of gauge", func() {
 			It("should be failed", func() {
-				size := quota.DefaultTagQuota + 1
+				size := max + 1
 				tags := make(map[string]string, size)
 				for i := 0; i < size; i++ {
 					s := "tag" + strconv.Itoa(i)
@@ -141,9 +142,8 @@ var _ = Describe("'Tag' service", func() {
 				Expect(err).To(BeNil())
 				Expect(respAddTags.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
 
-				size = quota.DefaultTagQuota
-				tags = make(map[string]string, size)
-				for i := 0; i < size; i++ {
+				tags = make(map[string]string, max)
+				for i := 0; i < max; i++ {
 					s := "tag" + strconv.Itoa(i)
 					tags[s] = s
 				}
@@ -468,7 +468,7 @@ var _ = Describe("'Tag' service", func() {
 				Expect(respAddTags.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
 
 				var arr []string
-				for i := 0; i < quota.DefaultTagQuota+1; i++ {
+				for i := 0; i < int(max)+1; i++ {
 					arr = append(arr, strconv.Itoa(i))
 				}
 				respAddTags, err = serviceResource.DeleteTags(getContext(), &pb.DeleteServiceTagsRequest{
diff --git a/datasource/engine.go b/server/service/quota/account.go
similarity index 66%
copy from datasource/engine.go
copy to server/service/quota/account.go
index 667d0db..4244fc5 100644
--- a/datasource/engine.go
+++ b/server/service/quota/account.go
@@ -15,21 +15,22 @@
  * limitations under the License.
  */
 
-package datasource
+package quota
 
 import (
 	"context"
-	"time"
 
-	"github.com/little-cui/etcdadpt"
+	"github.com/apache/servicecomb-service-center/pkg/util"
+	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 )
 
-// SCManager contains the APIs of registration of SC itself
-type SCManager interface {
-	SelfRegister(ctx context.Context) error
-	SelfUnregister(ctx context.Context) error
-	// OPS
-	ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error
-	UpgradeVersion(ctx context.Context) error
-	GetClusters(ctx context.Context) (etcdadpt.Clusters, error)
+const TypeAccount quota.ResourceType = "ACCOUNT"
+
+func ApplyAccount(ctx context.Context, size int64) error {
+	return quota.Apply(ctx, &quota.Request{
+		QuotaType: TypeAccount,
+		Domain:    util.ParseDomain(ctx),
+		Project:   util.ParseProject(ctx),
+		QuotaSize: size,
+	})
 }
diff --git a/datasource/mongo/mongo_test.go b/server/service/quota/instance.go
similarity index 63%
copy from datasource/mongo/mongo_test.go
copy to server/service/quota/instance.go
index c573034..a183216 100644
--- a/datasource/mongo/mongo_test.go
+++ b/server/service/quota/instance.go
@@ -15,28 +15,30 @@
  * limitations under the License.
  */
 
-package mongo_test
+package quota
 
-// initialize
 import (
 	"context"
-	"testing"
-	"time"
 
-	_ "github.com/apache/servicecomb-service-center/test"
-
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/pkg/util"
+	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 )
 
-var timeLimit = 2 * time.Second
+const TypeInstance quota.ResourceType = "INSTANCE"
+
+func InstanceQuota() int64 {
+	return quota.GetQuota(context.Background(), TypeInstance)
+}
 
-func getContext() context.Context {
-	return util.WithNoCache(util.SetDomainProject(context.Background(), "default", "default"))
+func ApplyInstance(ctx context.Context, size int64) error {
+	return quota.Apply(ctx, &quota.Request{
+		QuotaType: TypeInstance,
+		Domain:    util.ParseDomain(ctx),
+		Project:   util.ParseProject(ctx),
+		QuotaSize: size,
+	})
 }
 
-func TestMongo(t *testing.T) {
-	//clear service created in last test
-	time.Sleep(timeLimit)
-	_ = datasource.GetSCManager().ClearNoInstanceServices(getContext(), timeLimit)
+func RemandInstance(ctx context.Context) {
+	quota.Remand(ctx, TypeInstance)
 }
diff --git a/server/service/quota/instance_test.go b/server/service/quota/instance_test.go
new file mode 100644
index 0000000..6ce44da
--- /dev/null
+++ b/server/service/quota/instance_test.go
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package quota_test
+
+import (
+	"context"
+	"testing"
+
+	_ "github.com/apache/servicecomb-service-center/test"
+
+	"github.com/apache/servicecomb-service-center/pkg/util"
+	discosvc "github.com/apache/servicecomb-service-center/server/service/disco"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
+	pb "github.com/go-chassis/cari/discovery"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestApplyInstance(t *testing.T) {
+	//var id string
+	ctx := context.TODO()
+	ctx = util.SetDomainProject(ctx, "quota", "quota")
+	t.Run("create 1 instance,should success", func(t *testing.T) {
+		resp, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceName: "quota",
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+		defer discosvc.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+		err = quotasvc.ApplyInstance(ctx, 1)
+		assert.Nil(t, err)
+
+		err = quotasvc.ApplyInstance(ctx, 150001)
+		assert.NotNil(t, err)
+	})
+
+	t.Run("create 150001 instance,should failed", func(t *testing.T) {
+		resp, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceName: "quota2",
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+		defer discosvc.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+		err = quotasvc.ApplyInstance(ctx, 150001)
+		assert.NotNil(t, err)
+	})
+}
+
+func TestRemandInstance(t *testing.T) {
+	quotasvc.RemandInstance(context.Background())
+}
diff --git a/datasource/engine.go b/server/service/quota/role.go
similarity index 66%
copy from datasource/engine.go
copy to server/service/quota/role.go
index 667d0db..178a377 100644
--- a/datasource/engine.go
+++ b/server/service/quota/role.go
@@ -15,21 +15,22 @@
  * limitations under the License.
  */
 
-package datasource
+package quota
 
 import (
 	"context"
-	"time"
 
-	"github.com/little-cui/etcdadpt"
+	"github.com/apache/servicecomb-service-center/pkg/util"
+	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 )
 
-// SCManager contains the APIs of registration of SC itself
-type SCManager interface {
-	SelfRegister(ctx context.Context) error
-	SelfUnregister(ctx context.Context) error
-	// OPS
-	ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error
-	UpgradeVersion(ctx context.Context) error
-	GetClusters(ctx context.Context) (etcdadpt.Clusters, error)
+const TypeRole quota.ResourceType = "ROLE"
+
+func ApplyRole(ctx context.Context, size int64) error {
+	return quota.Apply(ctx, &quota.Request{
+		QuotaType: TypeRole,
+		Domain:    util.ParseDomain(ctx),
+		Project:   util.ParseProject(ctx),
+		QuotaSize: size,
+	})
 }
diff --git a/datasource/mongo/mongo_test.go b/server/service/quota/schema.go
similarity index 64%
copy from datasource/mongo/mongo_test.go
copy to server/service/quota/schema.go
index c573034..fe2c21d 100644
--- a/datasource/mongo/mongo_test.go
+++ b/server/service/quota/schema.go
@@ -15,28 +15,27 @@
  * limitations under the License.
  */
 
-package mongo_test
+package quota
 
-// initialize
 import (
 	"context"
-	"testing"
-	"time"
 
-	_ "github.com/apache/servicecomb-service-center/test"
-
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/pkg/util"
+	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 )
 
-var timeLimit = 2 * time.Second
+const TypeSchema quota.ResourceType = "SCHEMA"
 
-func getContext() context.Context {
-	return util.WithNoCache(util.SetDomainProject(context.Background(), "default", "default"))
+func SchemaQuota() int64 {
+	return quota.GetQuota(context.Background(), TypeSchema)
 }
 
-func TestMongo(t *testing.T) {
-	//clear service created in last test
-	time.Sleep(timeLimit)
-	_ = datasource.GetSCManager().ClearNoInstanceServices(getContext(), timeLimit)
+func ApplySchema(ctx context.Context, serviceID string, size int64) error {
+	return quota.Apply(ctx, &quota.Request{
+		QuotaType: TypeSchema,
+		Domain:    util.ParseDomain(ctx),
+		Project:   util.ParseProject(ctx),
+		ServiceID: serviceID,
+		QuotaSize: size,
+	})
 }
diff --git a/datasource/mongo/mongo_test.go b/server/service/quota/service.go
similarity index 63%
copy from datasource/mongo/mongo_test.go
copy to server/service/quota/service.go
index c573034..bedf589 100644
--- a/datasource/mongo/mongo_test.go
+++ b/server/service/quota/service.go
@@ -15,28 +15,30 @@
  * limitations under the License.
  */
 
-package mongo_test
+package quota
 
-// initialize
 import (
 	"context"
-	"testing"
-	"time"
 
-	_ "github.com/apache/servicecomb-service-center/test"
-
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/pkg/util"
+	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 )
 
-var timeLimit = 2 * time.Second
+const TypeService quota.ResourceType = "SERVICE"
+
+func ServiceQuota() int64 {
+	return quota.GetQuota(context.Background(), TypeService)
+}
 
-func getContext() context.Context {
-	return util.WithNoCache(util.SetDomainProject(context.Background(), "default", "default"))
+func ApplyService(ctx context.Context, size int64) error {
+	return quota.Apply(ctx, &quota.Request{
+		QuotaType: TypeService,
+		Domain:    util.ParseDomain(ctx),
+		Project:   util.ParseProject(ctx),
+		QuotaSize: size,
+	})
 }
 
-func TestMongo(t *testing.T) {
-	//clear service created in last test
-	time.Sleep(timeLimit)
-	_ = datasource.GetSCManager().ClearNoInstanceServices(getContext(), timeLimit)
+func RemandService(ctx context.Context) {
+	quota.Remand(ctx, TypeService)
 }
diff --git a/datasource/mongo/mongo_test.go b/server/service/quota/service_test.go
similarity index 66%
copy from datasource/mongo/mongo_test.go
copy to server/service/quota/service_test.go
index c573034..2a3884b 100644
--- a/datasource/mongo/mongo_test.go
+++ b/server/service/quota/service_test.go
@@ -15,28 +15,29 @@
  * limitations under the License.
  */
 
-package mongo_test
+package quota_test
 
-// initialize
 import (
 	"context"
 	"testing"
-	"time"
 
 	_ "github.com/apache/servicecomb-service-center/test"
 
-	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/pkg/util"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
+	"github.com/stretchr/testify/assert"
 )
 
-var timeLimit = 2 * time.Second
-
-func getContext() context.Context {
-	return util.WithNoCache(util.SetDomainProject(context.Background(), "default", "default"))
+func TestApplyService(t *testing.T) {
+	//var id string
+	ctx := context.TODO()
+	ctx = util.SetDomainProject(ctx, "quota", "quota")
+	t.Run("create service, should success", func(t *testing.T) {
+		err := quotasvc.ApplyService(ctx, 1)
+		assert.Nil(t, err)
+	})
 }
 
-func TestMongo(t *testing.T) {
-	//clear service created in last test
-	time.Sleep(timeLimit)
-	_ = datasource.GetSCManager().ClearNoInstanceServices(getContext(), timeLimit)
+func TestRemandService(t *testing.T) {
+	quotasvc.RemandService(context.Background())
 }
diff --git a/datasource/engine.go b/server/service/quota/tag.go
similarity index 66%
copy from datasource/engine.go
copy to server/service/quota/tag.go
index 667d0db..e846269 100644
--- a/datasource/engine.go
+++ b/server/service/quota/tag.go
@@ -15,21 +15,16 @@
  * limitations under the License.
  */
 
-package datasource
+package quota
 
 import (
 	"context"
-	"time"
 
-	"github.com/little-cui/etcdadpt"
+	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 )
 
-// SCManager contains the APIs of registration of SC itself
-type SCManager interface {
-	SelfRegister(ctx context.Context) error
-	SelfUnregister(ctx context.Context) error
-	// OPS
-	ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error
-	UpgradeVersion(ctx context.Context) error
-	GetClusters(ctx context.Context) (etcdadpt.Clusters, error)
+const TypeTag quota.ResourceType = "TAG"
+
+func TagQuota() int64 {
+	return quota.GetQuota(context.Background(), TypeTag)
 }
diff --git a/server/service/rbac/account_service.go b/server/service/rbac/account_service.go
index 464c011..f893f37 100644
--- a/server/service/rbac/account_service.go
+++ b/server/service/rbac/account_service.go
@@ -25,8 +25,7 @@ import (
 	"github.com/apache/servicecomb-service-center/datasource"
 	errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
 	"github.com/apache/servicecomb-service-center/pkg/log"
-	"github.com/apache/servicecomb-service-center/pkg/util"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	"github.com/apache/servicecomb-service-center/server/service/validator"
 	"github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/cari/rbac"
@@ -34,8 +33,7 @@ import (
 
 //CreateAccount save account info
 func CreateAccount(ctx context.Context, a *rbac.Account) error {
-	quotaErr := quota.Apply(ctx, quota.NewApplyQuotaResource(quota.TypeAccount,
-		util.ParseDomainProject(ctx), "", 1))
+	quotaErr := quotasvc.ApplyAccount(ctx, 1)
 	if quotaErr != nil {
 		return rbac.NewError(rbac.ErrAccountNoQuota, quotaErr.Error())
 	}
diff --git a/server/service/rbac/role_service.go b/server/service/rbac/role_service.go
index 7a76710..a317596 100644
--- a/server/service/rbac/role_service.go
+++ b/server/service/rbac/role_service.go
@@ -22,14 +22,13 @@ import (
 	"errors"
 	"fmt"
 
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	"github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/cari/rbac"
 
 	"github.com/apache/servicecomb-service-center/datasource"
 	errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
 	"github.com/apache/servicecomb-service-center/pkg/log"
-	"github.com/apache/servicecomb-service-center/pkg/util"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 	"github.com/apache/servicecomb-service-center/server/service/validator"
 )
 
@@ -39,8 +38,7 @@ func CreateRole(ctx context.Context, r *rbac.Role) error {
 		log.Error(fmt.Sprintf("create role [%s] failed", r.Name), err)
 		return discovery.NewError(discovery.ErrInvalidParams, err.Error())
 	}
-	quotaErr := quota.Apply(ctx, quota.NewApplyQuotaResource(quota.TypeRole,
-		util.ParseDomainProject(ctx), "", 1))
+	quotaErr := quotasvc.ApplyRole(ctx, 1)
 	if quotaErr != nil {
 		return rbac.NewError(rbac.ErrRoleNoQuota, quotaErr.Error())
 	}
diff --git a/server/service/validator/microservice_validator.go b/server/service/validator/microservice_validator.go
index 486721f..d1201ce 100644
--- a/server/service/validator/microservice_validator.go
+++ b/server/service/validator/microservice_validator.go
@@ -22,7 +22,7 @@ import (
 
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/pkg/validate"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	"github.com/go-chassis/cari/discovery"
 )
 
@@ -88,6 +88,8 @@ func GetServiceReqValidator() *validate.Validator {
 
 func CreateServiceReqValidator() *validate.Validator {
 	return createServiceReqValidator.Init(func(v *validate.Validator) {
+		max := int(quotasvc.SchemaQuota())
+
 		var pathValidator validate.Validator
 		pathValidator.AddRule("Path", &validate.Rule{Regexp: pathRegex})
 
@@ -103,7 +105,7 @@ func CreateServiceReqValidator() *validate.Validator {
 		microServiceValidator.AddRule("Description", &validate.Rule{Max: 256})
 		microServiceValidator.AddRule("Level", &validate.Rule{Regexp: levelRegex})
 		microServiceValidator.AddRule("Status", &validate.Rule{Regexp: statusRegex})
-		microServiceValidator.AddRule("Schemas", &validate.Rule{Max: quota.DefaultSchemaQuota, Regexp: schemaIDRegex})
+		microServiceValidator.AddRule("Schemas", &validate.Rule{Max: max, Regexp: schemaIDRegex})
 		microServiceValidator.AddSub("Paths", &pathValidator)
 		microServiceValidator.AddRule("Alias", &validate.Rule{Max: 128, Regexp: aliasRegex})
 		microServiceValidator.AddRule("RegisterBy", &validate.Rule{Max: 64, Regexp: registerByRegex})
diff --git a/server/service/validator/schema_validator.go b/server/service/validator/schema_validator.go
index 7cecff5..077294e 100644
--- a/server/service/validator/schema_validator.go
+++ b/server/service/validator/schema_validator.go
@@ -21,7 +21,7 @@ import (
 	"regexp"
 
 	"github.com/apache/servicecomb-service-center/pkg/validate"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 )
 
 var (
@@ -44,13 +44,15 @@ func GetSchemaReqValidator() *validate.Validator {
 
 func ModifySchemasReqValidator() *validate.Validator {
 	return modifySchemasReqValidator.Init(func(v *validate.Validator) {
+		max := int(quotasvc.SchemaQuota())
+
 		var subSchemaValidator validate.Validator
 		subSchemaValidator.AddRule("SchemaId", GetSchemaReqValidator().GetRule("SchemaId"))
 		subSchemaValidator.AddRule("Summary", &validate.Rule{Min: 1, Max: 128, Regexp: schemaSummaryRegex})
 		subSchemaValidator.AddRule("Schema", &validate.Rule{Min: 1})
 
 		v.AddRule("ServiceId", GetServiceReqValidator().GetRule("ServiceId"))
-		v.AddRule("Schemas", &validate.Rule{Min: 1, Max: quota.DefaultSchemaQuota})
+		v.AddRule("Schemas", &validate.Rule{Min: 1, Max: max})
 		v.AddSub("Schemas", &subSchemaValidator)
 	})
 }
diff --git a/server/service/validator/tag_validator.go b/server/service/validator/tag_validator.go
index bdd00af..8f0f299 100644
--- a/server/service/validator/tag_validator.go
+++ b/server/service/validator/tag_validator.go
@@ -21,7 +21,7 @@ import (
 	"regexp"
 
 	"github.com/apache/servicecomb-service-center/pkg/validate"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 )
 
 var (
@@ -43,8 +43,9 @@ func GetTagsReqValidator() *validate.Validator {
 
 func AddTagsReqValidator() *validate.Validator {
 	return addTagsReqValidator.Init(func(v *validate.Validator) {
+		max := int(quotasvc.TagQuota())
 		v.AddRule("ServiceId", GetServiceReqValidator().GetRule("ServiceId"))
-		v.AddRule("Tags", &validate.Rule{Max: quota.DefaultTagQuota, Regexp: tagRegex})
+		v.AddRule("Tags", &validate.Rule{Max: max, Regexp: tagRegex})
 	})
 }
 
@@ -59,7 +60,8 @@ func UpdateTagReqValidator() *validate.Validator {
 
 func DeleteTagReqValidator() *validate.Validator {
 	return deleteTagReqValidator.Init(func(v *validate.Validator) {
+		max := int(quotasvc.TagQuota())
 		v.AddRule("ServiceId", GetServiceReqValidator().GetRule("ServiceId"))
-		v.AddRule("Keys", &validate.Rule{Min: 1, Max: quota.DefaultTagQuota, Regexp: tagRegex})
+		v.AddRule("Keys", &validate.Rule{Min: 1, Max: max, Regexp: tagRegex})
 	})
 }
diff --git a/test/test.go b/test/test.go
index d5d651e..d1c4c2f 100644
--- a/test/test.go
+++ b/test/test.go
@@ -23,7 +23,6 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/apache/servicecomb-service-center/pkg/util"
 	_ "github.com/apache/servicecomb-service-center/server/init"
 
 	_ "github.com/apache/servicecomb-service-center/server/bootstrap"
@@ -31,6 +30,7 @@ import (
 	_ "github.com/go-chassis/go-chassis-extension/protocol/grpc/server"
 
 	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/core"
 	"github.com/apache/servicecomb-service-center/server/metrics"
 	"github.com/apache/servicecomb-service-center/server/service/disco"