wfz преди 3 години
ревизия
2804938fdd

+ 42 - 0
.gitignore

@@ -0,0 +1,42 @@
+# Reference https://github.com/github/gitignore/blob/master/Go.gitignore
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+vendor/
+
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# OS General
+Thumbs.db
+.DS_Store
+
+# project
+*.cert
+*.key
+*.log
+bin/
+
+# Develop tools
+.vscode/
+.idea/
+*.swp
+
+cmd/server/server
+cmd/server/server.exe
+#build.sh
+#start.sh
+js

+ 17 - 0
Dockerfile

@@ -0,0 +1,17 @@
+FROM alpine:3.13.5
+
+COPY  bin/server /app/server
+
+# 设定时区
+RUN echo -n 'VFppZjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdAAAAAwAAAAyAAAAAoJeigKF5BPDIWV6AyQn5cMnTvQDLBYrwy3xAANI7PvDTi3uA1EKt8NVFIgDWTL/w1zy/ANgGZnDZHfKA2UF88B66UiAfaZuQIH6EoCFJfZAiZ6EgIylfkCRHgyAlEnwQJidlICbyXhAoB0cgKNJAEAIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAABx1wAAAAB+kAEEAABwgAAITE1UAENEVABDU1QAVFppZjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdAAAAAwAAAAz/////fjZDKf////+gl6KA/////6F5BPD/////yFlegP/////JCflw/////8nTvQD/////ywWK8P/////LfEAA/////9I7PvD/////04t7gP/////UQq3w/////9VFIgD/////1ky/8P/////XPL8A/////9gGZnD/////2R3ygP/////ZQXzwAAAAAB66UiAAAAAAH2mbkAAAAAAgfoSgAAAAACFJfZAAAAAAImehIAAAAAAjKV+QAAAAACRHgyAAAAAAJRJ8EAAAAAAmJ2UgAAAAACbyXhAAAAAAKAdHIAAAAAAo0kAQAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIAAHHXAAAAAH6QAQQAAHCAAAhMTVQAQ0RUAENTVAAKQ1NULTgK'|base64 -d > /etc/localtime && echo -n 'Asia/Shanghai' > /etc/timezone
+
+WORKDIR /app
+
+ENV JL_GROUP=jl
+ENV JL_NAMESPACE=100680ab-5125-4564-bddf-d394f8d296e4
+ENV JL_CONFIG_SOURCE=http://mse-2b481c86-nacos-ans.mse.aliyuncs.com:8848
+
+EXPOSE 18000
+EXPOSE 19000
+
+CMD ["./server"]

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 go-kratos
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 31 - 0
Makefile

@@ -0,0 +1,31 @@
+#开发环境使用
+.PHONY: docker-dev
+docker-dev:
+	@rm -rf ./bin/server && \
+	go mod download && \
+	CGO_ENABLED=0 go build -o ./bin/ -ldflags "-X main.name={kratos-layout}" ./... && \
+	docker build -t {kratos-layout}-dev .
+
+#线上环境使用
+.PHONY: docker-pro
+docker-pro:
+	@rm -rf ./bin/server && \
+	go mod download && \
+	CGO_ENABLED=0 go build -o ./bin/ -ldflags "-X main.name={kratos-layout}" ./... && \
+	docker build -t {kratos-layout}-pro .
+
+#本机环境使用
+.PHONY: docker-mac #指令重命名
+docker-mac:
+	@rm -rf ./bin/server && \
+	CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./bin/ \
+	-ldflags "-X main.Name={kratos-layout}" ./... && \
+    docker build -t {kratos-layout} .
+
+.PHONY: run-docker
+run-docker: run-docker-rm start-docker
+run-docker-rm:
+	@-docker stop {kratos-layout} && docker rm {kratos-layout}
+start-docker:
+	@docker run -d -p 18000:18000 --name="{kratos-layout}" {kratos-layout}:latest
+

+ 30 - 0
README.md

@@ -0,0 +1,30 @@
+# Kratos Project Template
+
+## Install Kratos
+```
+go get -u github.com/go-kratos/kratos/cmd/kratos/v2@latest
+```
+## Create a service
+```
+# create a template project
+kratos new helloworld
+
+cd helloworld
+# Add a proto template
+kratos proto add api/helloworld/helloworld.proto
+# Generate the source code of service by proto file
+kratos proto server api/helloworld/helloworld.proto -t internal/service
+
+go generate ./...
+go build -o ./bin/ ./...
+./bin/helloworld -conf ./configs
+```
+## Automated Initialization (wire)
+```
+# install wire
+go get github.com/google/wire/cmd/wire
+
+# generate wire
+cd cmd/server
+wire
+```

+ 3 - 0
build.sh

@@ -0,0 +1,3 @@
+go get -d github.com/google/wire/cmd/wire@v0.5.0
+go generate ./...
+go build -o ./bin/ -ldflags "-X main.Version=x.y.z -X main.name={kratos-layout}" ./...

+ 144 - 0
cmd/server/main.go

