Fiber 集成 mysql redis es mongodb 等中间件
database.go
package config
import (
"context"
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"github.com/go-redis/redis/v8"
_ "github.com/gofiber/fiber/v2"
"github.com/olivere/elastic/v7"
"github.com/programmerug/fibergorm/entities"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"gorm.io/driver/mysql"
"gorm.io/gorm"
_ "gorm.io/hints"
)
var DB *gorm.DB
var ES *elastic.Client
var esUrl = "http://192.168.5.88:9205"
var RDB *redis.Client
var MONGO *mongo.Client
var OssCli *oss.Client
func Connect() (err error) {
//初始化数据库连接
dns := "root:123456@(localhost:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
DB, err = gorm.Open(mysql.Open(dns), &gorm.Config{})
if err != nil {
fmt.Printf("连接mysql出错,错误信息:%v", err)
} else {
fmt.Println("成功连接mysql!")
}
return
}
func ConnectEs() (err error) {
//连接客户端
ES, err := elastic.NewClient(elastic.SetURL(esUrl), elastic.SetSniff(false))
if err != nil {
// Handle error
panic(err)
}
// 获取版本号的直接API
esVersion, err := ES.ElasticsearchVersion(esUrl)
if err != nil {
panic(err)
fmt.Printf("连接es出错,错误信息:%v", err)
} else {
fmt.Println("成功连接es!")
fmt.Printf("es的版本为%s\n", esVersion)
}
return
}
func ConnectRedis() (err error) {
//Background返回一个非空的Context。 它永远不会被取消,没有值,也没有期限。
//它通常在main函数,初始化和测试时使用,并用作传入请求的顶级上下文。
var ctx = context.Background()
RDB := redis.NewClient(&redis.Options{
Addr: "192.168.5.86:8001",
Password: "12345678",
DB: 0,
})
_, err = RDB.Ping(ctx).Result()
if err != nil {
fmt.Printf("连接redis出错,错误信息:%v", err)
} else {
fmt.Println("成功连接redis!")
}
return
}
func ConnectMongoDB() (err error) {
// Set client options 建立mongodb连接
clientOptions := options.Client().ApplyURI("mongodb://127.0.0.1:27017/test")
// Connect to MongoDB
MONGO, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
fmt.Printf("连接MongoDB出错,错误信息:%v", err)
}
err = MONGO.Ping(context.TODO(), nil)
if err != nil {
fmt.Printf("Ping MongoDB出错,错误信息:%v", err)
} else {
fmt.Println("成功连接MongoDB!")
}
return
}
//创建oss连接
func ConnectOss() (err error) {
var ossConfig entities.OssCon
OssCli, err = oss.New(ossConfig.OssEndpoint, ossConfig.OssAccessKeyID, ossConfig.OssAccessKeySecret)
if err != nil {
panic(err)
}else {
fmt.Println("成功连接Oss!")
}
return
}
dog.go
package entities
import (
_ "time"
)
type Todo struct {
ID int `json:"id"`
Tiltle string `json:"title"`
Status bool `json:"status"`
}
type Language struct {
Content string `json:"content"`
}
type OssCon struct {
OssBucket string `json:"oss_bucket"`
OssEndpoint string `json:"oss_endpoint"`
// oss访问key
OssAccessKeyID string `json:"oss_access_key_id"`
// oss访问key secret
OssAccessKeySecret string `json:"oss_access_key_secret"`
}
dog.go
package handlers
import (
"context"
"encoding/json"
"fmt"
"github.com/apache/rocketmq-client-go/v2"
"github.com/apache/rocketmq-client-go/v2/consumer"
"github.com/apache/rocketmq-client-go/v2/primitive"
_ "github.com/apache/rocketmq-client-go/v2/primitive"
"github.com/apache/rocketmq-client-go/v2/producer"
_ "github.com/apache/rocketmq-client-go/v2/producer"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
_ "github.com/go-redis/redis/v8"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/utils"
_ "github.com/olivere/elastic/v7"
"github.com/programmerug/fibergorm/config"
"github.com/programmerug/fibergorm/entities"
"go.mongodb.org/mongo-driver/bson"
"log"
"os"
"strconv"
"time"
)
var mqUrl = "192.168.137.100:9876"
func GetDogs(c *fiber.Ctx) error {
var dogs []entities.Todo
config.DB.Find(&dogs)
return c.Status(200).JSON(dogs)
}
func GetDog(c *fiber.Ctx) error {
id := c.Params("id")
results := utils.ImmutableString(c.Params("id"))
log.Println("打印格式化参数:" + results)
//拷贝相关参数
// Make a copy
buffer := make([]byte, len(results))
copy(buffer, results)
resultCopy := string(buffer)
log.Println("打印拷贝参数:" + resultCopy)
var dog entities.Todo
result := config.DB.Find(&dog, id)
if result.RowsAffected == 0 {
return c.SendStatus(404)
}
return c.Status(200).JSON(&dog)
}
func Get(c *fiber.Ctx) error {
return c.Send([]byte("Hello, World!"))
}
func AddDog(c *fiber.Ctx) error {
dog := new(entities.Todo)
if err := c.BodyParser(dog); err != nil {
return c.Status(503).SendString(err.Error())
}
config.DB.Create(&dog)
return c.Status(201).JSON(dog)
}
func UpdateDog(c *fiber.Ctx) error {
dog := new(entities.Todo)
id := c.Params("id")
if err := c.BodyParser(dog); err != nil {
return c.Status(503).SendString(err.Error())
}
config.DB.Where("id = ?", id).Updates(&dog)
return c.Status(200).JSON(dog)
}
func RemoveDog(c *fiber.Ctx) error {
id := c.Params("id")
var dog entities.Todo
result := config.DB.Delete(&dog, id)
if result.RowsAffected == 0 {
return c.SendStatus(404)
}
return c.SendStatus(200)
}
func Create(c *fiber.Ctx) error {
e1 := entities.Language{Content: "golang"}
_, err := config.ES.Index().
Index("es").
Id("1").
BodyJson(e1).
Do(context.Background())
if err != nil {
panic(err)
}
return c.SendStatus(200)
}
func GetEs(c *fiber.Ctx) error {
query, err := config.ES.Get().Index("es").Id("1").Do(context.Background())
if err != nil {
panic(err)
}
var result entities.Language
if query.Found {
err := json.Unmarshal(query.Source, &result)
if err != nil {
fmt.Println(err)
}
fmt.Println(result.Content)
}
return c.Status(200).JSON(result)
}
func DeleteEs(c *fiber.Ctx) error {
//Background返回一个非空的Context。 它永远不会被取消,没有值,也没有期限。
//它通常在main函数,初始化和测试时使用,并用作传入请求的顶级上下文。
var ctx = context.Background()
config.ES.Delete().Index("es").Id("1").Do(ctx)
return c.SendStatus(200)
}
func DeleteRedis(c *fiber.Ctx) error {
//Background返回一个非空的Context。 它永远不会被取消,没有值,也没有期限。
//它通常在main函数,初始化和测试时使用,并用作传入请求的顶级上下文。
var ctx = context.Background()
n, err := config.RDB.Del(ctx, "key1", "key2").Result()
if err != nil {
panic(err)
}
fmt.Printf("成功删除了 %v 个\n", n)
return c.SendStatus(200)
}
func GetRedis(c *fiber.Ctx) error {
//Background返回一个非空的Context。 它永远不会被取消,没有值,也没有期限。
//它通常在main函数,初始化和测试时使用,并用作传入请求的顶级上下文。
var ctx = context.Background()
vType, err := config.RDB.Type(ctx, "key").Result()
if err != nil {
panic(err)
}
return c.Status(200).JSON(vType)
}
func SetRedis(c *fiber.Ctx) error {
//Background返回一个非空的Context。 它永远不会被取消,没有值,也没有期限。
//它通常在main函数,初始化和测试时使用,并用作传入请求的顶级上下文。
var ctx = context.Background()
err := config.RDB.SetEX(ctx, "key", "value", time.Hour*2).Err()
if err != nil {
panic(err)
}
return c.SendStatus(200)
}
func GetMongoDB(c *fiber.Ctx) error {
// 2, 选择数据库ichunt 3, 选择表cron_log
connect := config.MONGO.Database("ichunt").Collection("cron_log")
var result struct {
Value float64
}
filter := bson.D{{"name", "pi"}}
err := connect.FindOne(context.TODO(), filter).Decode(result)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found a single document: %+v\n", result)
return c.Status(200).JSON(result)
}
func Consumer(c *fiber.Ctx) error {
// 设置推送消费者
pull, _ := rocketmq.NewPushConsumer(
//消费组
consumer.WithGroupName("testGroup"),
// namesrv地址
consumer.WithNameServer([]string{"127.0.0.1:9876"}),
)
// 必须先在 开始前
err := pull.Subscribe("Topic-test", consumer.MessageSelector{}, func(ctx context.Context, ext ...*primitive.MessageExt) (consumer.ConsumeResult, error) {
for i := range ext {
fmt.Printf("subscribe callback:%v \n", ext[i])
}
return consumer.ConsumeSuccess, nil
})
if err != nil {
fmt.Println(err.Error())
}
err = pull.Start()
if err != nil {
fmt.Println(err.Error())
os.Exit(-1)
}
time.Sleep(time.Hour)
err = pull.Shutdown()
if err != nil {
fmt.Printf("shutdown Consumer error:%s",err.Error())
}
return c.SendStatus(200)
}
func Producer(c *fiber.Ctx) error {
push, _ := rocketmq.NewProducer(
// 设置 nameSrvAddr
// nameSrvAddr 是 Topic 路由注册中心
producer.WithNameServer([]string{"127.0.0.1:9876"}),
// 指定发送失败时的重试时间
producer.WithRetry(2),
// 设置 Group
producer.WithGroupName("testGroup"),
)
// 开始连接
err := push.Start()
if err != nil {
fmt.Printf("start producer error: %s", err.Error())
os.Exit(1)
}
// 设置节点名称
topic := "Topic-test"
// 循坏发送信息 (同步发送)
for i := 0; i < 10; i++ {
msg := &primitive.Message{
Topic: topic,
Body: []byte("Hello RocketMQ Go Client" + strconv.Itoa(i)),
}
// 发送信息
res, err := push.SendSync(context.Background(),msg)
if err != nil {
fmt.Printf("send message error:%s\n",err)
}else {
fmt.Printf("send message success: result=%s\n",res.String())
}
}
// 关闭生产者
err = push.Shutdown()
if err != nil {
fmt.Printf("shutdown producer error:%s",err.Error())
}
return c.SendStatus(200)
}
// Bucket: 获取bucket存储空间
func Bucket() *oss.Bucket {
var ossConfig entities.OssCon
bucket, err := config.OssCli.Bucket(ossConfig.OssBucket)
if err != nil {
log.Println(err.Error())
return nil
}
return bucket
}
func Upload(c *fiber.Ctx) error{
filename := "hes.text"
ossPath := "oss/" + filename // oss不能以/开头
file, _ := os.Open(filename)
err := Bucket().PutObject(ossPath, file)
if err != nil {
fmt.Printf("上传oss失败: %+v\n", err.Error())
return c.SendStatus(503)
}
return c.SendStatus(200)
}
// 临时下载授权
func DownUrl(c *fiber.Ctx) error{
filepath := "oss/hes.text"
url, err := Bucket().SignURL(filepath, oss.HTTPGet, 3600)
if err != nil {
fmt.Printf("下载oss失败: %+v\n", err.Error())
return c.SendStatus(503)
}
return c.Status(200).JSON(url)
}
go.mod
module github.com/programmerug/fibergorm
go 1.16
require (
github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/apache/rocketmq-client-go/v2 v2.1.0
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
github.com/fasthttp/websocket v1.4.5 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/go-redis/redis/v8 v8.11.4
github.com/go-stack/stack v1.8.1 // indirect
github.com/gofiber/fiber/v2 v2.24.0
github.com/gofiber/websocket/v2 v2.0.15
github.com/golang/mock v1.6.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/jinzhu/now v1.1.4 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.14.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/olivere/elastic/v7 v7.0.31
github.com/satori/go.uuid v1.2.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/tidwall/gjson v1.12.1 // indirect
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
go.mongodb.org/mongo-driver v1.8.2
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
golang.org/x/net v0.0.0-20220111093109-d55c255bac03 // indirect
golang.org/x/sys v0.0.0-20220111092808-5a964db01320 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
gorm.io/driver/mysql v1.2.3
gorm.io/gorm v1.22.5
gorm.io/hints v1.1.0
)
main.go
package main
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/websocket/v2"
"github.com/programmerug/fibergorm/config"
_ "github.com/programmerug/fibergorm/config"
"github.com/programmerug/fibergorm/handlers"
"log"
)
func main() {
app := fiber.New()
config.Connect()
app.Static("/", "/public")
// => http://localhost:3000/js/script.js
// => http://localhost:3000/css/style.css
app.Static("/prefix", "/public")
// => http://localhost:3000/prefix/js/script.js
// => http://localhost:3000/prefix/css/style.css
app.Static("*", "/public/index.html")
// => http://localhost:3000/any/path/shows/index/html
app.Get("/dogs", handlers.GetDogs)
app.Get("/list", handlers.Get)
app.Get("/dogs/:id", handlers.GetDog)
app.Post("/dogs", handlers.AddDog)
app.Put("/dogs/:id", handlers.UpdateDog)
app.Delete("/dogs/:id", handlers.RemoveDog)
config.ConnectEs()
//app.Get("/es", handlers.Create)
app.Get("/es", handlers.GetEs)
app.Delete("/deletes", handlers.DeleteEs)
config.ConnectRedis()
app.Put("/set", handlers.SetRedis)
app.Get("/get", handlers.GetRedis)
app.Delete("/deletes", handlers.DeleteRedis)
config.ConnectMongoDB()
app.Get("/mongodb", handlers.GetMongoDB)
// websocket 服务
app.Use("/ws", func(c *fiber.Ctx) error {
// IsWebSocketUpgrade returns true if the client
// requested upgrade to the WebSocket protocol.
if websocket.IsWebSocketUpgrade(c) {
c.Locals("allowed", true)
return c.Next()
}
return fiber.ErrUpgradeRequired
})
app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {
// c.Locals is added to the *websocket.Conn
log.Println(c.Locals("allowed")) // true
log.Println(c.Params("id")) // 123
log.Println(c.Query("v")) // 1.0
log.Println(c.Cookies("session")) // ""
// websocket.Conn bindings https://pkg.go.dev/github.com/fasthttp/websocket?tab=doc#pkg-index
var (
mt int
msg []byte
err error
)
for {
if mt, msg, err = c.ReadMessage(); err != nil {
log.Println("read:", err)
break
}
log.Printf("recv: %s", msg)
if err = c.WriteMessage(mt, msg); err != nil {
log.Println("write:", err)
break
}
}
}))
//监听端口
log.Fatal(app.Listen(":3000"))
}
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 就是这样的协议。