一,安装用到的库
liuhongdi@ku:~$ go get -u github.com/allegro/bigcache
说明:刘宏缔的go森林是一个专注golang的博客,
网站:https://blog.imgtouch.com
原文: go语言web开发系列之九:gin框架中用bigcache做进程内缓存 – 架构森林
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,演示项目的相关信息
1,项目地址:
GitHub - liuhongdi/digv09: gin框架中用bigcache做进程内缓存
2,项目功能说明:
演示了使用bigcache作进程内缓存
3,项目结构:如图:
三,go代码说明
1,global/bigcache.go
package global
import (
"github.com/allegro/bigcache"
"log"
"time"
)
//定义一个全局的bigcache
var (
BigCache *bigcache.BigCache
)
//创建一个全局的bigcache
func SetupGlobalCache() (error) {
config := bigcache.Config {
Shards: 1024, // 存储的条目数量,值必须是2的幂
LifeWindow: 5*time.Minute, // 超时后条目被处理
CleanWindow: 2*time.Minute, //处理超时条目的时间范围
MaxEntriesInWindow: 0, // 在 Life Window 中的最大数量,
MaxEntrySize: 0, // 条目最大尺寸,以字节为单位
HardMaxCacheSize: 0, // 设置缓存最大值,以MB为单位,超过了不在分配内存。0表示无限制分配
}
var initErr error
BigCache, initErr = bigcache.NewBigCache(config)
if initErr != nil {
log.Fatal(initErr)
return initErr
}
//BigCache.Stats().
return nil
}
2,main.go
package main
import (
"github.com/gin-gonic/gin"
_ "github.com/jinzhu/gorm/dialects/mysql"
"github.com/liuhongdi/digv09/global"
"github.com/liuhongdi/digv09/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)
}
//bigcache
err = global.SetupGlobalCache()
if err != nil {
log.Fatalf("init.SetupGlobalCache err: %v", err)
}
}
func main() {
//设置运行模式
gin.SetMode(global.ServerSetting.RunMode)
//引入路由
r := router.Router()
//run
r.Run(":"+global.ServerSetting.HttpPort)
}
3,service/article.go
package service
import (
"github.com/liuhongdi/digv09/cache"
"github.com/liuhongdi/digv09/dao"
"github.com/liuhongdi/digv09/model"
)
//得到一篇文章的详情
//得到一篇文章的详情
func GetOneArticle(articleId uint64) (*model.Article, error) {
//get from bigcache
article,err := cache.GetOneArticleCache(articleId);
if ( err != nil) {
//get from mysql
article,errSel := dao.SelectOneArticle(articleId);
if (errSel != nil) {
return nil,errSel
} else {
//set bigcache
errSet := 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
}
}
4,cache/article.go
package cache
import (
"encoding/json"
"fmt"
"github.com/liuhongdi/digv09/global"
"github.com/liuhongdi/digv09/model"
"strconv"
)
//bigcache中索引的名字
func getArticleCacheName(articleId uint64) (string) {
return "article_"+strconv.FormatUint(articleId,10)
}
//从bigcache得到一篇文章
func GetOneArticleCache(articleId uint64) (*model.Article,error) {
key := getArticleCacheName(articleId);
val,err := global.BigCache.Get(key)
if (err != nil) {
return nil,err
} else {
article := model.Article{}
if err := json.Unmarshal([]byte(val), &article); err != nil {
return nil,err
}
return &article,nil
}
}
//向bigcache保存一篇文章
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.BigCache.Set(key,[]byte(content))
if (errSet != nil) {
return errSet
}
fmt.Println("len:",global.BigCache.Len())
fmt.Println("Capacity:",global.BigCache.Capacity())
//global.BigCache.
return nil
}
5,其他相关代码可访问github
四,测试效果
访问一篇文章:
http://127.0.0.1:8000/article/getone/2
返回:
多刷新几次:
查看控制台上输出的响应时间:
[2020-12-21 15:03:57] [1.22ms] SELECT articleId, subject, url FROM `article` WHERE (articleId=2) LIMIT 1
[1 rows affected or returned ]
len: 1
Capacity: 350
[GIN] 2020/12/21 - 15:03:57 | 200 | 1.650001ms | 127.0.0.1 | GET "/article/getone/2"
[GIN] 2020/12/21 - 15:04:05 | 200 | 99.438µs | 127.0.0.1 | GET "/article/getone/2"
[GIN] 2020/12/21 - 15:04:07 | 200 | 86.126µs | 127.0.0.1 | GET "/article/getone/2"
[GIN] 2020/12/21 - 15:04:09 | 200 | 93.195µs | 127.0.0.1 | GET "/article/getone/2"
[GIN] 2020/12/21 - 15:04:10 | 200 | 49.438µs | 127.0.0.1 | GET "/article/getone/2"
[GIN] 2020/12/21 - 15:04:11 | 200 | 67.609µs | 127.0.0.1 | GET "/article/getone/2"
可以看到第一次查询是1ms以上,
而访问进程内缓存后的响应时间降到了100µs以内
五,查看库的版本:
module github.com/liuhongdi/digv09
go 1.15
require (
github.com/gin-gonic/gin v1.6.3
github.com/go-playground/universal-translator v0.17.0
github.com/go-playground/validator/v10 v10.2.0
github.com/jinzhu/gorm v1.9.16
github.com/magiconair/properties v1.8.4 // indirect
github.com/mitchellh/mapstructure v1.3.3 // indirect
github.com/pelletier/go-toml v1.8.1 // indirect
github.com/spf13/afero v1.4.1 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.7.1
github.com/allegro/bigcache v1.2.1
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
golang.org/x/text v0.3.4 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
)