common.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package common_db
  2. import (
  3. _ "database/sql"
  4. "fmt"
  5. "os"
  6. "strconv"
  7. "time"
  8. "git.shuncheng.lu/bigthing/gocommon/pkg/conf"
  9. . "git.shuncheng.lu/bigthing/gocommon/pkg/internal/util"
  10. _ "github.com/go-sql-driver/mysql"
  11. "xorm.io/xorm"
  12. "xorm.io/xorm/log"
  13. )
  14. func getMysqlConfig(key string, assertNil SetAndAssertNil) (map[string]string, error) {
  15. var (
  16. mysqlConfig = make(map[string]string)
  17. )
  18. if err := assertNil(mysqlConfig, key, "dbname", ""); err != nil {
  19. return nil, err
  20. }
  21. if err := assertNil(mysqlConfig, key, "host", ""); err != nil {
  22. return nil, err
  23. }
  24. if err := assertNil(mysqlConfig, key, "port", ""); err != nil {
  25. return nil, err
  26. }
  27. if err := assertNil(mysqlConfig, key, "user", ""); err != nil {
  28. return nil, err
  29. }
  30. if err := assertNil(mysqlConfig, key, "password", ""); err != nil {
  31. return nil, err
  32. }
  33. if err := assertNil(mysqlConfig, key, "charset", "utf8"); err != nil {
  34. return nil, err
  35. }
  36. if err := assertNil(mysqlConfig, key, "slave_dbname", ""); err != nil {
  37. return nil, err
  38. }
  39. if err := assertNil(mysqlConfig, key, "slave_host", ""); err != nil {
  40. return nil, err
  41. }
  42. if err := assertNil(mysqlConfig, key, "slave_port", ""); err != nil {
  43. return nil, err
  44. }
  45. if err := assertNil(mysqlConfig, key, "slave_user", ""); err != nil {
  46. return nil, err
  47. }
  48. if err := assertNil(mysqlConfig, key, "slave_password", ""); err != nil {
  49. return nil, err
  50. }
  51. if err := assertNil(mysqlConfig, key, "slave_charset", "utf8"); err != nil {
  52. return nil, err
  53. }
  54. if err := assertNil(mysqlConfig, key, "read_timeout", "5"); err != nil {
  55. return nil, err
  56. }
  57. if err := assertNil(mysqlConfig, key, "write_timeout", "5"); err != nil {
  58. return nil, err
  59. }
  60. if err := assertNil(mysqlConfig, key, "timeout", "10"); err != nil {
  61. return nil, err
  62. }
  63. if err := assertNil(mysqlConfig, key, "max_idle", "10"); err != nil {
  64. return nil, err
  65. }
  66. if err := assertNil(mysqlConfig, key, "max_conn", "100"); err != nil {
  67. return nil, err
  68. }
  69. if err := assertNil(mysqlConfig, key, "conn_max_life_time", "-1"); err != nil {
  70. return nil, err
  71. }
  72. if err := assertNil(mysqlConfig, key, "log_level", strconv.FormatInt(int64(log.LOG_WARNING), 10)); err != nil {
  73. return nil, err
  74. }
  75. if err := assertNil(mysqlConfig, key, "log_file", ""); err != nil {
  76. return nil, err
  77. }
  78. if err := assertNil(mysqlConfig, key, "refresh_config_time", "30"); err != nil {
  79. return nil, err
  80. }
  81. //if err := assertNil(mysqlConfig, key, "ping_connection", "30"); err != nil {
  82. // return nil, err
  83. //}
  84. mysqlConfig["read_timeout"] = mysqlConfig["read_timeout"] + "s"
  85. mysqlConfig["write_timeout"] = mysqlConfig["write_timeout"] + "s"
  86. mysqlConfig["timeout"] = mysqlConfig["timeout"] + "s"
  87. return mysqlConfig, nil
  88. }
  89. func fillDns(mysqlConfig map[string]string) string {
  90. return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local&readTimeout=%s&writeTimeout=%s&timeout=%s",
  91. mysqlConfig["user"],
  92. mysqlConfig["password"],
  93. mysqlConfig["host"],
  94. mysqlConfig["port"],
  95. mysqlConfig["dbname"],
  96. mysqlConfig["charset"],
  97. mysqlConfig["read_timeout"],
  98. mysqlConfig["write_timeout"],
  99. mysqlConfig["timeout"])
  100. }
  101. func fillDnsSlave(mysqlConfig map[string]string) string {
  102. return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local&readTimeout=%s&writeTimeout=%s&timeout=%s",
  103. mysqlConfig["slave_user"],
  104. mysqlConfig["slave_password"],
  105. mysqlConfig["slave_host"],
  106. mysqlConfig["slave_port"],
  107. mysqlConfig["slave_dbname"],
  108. mysqlConfig["slave_charset"],
  109. mysqlConfig["read_timeout"],
  110. mysqlConfig["write_timeout"],
  111. mysqlConfig["timeout"])
  112. }
  113. func newSqlLogFile(sqlLogFile string) (*os.File, error) {
  114. file, err := os.OpenFile(sqlLogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
  115. if err != nil {
  116. return nil, err
  117. }
  118. return file, err
  119. }
  120. func newEngine(dbName string) (*xorm.EngineGroup, map[string]string, error) {
  121. // 获取配置信息
  122. mysqlConfig, err := getMysqlConfig(dbName, conf.SetAndAssertNil)
  123. if err != nil {
  124. return nil, nil, err
  125. }
  126. //主库
  127. masterEngine, err := xorm.NewEngine("mysql", fillDns(mysqlConfig))
  128. if err != nil {
  129. return nil, nil, err
  130. }
  131. //从库
  132. slaveEngine, err := xorm.NewEngine("mysql", fillDnsSlave(mysqlConfig))
  133. if err != nil {
  134. return nil, nil, err
  135. }
  136. // 1主1从
  137. engineGroup, err := xorm.NewEngineGroup(masterEngine, []*xorm.Engine{slaveEngine})
  138. if err != nil {
  139. return nil, nil, err
  140. }
  141. // 最大空闲<最大连接
  142. engineGroup.SetMaxIdleConns(String2Int(mysqlConfig["max_idle"]))
  143. engineGroup.SetMaxOpenConns(String2Int(mysqlConfig["max_conn"]))
  144. engineGroup.SetConnMaxLifetime(time.Second * time.Duration(String2Int64(mysqlConfig["conn_max_life_time"])))
  145. file, err := newSqlLogFile(mysqlConfig["log_file"])
  146. if err != nil {
  147. // 异常,需要先释放资源
  148. nerr := engineGroup.Close()
  149. if nerr != nil {
  150. return nil, nil, nerr
  151. }
  152. return nil, nil, err
  153. }
  154. engineGroup.SetLogger(NewDbLog(log.NewSimpleLogger(file))) // todo 可能存在重新reload文件没有close释放掉
  155. engineGroup.ShowSQL(true) // 必须打印trace,否则会出现问题,span无法关闭,所以不把是否打印日志暴露出去了
  156. engineGroup.Logger().SetLevel(log.LogLevel(String2Int(mysqlConfig["log_level"], int(log.LOG_WARNING)))) // 默认打印warn级别
  157. Debugf("Db load %s config success, config=%+v.", dbName, mysqlConfig)
  158. return engineGroup, mysqlConfig, nil
  159. }
  160. func closeEngine(group *xorm.EngineGroup) error {
  161. if group == nil {
  162. return nil
  163. }
  164. return group.Close()
  165. }