@@ -0,0 +1,144 @@
+package main
+
+import (
+	"context"
+	"flag"
+	"os"
+
+	nacosConfig "git.ikuban.com/server/kratos-nacos/config"
+	"git.ikuban.com/server/kratos-nacos/registry"
+
+	"github.com/go-kratos/kratos/v2/config/file"
+
+	"git.ikuban.com/server/yaml"
+	"github.com/go-kratos/kratos-layout/internal/conf"
+	"github.com/go-kratos/kratos/v2"
+	"github.com/go-kratos/kratos/v2/config"
+	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-kratos/kratos/v2/transport/grpc"
+	"github.com/go-kratos/kratos/v2/transport/http"
+)
+
+// go build -ldflags "-X main.Version=x.y.z"
+var (
+	// Name is the name of the compiled software.
+	name string
+	// Version is the version of the compiled software.
+	Version string
+	// flagconf is the config flag.
+	flagconf string
+
+	group     string
+	namespace string
+
+	configSource string
+)
+
+func init() {
+	flag.StringVar(&flagconf, "f", "", "config path, eg: -f configs/config.yaml")
+
+	if configSource == "" {
+		configSource = "http://cfg.cpshelp.cn:80"
+	}
+
+	if os.Getenv("JL_GROUP") != "" {
+		group = os.Getenv("JL_GROUP")
+	}
+
+	if os.Getenv("JL_NAMESPACE") != "" {
+		namespace = os.Getenv("JL_NAMESPACE")
+	}
+
+	if os.Getenv("JL_CONFIG_SOURCE") != "" {
+		configSource = os.Getenv("JL_CONFIG_SOURCE")
+	}
+}
+
+func newApp(ctx context.Context, logger log.Logger, r *registry.Registry, hs *http.Server, gs *grpc.Server) *kratos.App {
+	opts := []kratos.Option{
+		kratos.Name(name),
+		kratos.Version(Version),
+		kratos.Metadata(map[string]string{}),
+		kratos.Logger(logger),
+		kratos.Server(
+			hs,
+			gs,
+		),
+		kratos.Context(ctx),
+	}
+	if r != nil {
+		opts = append(opts, kratos.Registrar(r))
+	}
+	err := postInitService()
+	if err != nil {
+		panic(err)
+	}
+	return kratos.New(
+		opts...,
+	)
+}
+
+func main() {
+	flag.Parse()
+	ctx := context.Background()
+	logger := log.NewStdLogger(os.Stdout)
+	logger = log.With(logger, "caller", log.Caller(4), "ts", log.DefaultTimestamp)
+	var confSource config.Source
+	if flagconf != "" {
+		confSource = file.NewSource(flagconf)
+	} else {
+		confSource = nacosConfig.NewSource(configSource,
+			namespace,
+			nacosConfig.Group(group),
+			nacosConfig.DataID(name),
+		)
+	}
+
+	bc := new(conf.Bootstrap)
+	c := config.New(
+		config.WithSource(
+			confSource,
+		),
+		config.WithDecoder(func(kv *config.KeyValue, v map[string]interface{}) error {
+			return yaml.Unmarshal(kv.Value, bc)
+		}),
+	)
+	if err := c.Load(); err != nil {
+		panic(err)
+	}
+
+	if bc.Server.Registrar == nil {
+		bc.Server.Registrar = &conf.Registrar{}
+	}
+
+	if bc.Server.Registrar.Namespace == "" {
+		bc.Server.Registrar.Namespace = namespace
+	}
+
+	if bc.Server.Registrar.Group == "" {
+		bc.Server.Registrar.Group = group
+	}
+
+	if bc.Server.Registrar.Endpoint == "" {
+		bc.Server.Registrar.Endpoint = configSource
+	}
+
+	if bc.TraceConf == nil {
+		bc.TraceConf = new(conf.TraceConf)
+	}
+
+	app, cleanup, err := initApp(ctx, bc, logger)
+	if err != nil {
+		panic(err)
+	}
+	defer cleanup()
+	// start and wait for stop signal
+	if err = app.Run(); err != nil {
+		panic(err)
+	}
+}
+
+//postInitService 在data和service初始化的之后的执行的方法
+func postInitService() error {
+	return nil
+}

+ 23 - 0
cmd/server/wire.go

@@ -0,0 +1,23 @@
+//go:build wireinject
+// +build wireinject
+
+// The build tag makes sure the stub is not built in the final build.
+
+package main
+
+import (
+	"context"
+
+	"github.com/go-kratos/kratos-layout/internal/conf"
+	"github.com/go-kratos/kratos-layout/internal/data"
+	"github.com/go-kratos/kratos-layout/internal/server"
+	"github.com/go-kratos/kratos-layout/internal/service"
+	"github.com/go-kratos/kratos/v2"
+	"github.com/go-kratos/kratos/v2/log"
+	"github.com/google/wire"
+)
+
+// initApp init kratos application.
+func initApp(context.Context, *conf.Bootstrap, log.Logger) (*kratos.App, func(), error) {
+	panic(wire.Build(server.ProviderSet, data.ProviderSet, service.ProviderSet, newApp))
+}

+ 40 - 0
cmd/server/wire_gen.go

@@ -0,0 +1,40 @@
+// Code generated by Wire. DO NOT EDIT.
+
+//go:generate go run github.com/google/wire/cmd/wire
+//go:build !wireinject
+// +build !wireinject
+
+package main
+
+import (
+	"context"
+	"github.com/go-kratos/kratos-layout/internal/conf"
+	"github.com/go-kratos/kratos-layout/internal/data"
+	"github.com/go-kratos/kratos-layout/internal/server"
+	"github.com/go-kratos/kratos-layout/internal/service"
+	"github.com/go-kratos/kratos/v2"
+	"github.com/go-kratos/kratos/v2/log"
+)
+
+// Injectors from wire.go:
+
+// initApp init kratos application.
+func initApp(contextContext context.Context, bootstrap *conf.Bootstrap, logger log.Logger) (*kratos.App, func(), error) {
+	registry := server.NewRegistrar(bootstrap)
+	client := data.NewRedis(bootstrap)
+	database, err := data.NewMongo(contextContext, bootstrap)
+	if err != nil {
+		return nil, nil, err
+	}
+	dataData, cleanup, err := data.NewData(bootstrap, client, database, logger, contextContext)
+	if err != nil {
+		return nil, nil, err
+	}
+	baseService := service.NewBaseService(logger, dataData)
+	httpServer := server.NewHTTPServer(bootstrap, logger, baseService)
+	grpcServer := server.NewGRPCServer(bootstrap, logger)
+	app := newApp(contextContext, logger, registry, httpServer, grpcServer)
+	return app, func() {
+		cleanup()
+	}, nil
+}

+ 16 - 0
configs/config.yaml

