一,安装需要用到的库
1,安装go-redis
liuhongdi@ku:~$ go get -u github.com/go-redis/redis
说明:刘宏缔的go森林是一个专注golang的博客,
网站:https://blog.imgtouch.com
原文: go语言web开发系列之八:gin框架中用go-redis缓存数据 – 架构森林
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,演示项目的相关信息
1,项目地址:
GitHub - liuhongdi/digv08: gin框架中用go-redis缓存数据
2,项目功能说明:
用go-redis缓存数据,提高响应速度,减少数据库压力
3,项目结构:如图:

三,go代码说明
1,config/config.yaml
Database:DBType: mysqlUserName: rootPassword: passwordHost: 127.0.0.1:3306DBName: digCharset: utf8ParseTime: TrueMaxIdleConns: 10MaxOpenConns: 30
Server:RunMode: debugHttpPort: 8000ReadTimeout: 60WriteTimeout: 60
Redis:Addr: 127.0.0.1:6379Password:
2,cache/article.go
package cacheimport ("encoding/json""fmt""github.com/go-redis/redis""github.com/liuhongdi/digv08/global""github.com/liuhongdi/digv08/model""strconv""time"
)
//token的过期时长
const ArticleDuration = time.Minute * 5//cache的名字
func getArticleCacheName(articleId uint64) (string) {return "article_"+strconv.FormatUint(articleId,10)
}//从cache得到一篇文章
func GetOneArticleCache(articleId uint64) (*model.Article,error) {key := getArticleCacheName(articleId);val, err := global.RedisDb.Get(key).Result()if (err == redis.Nil || err != nil) {return nil,err} else {article := model.Article{}if err := json.Unmarshal([]byte(val), &article); err != nil {//t.Error(target)return nil,err}return &article,nil}
}
//向cache保存一篇文章
func SetOneArticleCache(articleId uint64,article *model.Article) (error) {key := getArticleCacheName(articleId);content,err := json.Marshal(article)if (err != nil){fmt.Println(err)return err;}errSet := global.RedisDb.Set(key, content, ArticleDuration).Err()if (errSet != nil) {return errSet}return nil
}
3,global/setting.go
package globalimport ("github.com/liuhongdi/digv08/pkg/setting""time"
)
//服务器配置
type ServerSettingS struct {RunMode stringHttpPort stringReadTimeout time.DurationWriteTimeout time.Duration
}
//数据库配置
type DatabaseSettingS struct {DBType stringUserName stringPassword stringHost stringDBName stringCharset stringParseTime boolMaxIdleConns intMaxOpenConns int
}
//redis配置
type RedisSettingS struct {Addr stringPassword string
}
//定义全局变量
var (ServerSetting *ServerSettingSDatabaseSetting *DatabaseSettingSRedisSetting *RedisSettingS
)//读取配置到全局变量
func SetupSetting() error {s, err := setting.NewSetting()if err != nil {return err}err = s.ReadSection("Database", &DatabaseSetting)if err != nil {return err}err = s.ReadSection("Server", &ServerSetting)if err != nil {return err}err = s.ReadSection("Redis", &RedisSetting)if err != nil {return err}return nil
}
4,global/redisDb.go
package globalimport ("github.com/go-redis/redis"
)
//保存redis连接
var (RedisDb *redis.Client
)//创建到redis的连接
func SetupRedisDb() (error) {RedisDb = redis.NewClient(&redis.Options{Addr: RedisSetting.Addr,Password: RedisSetting.Password, // no password setDB: 0, // use default DB})_, err := RedisDb.Ping().Result()if err != nil {return err}return nil}
5,service/article.go
package serviceimport ("github.com/go-redis/redis""github.com/liuhongdi/digv08/cache""github.com/liuhongdi/digv08/dao""github.com/liuhongdi/digv08/model"
)
//得到一篇文章的详情
func GetOneArticle(articleId uint64) (*model.Article, error) {//get from cachearticle,err := cache.GetOneArticleCache(articleId);if (err == redis.Nil || err != nil) {//get from mysqlarticle,errSel := dao.SelectOneArticle(articleId);if (errSel != nil) {return nil,errSel} else {//set cacheerrSet := cache.SetOneArticleCache(articleId,article)if (errSet != nil){return nil,errSet} else {return article,errSel}}} else {return article,err}
}func GetArticleSum() (int, error) {return dao.SelectcountAll()
}//得到多篇文章,按分页返回
func GetArticleList(page int ,pageSize int) ([]*model.Article,error) {articles, err := dao.SelectAllArticle(page,pageSize)if err != nil {return nil,err} else {return articles,nil}
}
6,main.go
package mainimport ("github.com/gin-gonic/gin"_ "github.com/jinzhu/gorm/dialects/mysql""github.com/liuhongdi/digv08/global""github.com/liuhongdi/digv08/router""log"
)//init
func init() {err := global.SetupSetting()if err != nil {log.Fatalf("init.setupSetting err: %v", err)}err = global.SetupDBLink()if err != nil {log.Fatalf("init.setupDBEngine err: %v", err)}err = global.SetupRedisDb()if err != nil {log.Fatalf("init.SetupRedisDb err: %v", err)}
}func main() {//设置运行模式gin.SetMode(global.ServerSetting.RunMode)//引入路由r := router.Router()//runr.Run(":"+global.ServerSetting.HttpPort)
}
7,其他相关代码可访问github
四,测试效果
1,访问一篇文章:例:
http://127.0.0.1:8000/article/getone/4
返回:

查看redis中的缓存:
root@ku:/data/liuhongdi/digv08# /usr/local/soft/redis6/bin/redis-cli
127.0.0.1:6379>
127.0.0.1:6379> get article_4
"{\"ArticleId\":4,\"Subject\":\"\xe6\x89\xab\xe5\x9c\xb0\xe6\x9c\xba\xe5\x99\xa8\xe4\xba\xba\xe8\xbf\x99\xe4\xb8\xaa\xe4\xb8\x9c\xe8\xa5\xbf...\x80\x82\",\"Url\":\"\",\"imgurl\":\"\",\"headurl\":\"\"}"
再刷新几次,注意看gin在控制台打印出的响应时间:
(/data/liuhongdi/digv08/dao/article.go:12)
[2020-12-18 15:13:40] [2.14ms] SELECT articleId, subject, url FROM `article` WHERE (articleId=4) LIMIT 1
[1 rows affected or returned ]
[GIN] 2020/12/18 - 15:13:40 | 200 | 4.584695ms | 127.0.0.1 | GET "/article/getone/4"
[GIN] 2020/12/18 - 15:16:13 | 200 | 672.171µs | 127.0.0.1 | GET "/article/getone/4"
[GIN] 2020/12/18 - 15:16:15 | 200 | 611.256µs | 127.0.0.1 | GET "/article/getone/4"
[GIN] 2020/12/18 - 15:16:16 | 200 | 638.018µs | 127.0.0.1 | GET "/article/getone/4"
可以看到当有数据库查询时,响应时间为4毫秒左右
当直接访问redis时,响应时间提升了7倍左右,600微秒左右
五,查看库的版本:
module github.com/liuhongdi/digv08go 1.15require (github.com/gin-gonic/gin v1.6.3github.com/go-playground/universal-translator v0.17.0github.com/go-playground/validator/v10 v10.2.0github.com/jinzhu/gorm v1.9.16github.com/magiconair/properties v1.8.4 // indirectgithub.com/mitchellh/mapstructure v1.3.3 // indirectgithub.com/pelletier/go-toml v1.8.1 // indirectgithub.com/spf13/afero v1.4.1 // indirectgithub.com/spf13/cast v1.3.1 // indirectgithub.com/spf13/jwalterweatherman v1.1.0 // indirectgithub.com/spf13/pflag v1.0.5 // indirectgithub.com/spf13/viper v1.7.1github.com/go-redis/redis v6.15.9+incompatiblegolang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirectgolang.org/x/text v0.3.4 // indirectgopkg.in/ini.v1 v1.62.0 // indirectgopkg.in/yaml.v2 v2.3.0 // indirect
)




![Go语言WEB开发[html/template包]](https://img-blog.csdnimg.cn/c1edb049bfd841c09cffb0006a02bef0.png)







