前后端CI/CD, GO编写minio存储文件服务 (二)

本篇主要介绍Go开发minio存储文件服务的过程. 篇幅有点长.

要实现的功能, 如下:

鉴权(jwt、casbin)

注释文档(swagger)

MinioSDK(minio)

集成部署(jenkins, docker)

代码↓:

Github
前端 https://github.com/guangnaoke/vue3-admin
Go https://github.com/guangnaoke/go-minio

Gitee
前端 https://gitee.com/Xiao_Yi_Zhou/vue3-admin.git
Go https://gitee.com/Xiao_Yi_Zhou/go-minio.git

第一部分链接: 前后端CI/CD, GO编写minio存储文件服务 (一)

都是些比较简单的功能. 那么… 开整!

安装

GO安装库及插件

go get -u github.com/gin-gonic/gin
go get github.com/casbin/casbin/v2
go get github.com/golang-jwt/jwt
go get github.com/minio/minio-go/v7
go get github.com/swaggo/gin-swagger
go get github.com/swaggo/swag
go get gopkg.in/yaml.v3
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite

docker安装Minio

docker run \
-d \
-p 9000:9000 \
-p 9001:9001 \
--name minio \
--restart=always \
-v /www/minio/data:/data \
-e "MINIO_ROOT_USER=YOURNAME" \
-e "MINIO_ROOT_PASSWORD=YOURPASSWORD" \
minio/minio:latest server /data --console-address ":9001"

MINIO_ROOT_USER, MINIO_ROOT_PASSWORD 账号密码改成自己的

浏览器输入地址: http://127.0.0.1(替换地址):9001 看是否能打开minio控制端

在这里插入图片描述

账号密码就是刚才设置的. 现在可以建个bucket试试传输文件之类的.

查看SDK列表页

SDK列表 https://docs.min.io/docs/golang-client-api-reference.html
例子 https://github.com/minio/minio-go/tree/master/examples/s3

需要实现的接口不多, 以下:

删除桶之类的还是管理员去操作, 以免误删. 前端只需要上传和查看功能.

docker安装Mysql

docker run \
-p 3306:3306 \
--name mysql \
--privileged=true \
--restart=always \
-v /usr/mysql/local/conf:/etc/mysql/conf.d \
-v /usr/mysql/local/logs:/logs \
-v /usr/mysql/local/data:/var/lib/mysql \
-v /usr/mysql/local/mysql-files:/var/lib/mysql-files \
-e MYSQL_ROOT_PASSWORD=yourpassword \
-e TZ=Asia/Shanghai \
-d docker.io/mysql:latest

–privileged=true 【容器内的root拥有真正的权限, 否则只是普通用户权限】
-v 【挂载目录, 配置文件, 日志】
MYSQL_ROOT_PASSWORD 改成自己的密码

查看容器看是否运行成功

在这里插入图片描述

通过Navicat之类的工具看是否能正常连接数据库.

初始化配置信息

根目录创建conf文件夹.

创建conf.yaml, 把配置信息写入conf.yaml文件.

# Mysql服务配置
mysql:
  driverName: mysql
  host: 127.0.0.1
  port: 3306
  database: you_database
  username: admin
  password: admin
  charset: utf8mb4
  parseTime: True
  loc: Local

# MinIO文件存储服务器配置
minio:
  endpoint: 127.0.0.1:9000
  access: you_access
  accessKey: admin
  secretKey: admin

初始化全局单例

创建config.go, 这些都是程序初始化时要用到的模型, mysql的配置信息、minio账号配置等.

package conf

type MysqlConf struct {
   
    DriverName string `yaml:"driverName" json:"driver_name"`
    Username   string `yaml:"username" json:"username"`
    Password   string `yaml:"password" json:"password"`
    Host       string `yaml:"host" json:"host"`
    Port       string `yaml:"port" json:"port"`
    Database   string `yaml:"database" json:"database"`
    Charset    string `yaml:"charset" json:"charset"`
    ParseTime  string `yaml:"parseTime" json:"parse_time"`
    Loc        string `yaml:"loc" json:"loc"`
}

type MinioConf struct {
   
    Endpoint  string `yaml:"endpoint" json:"endpoint"`
    Access    string `yaml:"access" json:"access"`
    AccessKey string `yaml:"accessKey" json:"accessKey"`
    SecretKey string `yaml:"secretKey" json:"secretKey"`
}

type ServerConf struct {
   
    MysqlInfo MysqlConf `yaml:"mysql" json:"mysql"`
    MinioInfo MinioConf `yaml:"minio" json:"minio"`
}

创建global文件夹.

创建singleton.go, 设置全局单例.

package global

import (
    "minio_server/conf"

    "github.com/minio/minio-go/v7"
    "gorm.io/gorm"
)

var (
    Settings    conf.ServerConf
    DB          *gorm.DB
    MinioClient *minio.Client
)

创建一个initialize文件夹.

创建config.go, 将之前的yaml配置信息设置到全局serverConfig, 下面会用到.

package initialize

import (
    "io/ioutil"
    "log"
    "minio_server/conf"
    "minio_server/global"
    "os"

    "gopkg.in/yaml.v3"
)