@@ -0,0 +1,16 @@
+server:
+  http:
+    addr: 0.0.0.0:8000
+    timeout: 1s
+  grpc:
+    addr: 0.0.0.0:9000
+    timeout: 1s
+data:
+  database:
+    driver: mysql
+    source: root:root@tcp(127.0.0.1:3306)/test
+  redis:
+    addr: 127.0.0.1:6379
+    dial_timeout: 0.1s
+    read_timeout: 0.2s
+    write_timeout: 0.2s

+ 3 - 0
generate.go

@@ -0,0 +1,3 @@
+package generate
+
+//go:generate pw proto client .

+ 78 - 0
go.mod

@@ -0,0 +1,78 @@
+module github.com/go-kratos/kratos-layout
+
+go 1.17
+
+replace git.ikuban.com/server/pw-protobuf => ../pw-protobuf
+
+require (
+	git.ikuban.com/server/jl_utils v0.0.0-20220707030554-73a4f27ae284
+	git.ikuban.com/server/kratos-nacos v0.0.3-0.20220608073056-014e9d57d4dc
+	git.ikuban.com/server/kratos-utils v0.0.0-20220608075612-9a9aa543b363
+	git.ikuban.com/server/yaml v0.0.0-20210719032106-8dade6555fff
+	github.com/go-kratos/kratos/v2 v2.3.2-0.20220607143821-123fc1e6c81a
+	github.com/go-redis/redis/v8 v8.11.0
+	github.com/go-sql-driver/mysql v1.6.0
+	github.com/google/wire v0.5.0
+	go.mongodb.org/mongo-driver v1.9.0
+	google.golang.org/grpc v1.47.0
+	google.golang.org/protobuf v1.28.0
+	xorm.io/xorm v1.3.1
+)
+
+require (
+	github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 // indirect
+	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/buger/jsonparser v1.1.1 // indirect
+	github.com/cespare/xxhash/v2 v2.1.1 // indirect
+	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
+	github.com/fsnotify/fsnotify v1.5.4 // indirect
+	github.com/go-errors/errors v1.0.1 // indirect
+	github.com/go-playground/form/v4 v4.2.0 // indirect
+	github.com/go-stack/stack v1.8.0 // indirect
+	github.com/goccy/go-json v0.8.1 // indirect
+	github.com/golang/mock v1.3.1 // indirect
+	github.com/golang/protobuf v1.5.2 // indirect
+	github.com/golang/snappy v0.0.4 // indirect
+	github.com/google/subcommands v1.0.1 // indirect
+	github.com/google/uuid v1.3.0 // indirect
+	github.com/gorilla/mux v1.8.0 // indirect
+	github.com/imdario/mergo v0.3.12 // indirect
+	github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/klauspost/compress v1.13.6 // indirect
+	github.com/kr/text v0.2.0 // indirect
+	github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
+	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/nacos-group/nacos-sdk-go/v2 v2.0.3-bugfix // indirect
+	github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
+	github.com/pkg/errors v0.9.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/prometheus/client_golang v1.11.0 // indirect
+	github.com/prometheus/client_model v0.2.0 // indirect
+	github.com/prometheus/common v0.26.0 // indirect
+	github.com/prometheus/procfs v0.6.0 // indirect
+	github.com/syndtr/goleveldb v1.0.0 // indirect
+	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
+	github.com/xdg-go/scram v1.0.2 // indirect
+	github.com/xdg-go/stringprep v1.0.2 // indirect
+	github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
+	go.uber.org/atomic v1.6.0 // indirect
+	go.uber.org/multierr v1.5.0 // indirect
+	go.uber.org/zap v1.15.0 // indirect
+	golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
+	golang.org/x/mod v0.4.2 // indirect
+	golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect
+	golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 // indirect
+	golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
+	golang.org/x/text v0.3.6 // indirect
+	golang.org/x/tools v0.1.5 // indirect
+	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+	google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect
+	gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
+	gopkg.in/ini.v1 v1.42.0 // indirect
+	gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
+	gopkg.in/yaml.v3 v3.0.0 // indirect
+	xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 // indirect
+)

+ 1 - 0
internal/biz/README.md

@@ -0,0 +1 @@
+# Biz

+ 4 - 0
internal/biz/biz.go

@@ -0,0 +1,4 @@
+package biz
+
+// ProviderSet is biz providers.
+//var ProviderSet = wire.NewSet()

+ 974 - 0
internal/conf/conf.pb.go

