You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
592 lines
12 KiB
592 lines
12 KiB
package main
|
|
|
|
const (
|
|
_tplAppToml = `
|
|
# This is a TOML document. Boom~
|
|
`
|
|
|
|
_tplMySQLToml = `
|
|
[demo]
|
|
addr = "127.0.0.1:3306"
|
|
dsn = "{user}:{password}@tcp(127.0.0.1:3306)/{database}?timeout=1s&readTimeout=1s&writeTimeout=1s&parseTime=true&loc=Local&charset=utf8mb4,utf8"
|
|
readDSN = ["{user}:{password}@tcp(127.0.0.2:3306)/{database}?timeout=1s&readTimeout=1s&writeTimeout=1s&parseTime=true&loc=Local&charset=utf8mb4,utf8","{user}:{password}@tcp(127.0.0.3:3306)/{database}?timeout=1s&readTimeout=1s&writeTimeout=1s&parseTime=true&loc=Local&charset=utf8,utf8mb4"]
|
|
active = 20
|
|
idle = 10
|
|
idleTimeout ="4h"
|
|
queryTimeout = "200ms"
|
|
execTimeout = "300ms"
|
|
tranTimeout = "400ms"
|
|
`
|
|
_tplMCToml = `
|
|
demoExpire = "24h"
|
|
|
|
[demo]
|
|
name = "{{.Name}}"
|
|
proto = "tcp"
|
|
addr = "127.0.0.1:11211"
|
|
active = 50
|
|
idle = 10
|
|
dialTimeout = "100ms"
|
|
readTimeout = "200ms"
|
|
writeTimeout = "300ms"
|
|
idleTimeout = "80s"
|
|
`
|
|
_tplRedisToml = `
|
|
demoExpire = "24h"
|
|
|
|
[demo]
|
|
name = "{{.Name}}"
|
|
proto = "tcp"
|
|
addr = "127.0.0.1:6389"
|
|
idle = 10
|
|
active = 10
|
|
dialTimeout = "1s"
|
|
readTimeout = "1s"
|
|
writeTimeout = "1s"
|
|
idleTimeout = "10s"
|
|
`
|
|
|
|
_tplHTTPToml = `
|
|
[server]
|
|
addr = "0.0.0.0:8000"
|
|
timeout = "1s"
|
|
`
|
|
_tplGRPCToml = `
|
|
[server]
|
|
addr = "0.0.0.0:9000"
|
|
timeout = "1s"
|
|
`
|
|
|
|
_tplChangeLog = `## {{.Name}}
|
|
|
|
### v1.0.0
|
|
1. 上线功能xxx
|
|
`
|
|
_tplMain = `package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
"{{.ModuleName}}/internal/server/http"
|
|
"{{.ModuleName}}/internal/service"
|
|
"github.com/bilibili/kratos/pkg/conf/paladin"
|
|
"github.com/bilibili/kratos/pkg/log"
|
|
|
|
_ "go.uber.org/automaxprocs"
|
|
)
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
if err := paladin.Init(); err != nil {
|
|
panic(err)
|
|
}
|
|
log.Init(nil) // debug flag: log.dir={path}
|
|
defer log.Close()
|
|
log.Info("{{.Name}} start")
|
|
svc := service.New()
|
|
httpSrv := http.New(svc)
|
|
c := make(chan os.Signal, 1)
|
|
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
|
for {
|
|
s := <-c
|
|
log.Info("get a signal %s", s.String())
|
|
switch s {
|
|
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
|
ctx, cancel := context.WithTimeout(context.Background(), 35*time.Second)
|
|
if err := httpSrv.Shutdown(ctx); err != nil {
|
|
log.Error("httpSrv.Shutdown error(%v)", err)
|
|
}
|
|
log.Info("{{.Name}} exit")
|
|
svc.Close()
|
|
cancel()
|
|
time.Sleep(time.Second)
|
|
return
|
|
case syscall.SIGHUP:
|
|
default:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
_tplGRPCMain = `package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
"{{.ModuleName}}/internal/server/grpc"
|
|
"{{.ModuleName}}/internal/server/http"
|
|
"{{.ModuleName}}/internal/service"
|
|
"github.com/bilibili/kratos/pkg/conf/paladin"
|
|
"github.com/bilibili/kratos/pkg/log"
|
|
|
|
_ "go.uber.org/automaxprocs"
|
|
)
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
if err := paladin.Init(); err != nil {
|
|
panic(err)
|
|
}
|
|
log.Init(nil) // debug flag: log.dir={path}
|
|
defer log.Close()
|
|
log.Info("{{.Name}} start")
|
|
svc := service.New()
|
|
grpcSrv := grpc.New(svc)
|
|
httpSrv := http.New(svc)
|
|
c := make(chan os.Signal, 1)
|
|
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
|
for s := range c {
|
|
log.Info("get a signal %s", s.String())
|
|
switch s {
|
|
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
|
ctx, cancel := context.WithTimeout(context.Background(), 35*time.Second)
|
|
if err := grpcSrv.Shutdown(ctx); err != nil {
|
|
log.Error("grpcSrv.Shutdown error(%v)", err)
|
|
}
|
|
if err := httpSrv.Shutdown(ctx); err != nil {
|
|
log.Error("httpSrv.Shutdown error(%v)", err)
|
|
}
|
|
log.Info("{{.Name}} exit")
|
|
svc.Close()
|
|
cancel()
|
|
time.Sleep(time.Second)
|
|
return
|
|
case syscall.SIGHUP:
|
|
default:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
_tplContributors = `# Owner
|
|
{{.Owner}}
|
|
|
|
# Author
|
|
|
|
# Reviewer
|
|
`
|
|
|
|
_tplDao = `package dao
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/bilibili/kratos/pkg/cache/memcache"
|
|
"github.com/bilibili/kratos/pkg/cache/redis"
|
|
"github.com/bilibili/kratos/pkg/conf/paladin"
|
|
"github.com/bilibili/kratos/pkg/database/sql"
|
|
"github.com/bilibili/kratos/pkg/log"
|
|
xtime "github.com/bilibili/kratos/pkg/time"
|
|
)
|
|
|
|
// Dao dao interface
|
|
type Dao interface {
|
|
Close()
|
|
Ping(ctx context.Context) (err error)
|
|
}
|
|
|
|
// dao dao.
|
|
type dao struct {
|
|
db *sql.DB
|
|
redis *redis.Pool
|
|
redisExpire int32
|
|
mc *memcache.Memcache
|
|
mcExpire int32
|
|
}
|
|
|
|
func checkErr(err error) {
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// New new a dao and return.
|
|
func New() (Dao) {
|
|
var (
|
|
dc struct {
|
|
Demo *sql.Config
|
|
}
|
|
rc struct {
|
|
Demo *redis.Config
|
|
DemoExpire xtime.Duration
|
|
}
|
|
mc struct {
|
|
Demo *memcache.Config
|
|
DemoExpire xtime.Duration
|
|
}
|
|
)
|
|
checkErr(paladin.Get("mysql.toml").UnmarshalTOML(&dc))
|
|
checkErr(paladin.Get("redis.toml").UnmarshalTOML(&rc))
|
|
checkErr(paladin.Get("memcache.toml").UnmarshalTOML(&mc))
|
|
return &dao{
|
|
// mysql
|
|
db: sql.NewMySQL(dc.Demo),
|
|
// redis
|
|
redis: redis.NewPool(rc.Demo),
|
|
redisExpire: int32(time.Duration(rc.DemoExpire) / time.Second),
|
|
// memcache
|
|
mc: memcache.New(mc.Demo),
|
|
mcExpire: int32(time.Duration(mc.DemoExpire) / time.Second),
|
|
}
|
|
}
|
|
|
|
// Close close the resource.
|
|
func (d *dao) Close() {
|
|
d.mc.Close()
|
|
d.redis.Close()
|
|
d.db.Close()
|
|
}
|
|
|
|
// Ping ping the resource.
|
|
func (d *dao) Ping(ctx context.Context) (err error) {
|
|
if err = d.pingMC(ctx); err != nil {
|
|
return
|
|
}
|
|
if err = d.pingRedis(ctx); err != nil {
|
|
return
|
|
}
|
|
return d.db.Ping(ctx)
|
|
}
|
|
|
|
func (d *dao) pingMC(ctx context.Context) (err error) {
|
|
if err = d.mc.Set(ctx, &memcache.Item{Key: "ping", Value: []byte("pong"), Expiration: 0}); err != nil {
|
|
log.Error("conn.Set(PING) error(%v)", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (d *dao) pingRedis(ctx context.Context) (err error) {
|
|
conn := d.redis.Get(ctx)
|
|
defer conn.Close()
|
|
if _, err = conn.Do("SET", "ping", "pong"); err != nil {
|
|
log.Error("conn.Set(PING) error(%v)", err)
|
|
}
|
|
return
|
|
}
|
|
`
|
|
_tplReadme = `# {{.Name}}
|
|
|
|
## 项目简介
|
|
1.
|
|
`
|
|
_tplService = `package service
|
|
|
|
import (
|
|
"context"
|
|
|
|
"{{.ModuleName}}/internal/dao"
|
|
"github.com/bilibili/kratos/pkg/conf/paladin"
|
|
)
|
|
|
|
// Service service.
|
|
type Service struct {
|
|
ac *paladin.Map
|
|
dao dao.Dao
|
|
}
|
|
|
|
// New new a service and return.
|
|
func New() (s *Service) {
|
|
var ac = new(paladin.TOML)
|
|
if err := paladin.Watch("application.toml", ac); err != nil {
|
|
panic(err)
|
|
}
|
|
s = &Service{
|
|
ac: ac,
|
|
dao: dao.New(),
|
|
}
|
|
return s
|
|
}
|
|
|
|
// Ping ping the resource.
|
|
func (s *Service) Ping(ctx context.Context) (err error) {
|
|
return s.dao.Ping(ctx)
|
|
}
|
|
|
|
// Close close the resource.
|
|
func (s *Service) Close() {
|
|
s.dao.Close()
|
|
}
|
|
`
|
|
|
|
_tplGPRCService = `package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
pb "{{.ModuleName}}/api"
|
|
"{{.ModuleName}}/internal/dao"
|
|
"github.com/bilibili/kratos/pkg/conf/paladin"
|
|
|
|
"github.com/golang/protobuf/ptypes/empty"
|
|
)
|
|
|
|
// Service service.
|
|
type Service struct {
|
|
ac *paladin.Map
|
|
dao dao.Dao
|
|
}
|
|
|
|
// New new a service and return.
|
|
func New() (s *Service) {
|
|
var ac = new(paladin.TOML)
|
|
if err := paladin.Watch("application.toml", ac); err != nil {
|
|
panic(err)
|
|
}
|
|
s = &Service{
|
|
ac: ac,
|
|
dao: dao.New(),
|
|
}
|
|
return s
|
|
}
|
|
|
|
// SayHello grpc demo func.
|
|
func (s *Service) SayHello(ctx context.Context, req *pb.HelloReq) (reply *empty.Empty, err error) {
|
|
reply = new(empty.Empty)
|
|
fmt.Printf("hello %s", req.Name)
|
|
return
|
|
}
|
|
|
|
// SayHelloURL bm demo func.
|
|
func (s *Service) SayHelloURL(ctx context.Context, req *pb.HelloReq) (reply *pb.HelloResp, err error) {
|
|
reply = &pb.HelloResp{
|
|
Content: "hello " + req.Name,
|
|
}
|
|
fmt.Printf("hello url %s", req.Name)
|
|
return
|
|
}
|
|
|
|
// Ping ping the resource.
|
|
func (s *Service) Ping(ctx context.Context) (err error) {
|
|
return s.dao.Ping(ctx)
|
|
}
|
|
|
|
// Close close the resource.
|
|
func (s *Service) Close() {
|
|
s.dao.Close()
|
|
}
|
|
`
|
|
_tplHTTPServer = `package http
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"{{.ModuleName}}/internal/model"
|
|
"{{.ModuleName}}/internal/service"
|
|
|
|
"github.com/bilibili/kratos/pkg/conf/paladin"
|
|
"github.com/bilibili/kratos/pkg/log"
|
|
bm "github.com/bilibili/kratos/pkg/net/http/blademaster"
|
|
)
|
|
|
|
var (
|
|
svc *service.Service
|
|
)
|
|
|
|
// New new a bm server.
|
|
func New(s *service.Service) (engine *bm.Engine) {
|
|
var (
|
|
hc struct {
|
|
Server *bm.ServerConfig
|
|
}
|
|
)
|
|
if err := paladin.Get("http.toml").UnmarshalTOML(&hc); err != nil {
|
|
if err != paladin.ErrNotExist {
|
|
panic(err)
|
|
}
|
|
}
|
|
svc = s
|
|
engine = bm.DefaultServer(hc.Server)
|
|
initRouter(engine)
|
|
if err := engine.Start(); err != nil {
|
|
panic(err)
|
|
}
|
|
return
|
|
}
|
|
|
|
func initRouter(e *bm.Engine) {
|
|
e.Ping(ping)
|
|
g := e.Group("/{{.Name}}")
|
|
{
|
|
g.GET("/start", howToStart)
|
|
}
|
|
}
|
|
|
|
func ping(ctx *bm.Context) {
|
|
if err := svc.Ping(ctx); err != nil {
|
|
log.Error("ping error(%v)", err)
|
|
ctx.AbortWithStatus(http.StatusServiceUnavailable)
|
|
}
|
|
}
|
|
|
|
// example for http request handler.
|
|
func howToStart(c *bm.Context) {
|
|
k := &model.Kratos{
|
|
Hello: "Golang 大法好 !!!",
|
|
}
|
|
c.JSON(k, nil)
|
|
}
|
|
`
|
|
_tplPBHTTPServer = `package http
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
pb "{{.ModuleName}}/api"
|
|
"{{.ModuleName}}/internal/model"
|
|
"{{.ModuleName}}/internal/service"
|
|
|
|
"github.com/bilibili/kratos/pkg/conf/paladin"
|
|
"github.com/bilibili/kratos/pkg/log"
|
|
bm "github.com/bilibili/kratos/pkg/net/http/blademaster"
|
|
)
|
|
|
|
var (
|
|
svc *service.Service
|
|
)
|
|
|
|
// New new a bm server.
|
|
func New(s *service.Service) (engine *bm.Engine) {
|
|
var (
|
|
hc struct {
|
|
Server *bm.ServerConfig
|
|
}
|
|
)
|
|
if err := paladin.Get("http.toml").UnmarshalTOML(&hc); err != nil {
|
|
if err != paladin.ErrNotExist {
|
|
panic(err)
|
|
}
|
|
}
|
|
svc = s
|
|
engine = bm.DefaultServer(hc.Server)
|
|
pb.RegisterDemoBMServer(engine, svc)
|
|
initRouter(engine)
|
|
if err := engine.Start(); err != nil {
|
|
panic(err)
|
|
}
|
|
return
|
|
}
|
|
|
|
func initRouter(e *bm.Engine) {
|
|
e.Ping(ping)
|
|
g := e.Group("/{{.Name}}")
|
|
{
|
|
g.GET("/start", howToStart)
|
|
}
|
|
}
|
|
|
|
func ping(ctx *bm.Context) {
|
|
if err := svc.Ping(ctx); err != nil {
|
|
log.Error("ping error(%v)", err)
|
|
ctx.AbortWithStatus(http.StatusServiceUnavailable)
|
|
}
|
|
}
|
|
|
|
// example for http request handler.
|
|
func howToStart(c *bm.Context) {
|
|
k := &model.Kratos{
|
|
Hello: "Golang 大法好 !!!",
|
|
}
|
|
c.JSON(k, nil)
|
|
}
|
|
|
|
`
|
|
|
|
_tplAPIProto = `// 定义项目 API 的 proto 文件 可以同时描述 gRPC 和 HTTP API
|
|
// protobuf 文件参考:
|
|
// - https://developers.google.com/protocol-buffers/
|
|
syntax = "proto3";
|
|
|
|
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
|
import "google/protobuf/empty.proto";
|
|
import "google/api/annotations.proto";
|
|
|
|
// package 命名使用 {appid}.{version} 的方式, version 形如 v1, v2 ..
|
|
package demo.service.v1;
|
|
|
|
// NOTE: 最后请删除这些无用的注释 (゜-゜)つロ
|
|
|
|
option go_package = "api";
|
|
option (gogoproto.goproto_getters_all) = false;
|
|
|
|
service Demo {
|
|
rpc SayHello (HelloReq) returns (.google.protobuf.Empty);
|
|
rpc SayHelloURL(HelloReq) returns (HelloResp) {
|
|
option (google.api.http) = {
|
|
get:"/{{.Name}}/say_hello"
|
|
};
|
|
};
|
|
}
|
|
|
|
message HelloReq {
|
|
string name = 1 [(gogoproto.moretags)='form:"name" validate:"required"'];
|
|
}
|
|
|
|
message HelloResp {
|
|
string Content = 1 [(gogoproto.jsontag) = 'content'];
|
|
}
|
|
`
|
|
_tplModel = `package model
|
|
|
|
// Kratos hello kratos.
|
|
type Kratos struct {
|
|
Hello string
|
|
}`
|
|
_tplGoMod = `module {{.ModuleName}}
|
|
|
|
go 1.12
|
|
|
|
require (
|
|
github.com/bilibili/kratos master
|
|
github.com/gogo/protobuf v1.2.1
|
|
github.com/golang/protobuf v1.3.2
|
|
golang.org/x/net v0.0.0-20190628185345-da137c7871d7
|
|
google.golang.org/grpc v1.22.0
|
|
)
|
|
`
|
|
_tplGRPCServer = `package grpc
|
|
|
|
import (
|
|
pb "{{.ModuleName}}/api"
|
|
"{{.ModuleName}}/internal/service"
|
|
"github.com/bilibili/kratos/pkg/conf/paladin"
|
|
"github.com/bilibili/kratos/pkg/net/rpc/warden"
|
|
)
|
|
|
|
// New new a grpc server.
|
|
func New(svc *service.Service) *warden.Server {
|
|
var rc struct {
|
|
Server *warden.ServerConfig
|
|
}
|
|
if err := paladin.Get("grpc.toml").UnmarshalTOML(&rc); err != nil {
|
|
if err != paladin.ErrNotExist {
|
|
panic(err)
|
|
}
|
|
}
|
|
ws := warden.NewServer(rc.Server)
|
|
pb.RegisterDemoServer(ws.Server(), svc)
|
|
ws, err := ws.Start()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return ws
|
|
}
|
|
`
|
|
_tplGogen = `package api
|
|
|
|
//go:generate kratos tool protoc --swagger --grpc --bm api.proto
|
|
`
|
|
)
|
|
|