Fiber 集成 mysql redis es mongodb 等中间件

    image.png
    database.go

    1. package config
    2. import (
    3. "context"
    4. "fmt"
    5. "github.com/aliyun/aliyun-oss-go-sdk/oss"
    6. "github.com/go-redis/redis/v8"
    7. _ "github.com/gofiber/fiber/v2"
    8. "github.com/olivere/elastic/v7"
    9. "github.com/programmerug/fibergorm/entities"
    10. "go.mongodb.org/mongo-driver/mongo"
    11. "go.mongodb.org/mongo-driver/mongo/options"
    12. "gorm.io/driver/mysql"
    13. "gorm.io/gorm"
    14. _ "gorm.io/hints"
    15. )
    16. var DB *gorm.DB
    17. var ES *elastic.Client
    18. var esUrl = "http://192.168.5.88:9205"
    19. var RDB *redis.Client
    20. var MONGO *mongo.Client
    21. var OssCli *oss.Client
    22. func Connect() (err error) {
    23. //初始化数据库连接
    24. dns := "root:123456@(localhost:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
    25. DB, err = gorm.Open(mysql.Open(dns), &gorm.Config{})
    26. if err != nil {
    27. fmt.Printf("连接mysql出错,错误信息:%v", err)
    28. } else {
    29. fmt.Println("成功连接mysql!")
    30. }
    31. return
    32. }
    33. func ConnectEs() (err error) {
    34. //连接客户端
    35. ES, err := elastic.NewClient(elastic.SetURL(esUrl), elastic.SetSniff(false))
    36. if err != nil {
    37. // Handle error
    38. panic(err)
    39. }
    40. // 获取版本号的直接API
    41. esVersion, err := ES.ElasticsearchVersion(esUrl)
    42. if err != nil {
    43. panic(err)
    44. fmt.Printf("连接es出错,错误信息:%v", err)
    45. } else {
    46. fmt.Println("成功连接es!")
    47. fmt.Printf("es的版本为%s\n", esVersion)
    48. }
    49. return
    50. }
    51. func ConnectRedis() (err error) {
    52. //Background返回一个非空的Context。 它永远不会被取消,没有值,也没有期限。
    53. //它通常在main函数,初始化和测试时使用,并用作传入请求的顶级上下文。
    54. var ctx = context.Background()
    55. RDB := redis.NewClient(&redis.Options{
    56. Addr: "192.168.5.86:8001",
    57. Password: "12345678",
    58. DB: 0,
    59. })
    60. _, err = RDB.Ping(ctx).Result()
    61. if err != nil {
    62. fmt.Printf("连接redis出错,错误信息:%v", err)
    63. } else {
    64. fmt.Println("成功连接redis!")
    65. }
    66. return
    67. }
    68. func ConnectMongoDB() (err error) {
    69. // Set client options 建立mongodb连接
    70. clientOptions := options.Client().ApplyURI("mongodb://127.0.0.1:27017/test")
    71. // Connect to MongoDB
    72. MONGO, err := mongo.Connect(context.TODO(), clientOptions)
    73. if err != nil {
    74. fmt.Printf("连接MongoDB出错,错误信息:%v", err)
    75. }
    76. err = MONGO.Ping(context.TODO(), nil)
    77. if err != nil {
    78. fmt.Printf("Ping MongoDB出错,错误信息:%v", err)
    79. } else {
    80. fmt.Println("成功连接MongoDB!")
    81. }
    82. return
    83. }
    84. //创建oss连接
    85. func ConnectOss() (err error) {
    86. var ossConfig entities.OssCon
    87. OssCli, err = oss.New(ossConfig.OssEndpoint, ossConfig.OssAccessKeyID, ossConfig.OssAccessKeySecret)
    88. if err != nil {
    89. panic(err)
    90. }else {
    91. fmt.Println("成功连接Oss!")
    92. }
    93. return
    94. }

    dog.go

    1. package entities
    2. import (
    3. _ "time"
    4. )
    5. type Todo struct {
    6. ID int `json:"id"`
    7. Tiltle string `json:"title"`
    8. Status bool `json:"status"`
    9. }
    10. type Language struct {
    11. Content string `json:"content"`
    12. }
    13. type OssCon struct {
    14. OssBucket string `json:"oss_bucket"`
    15. OssEndpoint string `json:"oss_endpoint"`
    16. // oss访问key
    17. OssAccessKeyID string `json:"oss_access_key_id"`
    18. // oss访问key secret
    19. OssAccessKeySecret string `json:"oss_access_key_secret"`
    20. }

    dog.go

    1. package handlers
    2. import (
    3. "context"
    4. "encoding/json"
    5. "fmt"
    6. "github.com/apache/rocketmq-client-go/v2"
    7. "github.com/apache/rocketmq-client-go/v2/consumer"
    8. "github.com/apache/rocketmq-client-go/v2/primitive"
    9. _ "github.com/apache/rocketmq-client-go/v2/primitive"
    10. "github.com/apache/rocketmq-client-go/v2/producer"
    11. _ "github.com/apache/rocketmq-client-go/v2/producer"
    12. "github.com/aliyun/aliyun-oss-go-sdk/oss"
    13. _ "github.com/go-redis/redis/v8"
    14. "github.com/gofiber/fiber/v2"
    15. "github.com/gofiber/fiber/v2/utils"
    16. _ "github.com/olivere/elastic/v7"
    17. "github.com/programmerug/fibergorm/config"
    18. "github.com/programmerug/fibergorm/entities"
    19. "go.mongodb.org/mongo-driver/bson"
    20. "log"
    21. "os"
    22. "strconv"
    23. "time"
    24. )
    25. var mqUrl = "192.168.137.100:9876"
    26. func GetDogs(c *fiber.Ctx) error {
    27. var dogs []entities.Todo
    28. config.DB.Find(&dogs)
    29. return c.Status(200).JSON(dogs)
    30. }
    31. func GetDog(c *fiber.Ctx) error {
    32. id := c.Params("id")
    33. results := utils.ImmutableString(c.Params("id"))
    34. log.Println("打印格式化参数:" + results)
    35. //拷贝相关参数
    36. // Make a copy
    37. buffer := make([]byte, len(results))
    38. copy(buffer, results)
    39. resultCopy := string(buffer)
    40. log.Println("打印拷贝参数:" + resultCopy)
    41. var dog entities.Todo
    42. result := config.DB.Find(&dog, id)
    43. if result.RowsAffected == 0 {
    44. return c.SendStatus(404)
    45. }
    46. return c.Status(200).JSON(&dog)
    47. }
    48. func Get(c *fiber.Ctx) error {
    49. return c.Send([]byte("Hello, World!"))
    50. }
    51. func AddDog(c *fiber.Ctx) error {
    52. dog := new(entities.Todo)
    53. if err := c.BodyParser(dog); err != nil {
    54. return c.Status(503).SendString(err.Error())
    55. }
    56. config.DB.Create(&dog)
    57. return c.Status(201).JSON(dog)
    58. }
    59. func UpdateDog(c *fiber.Ctx) error {
    60. dog := new(entities.Todo)
    61. id := c.Params("id")
    62. if err := c.BodyParser(dog); err != nil {
    63. return c.Status(503).SendString(err.Error())
    64. }
    65. config.DB.Where("id = ?", id).Updates(&dog)
    66. return c.Status(200).JSON(dog)
    67. }
    68. func RemoveDog(c *fiber.Ctx) error {
    69. id := c.Params("id")
    70. var dog entities.Todo
    71. result := config.DB.Delete(&dog, id)
    72. if result.RowsAffected == 0 {
    73. return c.SendStatus(404)
    74. }
    75. return c.SendStatus(200)
    76. }
    77. func Create(c *fiber.Ctx) error {
    78. e1 := entities.Language{Content: "golang"}
    79. _, err := config.ES.Index().
    80. Index("es").
    81. Id("1").
    82. BodyJson(e1).
    83. Do(context.Background())
    84. if err != nil {
    85. panic(err)
    86. }
    87. return c.SendStatus(200)
    88. }
    89. func GetEs(c *fiber.Ctx) error {
    90. query, err := config.ES.Get().Index("es").Id("1").Do(context.Background())
    91. if err != nil {
    92. panic(err)
    93. }
    94. var result entities.Language
    95. if query.Found {
    96. err := json.Unmarshal(query.Source, &result)
    97. if err != nil {
    98. fmt.Println(err)
    99. }
    100. fmt.Println(result.Content)
    101. }
    102. return c.Status(200).JSON(result)
    103. }
    104. func DeleteEs(c *fiber.Ctx) error {
    105. //Background返回一个非空的Context。 它永远不会被取消,没有值,也没有期限。
    106. //它通常在main函数,初始化和测试时使用,并用作传入请求的顶级上下文。
    107. var ctx = context.Background()
    108. config.ES.Delete().Index("es").Id("1").Do(ctx)
    109. return c.SendStatus(200)
    110. }
    111. func DeleteRedis(c *fiber.Ctx) error {
    112. //Background返回一个非空的Context。 它永远不会被取消,没有值,也没有期限。
    113. //它通常在main函数,初始化和测试时使用,并用作传入请求的顶级上下文。
    114. var ctx = context.Background()
    115. n, err := config.RDB.Del(ctx, "key1", "key2").Result()
    116. if err != nil {
    117. panic(err)
    118. }
    119. fmt.Printf("成功删除了 %v 个\n", n)
    120. return c.SendStatus(200)
    121. }
    122. func GetRedis(c *fiber.Ctx) error {
    123. //Background返回一个非空的Context。 它永远不会被取消,没有值,也没有期限。
    124. //它通常在main函数,初始化和测试时使用,并用作传入请求的顶级上下文。
    125. var ctx = context.Background()
    126. vType, err := config.RDB.Type(ctx, "key").Result()
    127. if err != nil {
    128. panic(err)
    129. }
    130. return c.Status(200).JSON(vType)
    131. }
    132. func SetRedis(c *fiber.Ctx) error {
    133. //Background返回一个非空的Context。 它永远不会被取消,没有值,也没有期限。
    134. //它通常在main函数,初始化和测试时使用,并用作传入请求的顶级上下文。
    135. var ctx = context.Background()
    136. err := config.RDB.SetEX(ctx, "key", "value", time.Hour*2).Err()
    137. if err != nil {
    138. panic(err)
    139. }
    140. return c.SendStatus(200)
    141. }
    142. func GetMongoDB(c *fiber.Ctx) error {
    143. // 2, 选择数据库ichunt 3, 选择表cron_log
    144. connect := config.MONGO.Database("ichunt").Collection("cron_log")
    145. var result struct {
    146. Value float64
    147. }
    148. filter := bson.D{{"name", "pi"}}
    149. err := connect.FindOne(context.TODO(), filter).Decode(result)
    150. if err != nil {
    151. log.Fatal(err)
    152. }
    153. fmt.Printf("Found a single document: %+v\n", result)
    154. return c.Status(200).JSON(result)
    155. }
    156. func Consumer(c *fiber.Ctx) error {
    157. // 设置推送消费者
    158. pull, _ := rocketmq.NewPushConsumer(
    159. //消费组
    160. consumer.WithGroupName("testGroup"),
    161. // namesrv地址
    162. consumer.WithNameServer([]string{"127.0.0.1:9876"}),
    163. )
    164. // 必须先在 开始前
    165. err := pull.Subscribe("Topic-test", consumer.MessageSelector{}, func(ctx context.Context, ext ...*primitive.MessageExt) (consumer.ConsumeResult, error) {
    166. for i := range ext {
    167. fmt.Printf("subscribe callback:%v \n", ext[i])
    168. }
    169. return consumer.ConsumeSuccess, nil
    170. })
    171. if err != nil {
    172. fmt.Println(err.Error())
    173. }
    174. err = pull.Start()
    175. if err != nil {
    176. fmt.Println(err.Error())
    177. os.Exit(-1)
    178. }
    179. time.Sleep(time.Hour)
    180. err = pull.Shutdown()
    181. if err != nil {
    182. fmt.Printf("shutdown Consumer error:%s",err.Error())
    183. }
    184. return c.SendStatus(200)
    185. }
    186. func Producer(c *fiber.Ctx) error {
    187. push, _ := rocketmq.NewProducer(
    188. // 设置 nameSrvAddr
    189. // nameSrvAddr 是 Topic 路由注册中心
    190. producer.WithNameServer([]string{"127.0.0.1:9876"}),
    191. // 指定发送失败时的重试时间
    192. producer.WithRetry(2),
    193. // 设置 Group
    194. producer.WithGroupName("testGroup"),
    195. )
    196. // 开始连接
    197. err := push.Start()
    198. if err != nil {
    199. fmt.Printf("start producer error: %s", err.Error())
    200. os.Exit(1)
    201. }
    202. // 设置节点名称
    203. topic := "Topic-test"
    204. // 循坏发送信息 (同步发送)
    205. for i := 0; i < 10; i++ {
    206. msg := &primitive.Message{
    207. Topic: topic,
    208. Body: []byte("Hello RocketMQ Go Client" + strconv.Itoa(i)),
    209. }
    210. // 发送信息
    211. res, err := push.SendSync(context.Background(),msg)
    212. if err != nil {
    213. fmt.Printf("send message error:%s\n",err)
    214. }else {
    215. fmt.Printf("send message success: result=%s\n",res.String())
    216. }
    217. }
    218. // 关闭生产者
    219. err = push.Shutdown()
    220. if err != nil {
    221. fmt.Printf("shutdown producer error:%s",err.Error())
    222. }
    223. return c.SendStatus(200)
    224. }
    225. // Bucket: 获取bucket存储空间
    226. func Bucket() *oss.Bucket {
    227. var ossConfig entities.OssCon
    228. bucket, err := config.OssCli.Bucket(ossConfig.OssBucket)
    229. if err != nil {
    230. log.Println(err.Error())
    231. return nil
    232. }
    233. return bucket
    234. }
    235. func Upload(c *fiber.Ctx) error{
    236. filename := "hes.text"
    237. ossPath := "oss/" + filename // oss不能以/开头
    238. file, _ := os.Open(filename)
    239. err := Bucket().PutObject(ossPath, file)
    240. if err != nil {
    241. fmt.Printf("上传oss失败: %+v\n", err.Error())
    242. return c.SendStatus(503)
    243. }
    244. return c.SendStatus(200)
    245. }
    246. // 临时下载授权
    247. func DownUrl(c *fiber.Ctx) error{
    248. filepath := "oss/hes.text"
    249. url, err := Bucket().SignURL(filepath, oss.HTTPGet, 3600)
    250. if err != nil {
    251. fmt.Printf("下载oss失败: %+v\n", err.Error())
    252. return c.SendStatus(503)
    253. }
    254. return c.Status(200).JSON(url)
    255. }

    go.mod

    1. module github.com/programmerug/fibergorm
    2. go 1.16
    3. require (
    4. github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible
    5. github.com/andybalholm/brotli v1.0.4 // indirect
    6. github.com/apache/rocketmq-client-go/v2 v2.1.0
    7. github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
    8. github.com/fasthttp/websocket v1.4.5 // indirect
    9. github.com/fsnotify/fsnotify v1.5.1 // indirect
    10. github.com/go-redis/redis/v8 v8.11.4
    11. github.com/go-stack/stack v1.8.1 // indirect
    12. github.com/gofiber/fiber/v2 v2.24.0
    13. github.com/gofiber/websocket/v2 v2.0.15
    14. github.com/golang/mock v1.6.0 // indirect
    15. github.com/golang/snappy v0.0.4 // indirect
    16. github.com/jinzhu/now v1.1.4 // indirect
    17. github.com/json-iterator/go v1.1.12 // indirect
    18. github.com/klauspost/compress v1.14.1 // indirect
    19. github.com/kr/text v0.2.0 // indirect
    20. github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
    21. github.com/olivere/elastic/v7 v7.0.31
    22. github.com/satori/go.uuid v1.2.0 // indirect
    23. github.com/sirupsen/logrus v1.8.1 // indirect
    24. github.com/tidwall/gjson v1.12.1 // indirect
    25. github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
    26. go.mongodb.org/mongo-driver v1.8.2
    27. go.uber.org/atomic v1.9.0 // indirect
    28. golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
    29. golang.org/x/net v0.0.0-20220111093109-d55c255bac03 // indirect
    30. golang.org/x/sys v0.0.0-20220111092808-5a964db01320 // indirect
    31. golang.org/x/text v0.3.7 // indirect
    32. golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect
    33. gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
    34. gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
    35. gorm.io/driver/mysql v1.2.3
    36. gorm.io/gorm v1.22.5
    37. gorm.io/hints v1.1.0
    38. )

    main.go

    1. package main
    2. import (
    3. "github.com/gofiber/fiber/v2"
    4. "github.com/gofiber/websocket/v2"
    5. "github.com/programmerug/fibergorm/config"
    6. _ "github.com/programmerug/fibergorm/config"
    7. "github.com/programmerug/fibergorm/handlers"
    8. "log"
    9. )
    10. func main() {
    11. app := fiber.New()
    12. config.Connect()
    13. app.Static("/", "/public")
    14. // => http://localhost:3000/js/script.js
    15. // => http://localhost:3000/css/style.css
    16. app.Static("/prefix", "/public")
    17. // => http://localhost:3000/prefix/js/script.js
    18. // => http://localhost:3000/prefix/css/style.css
    19. app.Static("*", "/public/index.html")
    20. // => http://localhost:3000/any/path/shows/index/html
    21. app.Get("/dogs", handlers.GetDogs)
    22. app.Get("/list", handlers.Get)
    23. app.Get("/dogs/:id", handlers.GetDog)
    24. app.Post("/dogs", handlers.AddDog)
    25. app.Put("/dogs/:id", handlers.UpdateDog)
    26. app.Delete("/dogs/:id", handlers.RemoveDog)
    27. config.ConnectEs()
    28. //app.Get("/es", handlers.Create)
    29. app.Get("/es", handlers.GetEs)
    30. app.Delete("/deletes", handlers.DeleteEs)
    31. config.ConnectRedis()
    32. app.Put("/set", handlers.SetRedis)
    33. app.Get("/get", handlers.GetRedis)
    34. app.Delete("/deletes", handlers.DeleteRedis)
    35. config.ConnectMongoDB()
    36. app.Get("/mongodb", handlers.GetMongoDB)
    37. // websocket 服务
    38. app.Use("/ws", func(c *fiber.Ctx) error {
    39. // IsWebSocketUpgrade returns true if the client
    40. // requested upgrade to the WebSocket protocol.
    41. if websocket.IsWebSocketUpgrade(c) {
    42. c.Locals("allowed", true)
    43. return c.Next()
    44. }
    45. return fiber.ErrUpgradeRequired
    46. })
    47. app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {
    48. // c.Locals is added to the *websocket.Conn
    49. log.Println(c.Locals("allowed")) // true
    50. log.Println(c.Params("id")) // 123
    51. log.Println(c.Query("v")) // 1.0
    52. log.Println(c.Cookies("session")) // ""
    53. // websocket.Conn bindings https://pkg.go.dev/github.com/fasthttp/websocket?tab=doc#pkg-index
    54. var (
    55. mt int
    56. msg []byte
    57. err error
    58. )
    59. for {
    60. if mt, msg, err = c.ReadMessage(); err != nil {
    61. log.Println("read:", err)
    62. break
    63. }
    64. log.Printf("recv: %s", msg)
    65. if err = c.WriteMessage(mt, msg); err != nil {
    66. log.Println("write:", err)
    67. break
    68. }
    69. }
    70. }))
    71. //监听端口
    72. log.Fatal(app.Listen(":3000"))
    73. }

    go mysql 教程:https://gorm.io/zh_CN/docs/connecting_to_the_database.html
    go 语法教程:https://tour.go-zh.org/basics/13
    fiber 教程 : https://learnku.com/docs/gofiber/2.x/context-object/11726
    go-zero 教程: goctl api new leaf 此命令就生成了leaf的web项目
    IAM系统 教程:https://gitee.com/bryant_ba/iam?_from=gitee_search
    API文档转换:https://github.com/LucyBot-Inc/api-spec-converter
    go+ 官网:https://gocn.vip/topics/20888
    **go get -u**用来更新现有软件包。
    **go get -u all**用来更新您的所有软件包
    **go get -u -x** 打印出用到的命令
    go mod download下载指定名字的模块,可为选择主模块依赖的模块匹配模式
    go mod verify检查存储在本地下载源代码缓存中的当前模块的依赖,是否自从下载之后未被修改
    go install 下载包
    go mod tidy//拉取缺少的模块,移除不用的模块。
    **go mod vendor**将依赖复制到vendor下
    **go mod graph**打印模块依赖图
    **go get -u**

    • -u:下载并安装代码包,不论工作区中是否已存在它们。
    • -d:只下载代码包,不安装代码包。
    • -fix:在下载代码包后先运行一个用于根据当前 Go 语言版本修正代码的工具,然后再安装代码包。
    • -t:同时下载测试所需的代码包。
    • -insecure:允许通过非安全的网络协议下载和安装代码包。HTTP 就是这样的协议。