@@ -0,0 +1,974 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.26.0-devel
+// 	protoc        v3.15.8
+// source: conf.proto
+
+package conf
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	durationpb "google.golang.org/protobuf/types/known/durationpb"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type Bootstrap struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Server    *Server    `protobuf:"bytes,1,opt,name=server,proto3" json:"server"`
+	Data      *Data      `protobuf:"bytes,2,opt,name=data,proto3" json:"data"`
+	TraceConf *TraceConf `protobuf:"bytes,4,opt,name=traceConf,proto3" json:"traceConf"`
+}
+
+func (x *Bootstrap) Reset() {
+	*x = Bootstrap{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_conf_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Bootstrap) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Bootstrap) ProtoMessage() {}
+
+func (x *Bootstrap) ProtoReflect() protoreflect.Message {
+	mi := &file_conf_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Bootstrap.ProtoReflect.Descriptor instead.
+func (*Bootstrap) Descriptor() ([]byte, []int) {
+	return file_conf_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Bootstrap) GetServer() *Server {
+	if x != nil {
+		return x.Server
+	}
+	return nil
+}
+
+func (x *Bootstrap) GetData() *Data {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
+func (x *Bootstrap) GetTraceConf() *TraceConf {
+	if x != nil {
+		return x.TraceConf
+	}
+	return nil
+}
+
+type TraceConf struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Endpoint string `protobuf:"bytes,1,opt,name=endpoint,proto3" json:"endpoint"`
+	Env      string `protobuf:"bytes,2,opt,name=env,proto3" json:"env"`
+}
+
+func (x *TraceConf) Reset() {
+	*x = TraceConf{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_conf_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *TraceConf) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TraceConf) ProtoMessage() {}
+
+func (x *TraceConf) ProtoReflect() protoreflect.Message {
+	mi := &file_conf_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use TraceConf.ProtoReflect.Descriptor instead.
+func (*TraceConf) Descriptor() ([]byte, []int) {
+	return file_conf_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *TraceConf) GetEndpoint() string {
+	if x != nil {
+		return x.Endpoint
+	}
+	return ""
+}
+
+func (x *TraceConf) GetEnv() string {
+	if x != nil {
+		return x.Env
+	}
+	return ""
+}
+
+type Server struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Http      *HTTP      `protobuf:"bytes,1,opt,name=http,proto3" json:"http"`
+	Grpc      *GRPC      `protobuf:"bytes,2,opt,name=grpc,proto3" json:"grpc"`
+	Registrar *Registrar `protobuf:"bytes,3,opt,name=registrar,proto3" json:"registrar"`
+}
+
+func (x *Server) Reset() {
+	*x = Server{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_conf_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Server) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Server) ProtoMessage() {}
+
+func (x *Server) ProtoReflect() protoreflect.Message {
+	mi := &file_conf_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Server.ProtoReflect.Descriptor instead.
+func (*Server) Descriptor() ([]byte, []int) {
+	return file_conf_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *Server) GetHttp() *HTTP {
+	if x != nil {
+		return x.Http
+	}
+	return nil
+}
+
+func (x *Server) GetGrpc() *GRPC {
+	if x != nil {
+		return x.Grpc
+	}
+	return nil
+}
+
+func (x *Server) GetRegistrar() *Registrar {
+	if x != nil {
+		return x.Registrar
+	}
+	return nil
+}
+
+type HTTP struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Network string               `protobuf:"bytes,1,opt,name=network,proto3" json:"network"`
+	Addr    string               `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr"`
+	Timeout *durationpb.Duration `protobuf:"bytes,3,opt,name=timeout,proto3" json:"timeout"`
+}
+
+func (x *HTTP) Reset() {
+	*x = HTTP{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_conf_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *HTTP) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*HTTP) ProtoMessage() {}
+
+func (x *HTTP) ProtoReflect() protoreflect.Message {
+	mi := &file_conf_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use HTTP.ProtoReflect.Descriptor instead.
+func (*HTTP) Descriptor() ([]byte, []int) {
+	return file_conf_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *HTTP) GetNetwork() string {
+	if x != nil {
+		return x.Network
+	}
+	return ""
+}
+
+func (x *HTTP) GetAddr() string {
+	if x != nil {
+		return x.Addr
+	}
+	return ""
+}
+
+func (x *HTTP) GetTimeout() *durationpb.Duration {
+	if x != nil {
+		return x.Timeout
+	}
+	return nil
+}
+
+type GRPC struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Network string               `protobuf:"bytes,1,opt,name=network,proto3" json:"network"`
+	Addr    string               `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr"`
+	Timeout *durationpb.Duration `protobuf:"bytes,3,opt,name=timeout,proto3" json:"timeout"`
+}
+
+func (x *GRPC) Reset() {
+	*x = GRPC{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_conf_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GRPC) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GRPC) ProtoMessage() {}
+
+func (x *GRPC) ProtoReflect() protoreflect.Message {
+	mi := &file_conf_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GRPC.ProtoReflect.Descriptor instead.
+func (*GRPC) Descriptor() ([]byte, []int) {
+	return file_conf_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *GRPC) GetNetwork() string {
+	if x != nil {
+		return x.Network
+	}
+	return ""
+}
+
+func (x *GRPC) GetAddr() string {
+	if x != nil {
+		return x.Addr
+	}
+	return ""
+}
+
+func (x *GRPC) GetTimeout() *durationpb.Duration {
+	if x != nil {
+		return x.Timeout
+	}
+	return nil
+}
+
+type Registrar struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace"`
+	Group     string `protobuf:"bytes,2,opt,name=group,proto3" json:"group"`
+	Endpoint  string `protobuf:"bytes,3,opt,name=endpoint,proto3" json:"endpoint"`
+}
+
+func (x *Registrar) Reset() {
+	*x = Registrar{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_conf_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Registrar) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Registrar) ProtoMessage() {}
+
+func (x *Registrar) ProtoReflect() protoreflect.Message {
+	mi := &file_conf_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Registrar.ProtoReflect.Descriptor instead.
+func (*Registrar) Descriptor() ([]byte, []int) {
+	return file_conf_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *Registrar) GetNamespace() string {
+	if x != nil {
+		return x.Namespace
+	}
+	return ""
+}
+
+func (x *Registrar) GetGroup() string {
+	if x != nil {
+		return x.Group
+	}
+	return ""
+}
+
+func (x *Registrar) GetEndpoint() string {
+	if x != nil {
+		return x.Endpoint
+	}
+	return ""
+}
+
+type Data struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Database *Database `protobuf:"bytes,1,opt,name=database,proto3" json:"database"`
+	Redis    *Redis    `protobuf:"bytes,2,opt,name=redis,proto3" json:"redis"`
+	Mongo    *Mongo    `protobuf:"bytes,3,opt,name=mongo,proto3" json:"mongo"`
+}
+
+func (x *Data) Reset() {
+	*x = Data{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_conf_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Data) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Data) ProtoMessage() {}
+
+func (x *Data) ProtoReflect() protoreflect.Message {
+	mi := &file_conf_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Data.ProtoReflect.Descriptor instead.
+func (*Data) Descriptor() ([]byte, []int) {
+	return file_conf_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *Data) GetDatabase() *Database {
+	if x != nil {
+		return x.Database
+	}
+	return nil
+}
+
+func (x *Data) GetRedis() *Redis {
+	if x != nil {
+		return x.Redis
+	}
+	return nil
+}
+
+func (x *Data) GetMongo() *Mongo {
+	if x != nil {
+		return x.Mongo
+	}
+	return nil
+}
+
+type Database struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Driver       string `protobuf:"bytes,1,opt,name=driver,proto3" json:"driver"`
+	Source       string `protobuf:"bytes,2,opt,name=source,proto3" json:"source"`
+	MaxIdleConns int32  `protobuf:"varint,3,opt,name=maxIdleConns,proto3" json:"maxIdleConns"`
+	MaxOpenConns int32  `protobuf:"varint,4,opt,name=maxOpenConns,proto3" json:"maxOpenConns"`
+}
+
+func (x *Database) Reset() {
+	*x = Database{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_conf_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Database) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Database) ProtoMessage() {}
+
+func (x *Database) ProtoReflect() protoreflect.Message {
+	mi := &file_conf_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Database.ProtoReflect.Descriptor instead.
+func (*Database) Descriptor() ([]byte, []int) {
+	return file_conf_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *Database) GetDriver() string {
+	if x != nil {
+		return x.Driver
+	}
+	return ""
+}
+
+func (x *Database) GetSource() string {
+	if x != nil {
+		return x.Source
+	}
+	return ""
+}
+
+func (x *Database) GetMaxIdleConns() int32 {
+	if x != nil {
+		return x.MaxIdleConns
+	}
+	return 0
+}
+
+func (x *Database) GetMaxOpenConns() int32 {
+	if x != nil {
+		return x.MaxOpenConns
+	}
+	return 0
+}
+
+type Redis struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Network      string               `protobuf:"bytes,1,opt,name=network,proto3" json:"network"`
+	Addr         string               `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr"`
+	Db           int32                `protobuf:"varint,3,opt,name=db,proto3" json:"db"`
+	DialTimeout  *durationpb.Duration `protobuf:"bytes,4,opt,name=dial_timeout,json=dialTimeout,proto3" json:"dial_timeout"`
+	ReadTimeout  *durationpb.Duration `protobuf:"bytes,5,opt,name=read_timeout,json=readTimeout,proto3" json:"read_timeout"`
+	WriteTimeout *durationpb.Duration `protobuf:"bytes,6,opt,name=write_timeout,json=writeTimeout,proto3" json:"write_timeout"`
+	PoolSize     int32                `protobuf:"varint,7,opt,name=poolSize,proto3" json:"poolSize"`
+	MinIdleConns int32                `protobuf:"varint,8,opt,name=minIdleConns,proto3" json:"minIdleConns"`
+}
+
+func (x *Redis) Reset() {
+	*x = Redis{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_conf_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Redis) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Redis) ProtoMessage() {}
+
+func (x *Redis) ProtoReflect() protoreflect.Message {
+	mi := &file_conf_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Redis.ProtoReflect.Descriptor instead.
+func (*Redis) Descriptor() ([]byte, []int) {
+	return file_conf_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *Redis) GetNetwork() string {
+	if x != nil {
+		return x.Network
+	}
+	return ""
+}
+
+func (x *Redis) GetAddr() string {
+	if x != nil {
+		return x.Addr
+	}
+	return ""
+}
+
+func (x *Redis) GetDb() int32 {
+	if x != nil {
+		return x.Db
+	}
+	return 0
+}
+
+func (x *Redis) GetDialTimeout() *durationpb.Duration {
+	if x != nil {
+		return x.DialTimeout
+	}
+	return nil
+}
+
+func (x *Redis) GetReadTimeout() *durationpb.Duration {
+	if x != nil {
+		return x.ReadTimeout
+	}
+	return nil
+}
+
+func (x *Redis) GetWriteTimeout() *durationpb.Duration {
+	if x != nil {
+		return x.WriteTimeout
+	}
+	return nil
+}
+
+func (x *Redis) GetPoolSize() int32 {
+	if x != nil {
+		return x.PoolSize
+	}
+	return 0
+}
+
+func (x *Redis) GetMinIdleConns() int32 {
+	if x != nil {
+		return x.MinIdleConns
+	}
+	return 0
+}
+
+type Mongo struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uri      string `protobuf:"bytes,1,opt,name=uri,proto3" json:"uri"`
+	Database string `protobuf:"bytes,2,opt,name=database,proto3" json:"database"`
+}
+
+func (x *Mongo) Reset() {
+	*x = Mongo{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_conf_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Mongo) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Mongo) ProtoMessage() {}
+
+func (x *Mongo) ProtoReflect() protoreflect.Message {
+	mi := &file_conf_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Mongo.ProtoReflect.Descriptor instead.
+func (*Mongo) Descriptor() ([]byte, []int) {
+	return file_conf_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *Mongo) GetUri() string {
+	if x != nil {
+		return x.Uri
+	}
+	return ""
+}
+
+func (x *Mongo) GetDatabase() string {
+	if x != nil {
+		return x.Database
+	}
+	return ""
+}
+
+var File_conf_proto protoreflect.FileDescriptor
+
+var file_conf_proto_rawDesc = []byte{
+	0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x6b, 0x72,
+	0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x92, 0x01, 0x0a, 0x09, 0x42, 0x6f, 0x6f,
+	0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e,
+	0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76,
+	0x65, 0x72, 0x12, 0x24, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x10, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x61,
+	0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x33, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x63,
+	0x65, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6b, 0x72,
+	0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f,
+	0x6e, 0x66, 0x52, 0x09, 0x74, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x22, 0x39, 0x0a,
+	0x09, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e,
+	0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e,
+	0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x22, 0x89, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x72,
+	0x76, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x10, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48,
+	0x54, 0x54, 0x50, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x24, 0x0a, 0x04, 0x67, 0x72, 0x70,
+	0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73,
+	0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52, 0x04, 0x67, 0x72, 0x70, 0x63, 0x12,
+	0x33, 0x0a, 0x09, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e,
+	0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x72, 0x52, 0x09, 0x72, 0x65, 0x67, 0x69, 0x73,
+	0x74, 0x72, 0x61, 0x72, 0x22, 0x69, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x12, 0x18, 0x0a, 0x07,
+	0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e,
+	0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69,
+	0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f,
+	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75,
+	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22,
+	0x69, 0x0a, 0x04, 0x47, 0x52, 0x50, 0x43, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f,
+	0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
+	0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x5b, 0x0a, 0x09, 0x52, 0x65,
+	0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73,
+	0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65,
+	0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x65,
+	0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65,
+	0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0x8a, 0x01, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61,
+	0x12, 0x30, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e,
+	0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61,
+	0x73, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x72, 0x65, 0x64, 0x69, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x11, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52,
+	0x65, 0x64, 0x69, 0x73, 0x52, 0x05, 0x72, 0x65, 0x64, 0x69, 0x73, 0x12, 0x27, 0x0a, 0x05, 0x6d,
+	0x6f, 0x6e, 0x67, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6b, 0x72, 0x61,
+	0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x52, 0x05, 0x6d,
+	0x6f, 0x6e, 0x67, 0x6f, 0x22, 0x82, 0x01, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73,
+	0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75,
+	0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63,
+	0x65, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x49, 0x64, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e,
+	0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x49, 0x64, 0x6c, 0x65,
+	0x43, 0x6f, 0x6e, 0x6e, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x4f, 0x70, 0x65, 0x6e,
+	0x43, 0x6f, 0x6e, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x61, 0x78,
+	0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x6e, 0x73, 0x22, 0xc1, 0x02, 0x0a, 0x05, 0x52, 0x65,
+	0x64, 0x69, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a,
+	0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64,
+	0x72, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x64,
+	0x62, 0x12, 0x3c, 0x0a, 0x0c, 0x64, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75,
+	0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x69, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12,
+	0x3c, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18,
+	0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x52, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x3e, 0x0a,
+	0x0d, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x06,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x0c, 0x77, 0x72, 0x69, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x1a, 0x0a,
+	0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x69, 0x6e,
+	0x49, 0x64, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x0c, 0x6d, 0x69, 0x6e, 0x49, 0x64, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x73, 0x22, 0x35, 0x0a,
+	0x05, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61,
+	0x62, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61,
+	0x62, 0x61, 0x73, 0x65, 0x42, 0x37, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
+	0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61,
+	0x74, 0x6f, 0x73, 0x2d, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72,
+	0x6e, 0x61, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x3b, 0x63, 0x6f, 0x6e, 0x66, 0x62, 0x06, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_conf_proto_rawDescOnce sync.Once
+	file_conf_proto_rawDescData = file_conf_proto_rawDesc
+)
+
+func file_conf_proto_rawDescGZIP() []byte {
+	file_conf_proto_rawDescOnce.Do(func() {
+		file_conf_proto_rawDescData = protoimpl.X.CompressGZIP(file_conf_proto_rawDescData)
+	})
+	return file_conf_proto_rawDescData
+}
+
+var file_conf_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
+var file_conf_proto_goTypes = []interface{}{
+	(*Bootstrap)(nil),           // 0: kratos.api.Bootstrap
+	(*TraceConf)(nil),           // 1: kratos.api.TraceConf
+	(*Server)(nil),              // 2: kratos.api.Server
+	(*HTTP)(nil),                // 3: kratos.api.HTTP
+	(*GRPC)(nil),                // 4: kratos.api.GRPC
+	(*Registrar)(nil),           // 5: kratos.api.Registrar
+	(*Data)(nil),                // 6: kratos.api.Data
+	(*Database)(nil),            // 7: kratos.api.Database
+	(*Redis)(nil),               // 8: kratos.api.Redis
+	(*Mongo)(nil),               // 9: kratos.api.Mongo
+	(*durationpb.Duration)(nil), // 10: google.protobuf.Duration
+}
+var file_conf_proto_depIdxs = []int32{
+	2,  // 0: kratos.api.Bootstrap.server:type_name -> kratos.api.Server
+	6,  // 1: kratos.api.Bootstrap.data:type_name -> kratos.api.Data
+	1,  // 2: kratos.api.Bootstrap.traceConf:type_name -> kratos.api.TraceConf
+	3,  // 3: kratos.api.Server.http:type_name -> kratos.api.HTTP
+	4,  // 4: kratos.api.Server.grpc:type_name -> kratos.api.GRPC
+	5,  // 5: kratos.api.Server.registrar:type_name -> kratos.api.Registrar
+	10, // 6: kratos.api.HTTP.timeout:type_name -> google.protobuf.Duration
+	10, // 7: kratos.api.GRPC.timeout:type_name -> google.protobuf.Duration
+	7,  // 8: kratos.api.Data.database:type_name -> kratos.api.Database
+	8,  // 9: kratos.api.Data.redis:type_name -> kratos.api.Redis
+	9,  // 10: kratos.api.Data.mongo:type_name -> kratos.api.Mongo
+	10, // 11: kratos.api.Redis.dial_timeout:type_name -> google.protobuf.Duration
+	10, // 12: kratos.api.Redis.read_timeout:type_name -> google.protobuf.Duration
+	10, // 13: kratos.api.Redis.write_timeout:type_name -> google.protobuf.Duration
+	14, // [14:14] is the sub-list for method output_type
+	14, // [14:14] is the sub-list for method input_type
+	14, // [14:14] is the sub-list for extension type_name
+	14, // [14:14] is the sub-list for extension extendee
+	0,  // [0:14] is the sub-list for field type_name
+}
+
+func init() { file_conf_proto_init() }
+func file_conf_proto_init() {
+	if File_conf_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_conf_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Bootstrap); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_conf_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*TraceConf); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_conf_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Server); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_conf_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*HTTP); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_conf_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GRPC); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_conf_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Registrar); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_conf_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Data); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_conf_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Database); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_conf_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Redis); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_conf_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Mongo); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_conf_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   10,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_conf_proto_goTypes,
+		DependencyIndexes: file_conf_proto_depIdxs,
+		MessageInfos:      file_conf_proto_msgTypes,
+	}.Build()
+	File_conf_proto = out.File
+	file_conf_proto_rawDesc = nil
+	file_conf_proto_goTypes = nil
+	file_conf_proto_depIdxs = nil
+}