func InitConfig() error {
   
    workDor, _ := os.Getwd()
    // 读取yaml配置文件
    yamlFile, err := ioutil.ReadFile(workDor + "/conf/conf.yaml")
    if err != nil {
   
        log.Printf("yamlFile.Get err %v", err)
        return err
    }
    
    // 配置信息模型
    serverConfig := conf.ServerConf{
   }
    
    // 将yaml文件对应的配置信息写入serverConfig
    err = yaml.Unmarshal(yamlFile, &serverConfig)
    if err != nil {
   
        log.Fatalf("Unmarshal: %v", err)
        return err
    }
    
    // 设置全局Settings
    global.Settings = serverConfig

    return nil
}

创建mysql.go

package initialize

import (
    "database/sql"
    "fmt"
    "log"
    "minio_server/global"
    "time"

    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "gorm.io/gorm/schema"
)

func InitMysqlDB() error {
   
    mysqlInfo := global.Settings.MysqlInfo

    args := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=%s&loc=%s",
        mysqlInfo.Username,
        mysqlInfo.Password,
        mysqlInfo.Host,
        mysqlInfo.Port,
        mysqlInfo.Database,
        mysqlInfo.Charset,
        mysqlInfo.ParseTime,
        mysqlInfo.Loc,
    )

    sqlDB, err := sql.Open(mysqlInfo.DriverName, args)
    if err != nil {
   
        log.Fatalln(err)

        return err
    }

    // 空闲连接池中连接的最大数量
    sqlDB.SetMaxIdleConns(10)
    // 打开数据库连接的最大数量, 根据需求看着调
    sqlDB.SetMaxOpenConns(100)
    // 连接可复用的最大时间。
    sqlDB.SetConnMaxLifetime(time.Hour)

    // 注册单例
    gormDB, err := gorm.Open(mysql.New(mysql.Config{
   
        Conn: sqlDB,
    }), &gorm.Config{
   
        // 禁止自动给表名加 "s"
        NamingStrategy: schema.NamingStrategy{
   SingularTable: true},
    })
    if err != nil {
   
        global.DB = nil
        log.Fatalln(err)

        return err
    }
    
    // 设置全局DB
    global.DB = gormDB
    log.Println("Mysql Init Success")

    return nil
}

创建minio.go

package initialize

import (
    "log"
    "minio_server/global"

    "github.com/minio/minio-go/v7"
    "github.com/minio/minio-go/v7/pkg/credentials"
)

func InitMinIO() error {
   
    minioInfo := global.Settings.MinioInfo
    
    // 创建minio服务, 传入IP、账号、密码.
    minioClient, err := minio.New(minioInfo.Endpoint, &minio.Options{
   
        Creds:  credentials.NewStaticV4(minioInfo.AccessKey, minioInfo.SecretKey, ""),
        // 关闭TLS, 暂时不需要
        Secure: false,
    })
    if err != nil {
   
        global.MinioClient = nil
        log.Fatalln(err)

        return err
    }
    
    // 设置全局MinioClient
    global.MinioClient = minioClient
    log.Println("Minio Init Success")

    return nil
}

创建init.go, 将需要初始化配置的应用统一封装到init文件.

package initialize

func Init() {
   
    errConf := InitConfig()
    if errConf != nil {
   
        panic(errConf)
    }

    errSql := InitMysqlDB()
    if errSql != nil {
   
        panic(errSql)
    }

    errMinio := InitMinIO()
    if errMinio != nil {
   
        panic(errMinio)
    }
}

SDK封装

接下来写点SDK相关的代码.

创建models文件夹.

创建user.go, 按照字段去mysql数据库里面创建一些要用的账号密码. Level分1-3级, 根据自己需求配置.

package models

import "time"

type User struct {
   
    UserID     int16   `sql:"user_id" json:"user_id"`         // 用户ID
    Access     string    `sql:"access" json:"access"`           // 用户权限
    AccessKey  string    `sql:"access_key" json:"access_key"`   // 用户名称
    SecretKey  string    `sql:"secret_key" json:"secret_key"`   // 用户密码
    Level      int       `sql:"level" json:"level"`             // 用户等级
    CreateTime time.Time `sql:"create_time" json:"create_time"` // 创建时间
    UpdateTime time.Time `sql:"update_time" json:"update_time"` // 更新时间
}

JWT

创建common文件夹.

创建jwt.go

package common

import (
    "minio_server/models"
    "time"

    "github.com/golang-jwt/jwt"
)

var jwtKey = []byte("your_key")

type Claims struct {
   
    UserID    int64
    Access    string
    AccessKey string
    Level     int
    jwt.StandardClaims
}

// 颁发token
func ReleaseToken(user models.User) (string, error) {
   
    expirationTime := time.Now().Add(7 * 24 * time.Hour)

    claims := &Claims{
   
        UserID:    user.UserID, // 用户id
        Access:    user.Access, // 用户权限
        AccessKey: user.AccessKey, // 用户账号
        Level:     user.Level, // 等级
        StandardClaims: jwt.StandardClaims{
   
            ExpiresAt: expirationTime.Unix(), // 过期时间
            IssuedAt:  time.Now().Unix(), // 签发时间
            Issuer:    "minio", // 签发人
            Subject:   "token", // 标题
        },
    }
    
    // 加密
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    tokenString, err := token.SignedString(jwtKey)
    if err != nil {
   
        return "", err
    }

    return tokenString, nil
}

// 解析token
func ParseToken(tokenString string) (*jwt.Token, *Claims, error) {
   
    claims := &Claims{
   }

    token, err := jwt.ParseWithClaims(tokenString, claims
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值