boot.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package boot
  2. import (
  3. "errors"
  4. "fmt"
  5. "sync"
  6. "git.shuncheng.lu/bigthing/gocommon/pkg/cache/localcache"
  7. "git.shuncheng.lu/bigthing/gocommon/pkg/cache/redis"
  8. "git.shuncheng.lu/bigthing/gocommon/pkg/conf"
  9. "git.shuncheng.lu/bigthing/gocommon/pkg/database/db"
  10. "git.shuncheng.lu/bigthing/gocommon/pkg/database/elastic"
  11. "git.shuncheng.lu/bigthing/gocommon/pkg/database/multi_db"
  12. "git.shuncheng.lu/bigthing/gocommon/pkg/internal/util"
  13. "git.shuncheng.lu/bigthing/gocommon/pkg/logger"
  14. "git.shuncheng.lu/bigthing/gocommon/pkg/mq/kafka"
  15. "git.shuncheng.lu/bigthing/gocommon/pkg/mq/rocketmq"
  16. "git.shuncheng.lu/bigthing/gocommon/pkg/net/nacos"
  17. "git.shuncheng.lu/bigthing/gocommon/pkg/net/pprof"
  18. "git.shuncheng.lu/bigthing/gocommon/pkg/net/qconf"
  19. "git.shuncheng.lu/bigthing/gocommon/pkg/trace"
  20. )
  21. // go get golang.org/x/tools/cmd/stringer
  22. //go:generate stringer -type=ResourceType
  23. type ResourceType uint8
  24. type ConfigResource func(config *ResourceConfig)
  25. // 每变更一次类型都需要执行一次 go:generate
  26. const (
  27. Config ResourceType = iota + 1
  28. Logger
  29. Qconf
  30. DB
  31. MultiDB
  32. Redis
  33. Trace
  34. KafkaProducer
  35. KafkaConsumer
  36. LocalCache
  37. NacosDiscover // 发现中心 nacos
  38. NacosRegister // 注册中心 nacos
  39. Elastic
  40. Pprof
  41. RocketMQProducer
  42. RocketMQConsumer
  43. )
  44. type Resource interface {
  45. Init() error
  46. Start() error
  47. Config() ResourceConfig
  48. }
  49. type initFunc func() error
  50. type startFunc func() error
  51. /**
  52. 注册init 函数
  53. */
  54. var (
  55. resourceMap = map[ResourceType]Resource{
  56. Config: newResource(conf.Init, nil),
  57. Logger: newResource(logger.Init, nil),
  58. DB: newResource(db.Init, nil),
  59. MultiDB: newResource(multi_db.Init, nil),
  60. Qconf: newResource(qconf.InitQconf, nil),
  61. Redis: newResource(redis.Init, nil),
  62. Trace: newResource(trace.Init, nil),
  63. KafkaProducer: newResource(kafka.InitProducer, nil),
  64. KafkaConsumer: newResource(kafka.InitConsumer, nil),
  65. LocalCache: newResource(localcache.Init, localcache.Start),
  66. Elastic: newResource(elastic.Init, nil),
  67. NacosDiscover: newResource(nacos.InitNacosDiscoverClient, nil),
  68. NacosRegister: newResource(nacos.InitNacosRegisterClientV2, nacos.StartNacosRegisterClientV2),
  69. Pprof: newResource(pprof.Init, nil),
  70. RocketMQProducer: newResource(rocketmq.InitProducer, nil),
  71. RocketMQConsumer: newResource(rocketmq.InitConsumer, rocketmq.StartConsumer),
  72. }
  73. // 锁,防止重复init
  74. initLock sync.Mutex
  75. initializedMap = map[ResourceType]Resource{}
  76. startedMap = map[ResourceType]Resource{}
  77. // 必须加载的资源
  78. mustInitResource = []ResourceType{Config, Logger}
  79. )
  80. // 允许多次init
  81. func Init(resource ...ResourceType) {
  82. if resource == nil || len(resource) == 0 {
  83. resource = mustInitResource // 这俩是必须初始化的
  84. }
  85. // 排序和append_need_load_resource 加载资源的顺序
  86. resource = sortResourceType(handlerResourceType(resource))
  87. //
  88. initLock.Lock()
  89. defer initLock.Unlock()
  90. // 遍历初始化
  91. for _, elem := range resource {
  92. resource, isExist := resourceMap[elem]
  93. // 存在
  94. if isExist {
  95. // 是否已经启动过
  96. if _, isInit := initializedMap[elem]; isInit {
  97. continue
  98. }
  99. util.Infof("[%s] start init...", elem)
  100. err := resource.Init()
  101. if err != nil {
  102. util.Painc(errors.New(fmt.Sprintf("init %s find err: %s", elem, err)))
  103. }
  104. initializedMap[elem] = resource
  105. util.Infof("[%s] end init...", elem)
  106. }
  107. }
  108. }
  109. func Start() {
  110. initLock.Lock()
  111. defer initLock.Unlock()
  112. for _type, elem := range initializedMap {
  113. if _, isStart := startedMap[_type]; isStart {
  114. continue
  115. }
  116. if err := elem.Start(); err != nil {
  117. util.Painc(err)
  118. }
  119. startedMap[_type] = elem
  120. }
  121. // 写进程pid
  122. util.WritePid()
  123. }
  124. func handlerResourceType(resource []ResourceType) []ResourceType {
  125. if resource == nil || len(resource) == 0 {
  126. return mustInitResource
  127. }
  128. resource = append(resource, mustInitResource...)
  129. filterMap := make(map[ResourceType]interface{}, 0)
  130. for _, elem := range resource {
  131. filterMap[elem] = nil
  132. }
  133. newResource := make([]ResourceType, 0)
  134. for key, _ := range filterMap {
  135. newResource = append(newResource, key)
  136. }
  137. return newResource
  138. }