+ 67 - 0
internal/conf/conf.proto

@@ -0,0 +1,67 @@
+syntax = "proto3";
+package kratos.api;
+
+option go_package = "github.com/go-kratos/kratos-layout/internal/conf;conf";
+
+import "google/protobuf/duration.proto";
+
+message Bootstrap {
+  Server server = 1;
+  Data data = 2;
+  TraceConf traceConf = 4;
+}
+
+message TraceConf {
+  string endpoint = 1;
+  string env = 2;
+}
+
+message Server {
+  HTTP http = 1;
+  GRPC grpc = 2;
+  Registrar registrar = 3;
+}
+
+message HTTP {
+  string network = 1;
+  string addr = 2;
+  google.protobuf.Duration timeout = 3;
+}
+message GRPC {
+  string network = 1;
+  string addr = 2;
+  google.protobuf.Duration timeout = 3;
+}
+message Registrar {
+  string namespace = 1;
+  string group = 2;
+  string endpoint = 3;
+}
+
+message Data {
+  Database database = 1;
+  Redis redis = 2;
+  Mongo mongo = 3;
+}
+
+message Database {
+  string driver = 1;
+  string source = 2;
+  int32 maxIdleConns = 3;
+  int32 maxOpenConns = 4;
+}
+message Redis {
+  string network = 1;
+  string addr = 2;
+  int32 db = 3;
+  google.protobuf.Duration dial_timeout = 4;
+  google.protobuf.Duration read_timeout = 5;
+  google.protobuf.Duration write_timeout = 6;
+  int32 poolSize = 7;
+  int32 minIdleConns = 8;
+}
+
+message Mongo {
+  string uri = 1;
+  string database = 2;
+}

+ 1 - 0
internal/data/README.md

@@ -0,0 +1 @@
+# Data

+ 94 - 0
internal/data/data.go

@@ -0,0 +1,94 @@
+package data
+
+import (
+	"context"
+	"time"
+
+	"github.com/go-kratos/kratos-layout/internal/conf"
+	"github.com/go-kratos/kratos-layout/internal/data/models"
+	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-redis/redis/v8"
+	"github.com/google/wire"
+	"go.mongodb.org/mongo-driver/mongo"
+	"go.mongodb.org/mongo-driver/mongo/options"
+	"go.mongodb.org/mongo-driver/mongo/readconcern"
+	"go.mongodb.org/mongo-driver/mongo/writeconcern"
+)
+
+// ProviderSet is data providers.
+var ProviderSet = wire.NewSet(NewRedis, NewData, NewMongo)
+
+// Data .
+type Data struct {
+	log *log.Helper
+	rdb *redis.Client
+	*models.Mysql
+	mongodb *mongo.Database
+}
+
+// NewData .
+func NewData(c *conf.Bootstrap, rdb *redis.Client, mongodb *mongo.Database, logger log.Logger, ctx context.Context) (*Data, func(), error) {
+	cleanup := func() {
+	}
+	data := &Data{
+		log: log.NewHelper(log.With(logger, "module", "data/data")),
+	}
+	var err error
+	if c.Data.Database != nil {
+		data.Mysql, err = models.NewMysql(c.Data.Database.Source, logger)
+		if err != nil {
+			return nil, cleanup, err
+		}
+		data.Mysql.XDB.SetMaxIdleConns(int(c.Data.Database.MaxIdleConns))
+		data.Mysql.XDB.SetMaxOpenConns(int(c.Data.Database.MaxOpenConns))
+	}
+	if rdb != nil {
+		data.rdb = rdb
+	}
+	if mongodb != nil {
+		data.mongodb = mongodb
+	}
+	cleanup = func() {
+		if data.XDB != nil {
+			data.XDB.Close()
+		}
+		if data.rdb != nil {
+			data.rdb.Close()
+		}
+		if data.mongodb != nil {
+			data.mongodb.Client().Disconnect(ctx)
+		}
+	}
+	return data, cleanup, nil
+}
+
+func NewRedis(c *conf.Bootstrap) *redis.Client {
+	if c.Data.Redis == nil {
+		return nil
+	}
+	rdb := redis.NewClient(&redis.Options{
+		Addr:         c.Data.Redis.Addr,
+		DB:           int(c.Data.Redis.Db),
+		DialTimeout:  c.Data.Redis.DialTimeout.AsDuration(),
+		WriteTimeout: c.Data.Redis.WriteTimeout.AsDuration(),
+		ReadTimeout:  c.Data.Redis.ReadTimeout.AsDuration(),
+		PoolSize:     int(c.Data.Redis.PoolSize),
+		MinIdleConns: int(c.Data.Redis.MinIdleConns),
+	})
+	return rdb
+}
+
+func NewMongo(ctx context.Context, c *conf.Bootstrap) (*mongo.Database, error) {
+	if c.Data.Mongo == nil {
+		return nil, nil
+	}
+	clientOptions := options.Client().ApplyURI(c.Data.Mongo.Uri).SetSocketTimeout(time.Second * 30).
+		SetReadConcern(readconcern.Majority()).SetWriteConcern(writeconcern.New(writeconcern.WMajority(), writeconcern.J(true)))
+	client, err := mongo.Connect(ctx, clientOptions)
+
+	if err != nil {
+		return nil, err
+	}
+	database := client.Database(c.Data.Mongo.Database)
+	return database, nil
+}

+ 33 - 0
internal/data/models/init.go

@@ -0,0 +1,33 @@
+package models
+
+import (
+	"database/sql"
+
+	"xorm.io/xorm/names"
+
+	"github.com/go-kratos/kratos/v2/log"
+
+	"xorm.io/xorm"
+
+	_ "github.com/go-sql-driver/mysql"
+)
+
+type Mysql struct {
+	XDB *xorm.Engine
+	DB  *sql.DB
+	log *log.Helper
+}
+
+func NewMysql(source string, logger log.Logger) (*Mysql, error) {
+	orm, err := xorm.NewEngine("mysql", source)
+	if err != nil {
+		return nil, err
+	}
+	orm.SetMapper(names.LintGonicMapper)
+	m := &Mysql{
+		XDB: orm,
+		DB:  orm.DB().DB,
+		log: log.NewHelper(log.With(logger, "module", "models/init")),
+	}
+	return m, nil
+}

+ 42 - 0
internal/server/grpc.go

@@ -0,0 +1,42 @@
+package server
+
+import (
+	"git.ikuban.com/server/jl_utils/server"
+	"git.ikuban.com/server/kratos-utils/http/middleware/logging"
+	"github.com/go-kratos/kratos-layout/internal/conf"
+	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-kratos/kratos/v2/middleware"
+	"github.com/go-kratos/kratos/v2/middleware/recovery"
+	"github.com/go-kratos/kratos/v2/transport/grpc"
+	grpc2 "google.golang.org/grpc"
+)
+
+// NewGRPCServer new a gRPC server.
+func NewGRPCServer(c *conf.Bootstrap, logger log.Logger) *grpc.Server {
+	chain := []middleware.Middleware{
+		recovery.Recovery(),
+		logging.Server(logger),
+		server.GrpcValue,
+	}
+
+	var opts = []grpc.ServerOption{
+		grpc.Middleware(
+			chain...,
+		),
+		grpc.Options(
+			grpc2.MaxRecvMsgSize(10000000000),
+			grpc2.MaxSendMsgSize(10000000000),
+		),
+	}
+	if c.Server.Grpc.Network != "" {
+		opts = append(opts, grpc.Network(c.Server.Grpc.Network))
+	}
+	if c.Server.Grpc.Addr != "" {
+		opts = append(opts, grpc.Address(c.Server.Grpc.Addr))
+	}
+	if c.Server.Grpc.Timeout != nil {
+		opts = append(opts, grpc.Timeout(c.Server.Grpc.Timeout.AsDuration()))
+	}
+	srv := grpc.NewServer(opts...)
+	return srv
+}

+ 43 - 0
internal/server/http.go

@@ -0,0 +1,43 @@
+package server
+
+import (
+	http2 "net/http"
+
+	"git.ikuban.com/server/kratos-utils/http/middleware/logging"
+	"github.com/go-kratos/kratos-layout/internal/conf"
+	"github.com/go-kratos/kratos-layout/internal/service"
+	"github.com/go-kratos/kratos/v2/log"
+	"github.com/go-kratos/kratos/v2/middleware"
+	"github.com/go-kratos/kratos/v2/middleware/recovery"
+	"github.com/go-kratos/kratos/v2/transport/http"
+)
+
+// NewHTTPServer new a HTTP server.
+func NewHTTPServer(c *conf.Bootstrap, logger log.Logger, service *service.BaseService) *http.Server {
+	var opts = []http.ServerOption{}
+	if c.Server.Http.Network != "" {
+		opts = append(opts, http.Network(c.Server.Http.Network))
+	}
+	if c.Server.Http.Addr != "" {
+		opts = append(opts, http.Address(c.Server.Http.Addr))
+	}
+	if c.Server.Http.Timeout != nil {
+		opts = append(opts, http.Timeout(c.Server.Http.Timeout.AsDuration()))
+	}
+
+	chain := []middleware.Middleware{
+		recovery.Recovery(),
+		logging.Server(logger),
+	}
+
+	opts = append(opts, http.Middleware(
+		middleware.Chain(chain...),
+	))
+
+	srv := http.NewServer(opts...)
+
+	srv.HandleFunc("/ping", func(w http2.ResponseWriter, r *http2.Request) {
+		w.Write([]byte(service.Ping()))
+	})
+	return srv
+}

+ 17 - 0
internal/server/registrar.go

@@ -0,0 +1,17 @@
+package server
+
+import (
+	"git.ikuban.com/server/kratos-nacos/registry"
+	"github.com/go-kratos/kratos-layout/internal/conf"
+)
+
+func NewRegistrar(c *conf.Bootstrap) *registry.Registry {
+	if c.Server.Registrar.Group != "" {
+		r, err := registry.New(c.Server.Registrar.Endpoint, c.Server.Registrar.Namespace, registry.Group(c.Server.Registrar.Group))
+		if err != nil {
+			panic(err)
+		}
+		return r
+	}
+	return nil
+}

+ 8 - 0
internal/server/server.go

@@ -0,0 +1,8 @@
+package server
+
+import (
+	"github.com/google/wire"
+)
+
+// ProviderSet is server providers.
+var ProviderSet = wire.NewSet(NewHTTPServer, NewGRPCServer, NewRegistrar)

+ 1 - 0
internal/service/README.md

@@ -0,0 +1 @@
+# Service

+ 22 - 0
internal/service/base_service.go

@@ -0,0 +1,22 @@
+package service
+
+import (
+	"github.com/go-kratos/kratos-layout/internal/data"
+	"github.com/go-kratos/kratos/v2/log"
+)
+
+type BaseService struct {
+	log  *log.Helper
+	data *data.Data
+}
+
+func NewBaseService(logger log.Logger, data *data.Data) *BaseService {
+	return &BaseService{
+		log:  log.NewHelper(log.With(logger, "module", "service/base")),
+		data: data,
+	}
+}
+
+func (this *BaseService) Ping() string {
+	return "ok"
+}

+ 6 - 0
internal/service/service.go

@@ -0,0 +1,6 @@
+package service
+
+import "github.com/google/wire"
+
+// ProviderSet is service providers.
+var ProviderSet = wire.NewSet(NewBaseService)

+ 1 - 0
start.sh

@@ -0,0 +1 @@
+./bin/server -conf ./configs