• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

go语言web开发系列之九:gin框架中用bigcache做进程内缓存

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

一,安装用到的库

1,安装go-redis

liuhongdi@ku:~$ go get -u github.com/go-redis/redis
 

2,安装bigcache

liuhongdi@ku:~$ go get -u github.com/allegro/bigcache

说明:刘宏缔的go森林是一个专注golang的博客,
          地址:https://blog.csdn.net/weixin_43881017

说明:作者:刘宏缔 邮箱: [email protected]

 

二,演示项目的相关信息

1,项目地址:

https://github.com/liuhongdi/digv10

2,项目功能:演示redis+bigcache两级缓存,

                    通过订阅redis消息更新进程内缓存bigcache

 

3,项目结构:如图:

三,go代码说明

1,config/config.yaml

  1.  
    Database:
  2.  
    DBType: mysql
  3.  
    UserName: root
  4.  
    Password: password
  5.  
    Host: 127.0.0.1:3306
  6.  
    DBName: dig
  7.  
    Charset: utf8
  8.  
    ParseTime: True
  9.  
    MaxIdleConns: 10
  10.  
    MaxOpenConns: 30
  11.  
    Server:
  12.  
    RunMode: debug
  13.  
    HttpPort: 8000
  14.  
    ReadTimeout: 60
  15.  
    WriteTimeout: 60
  16.  
    Redis:
  17.  
    Addr: 127.0.0.1:6379
  18.  
    Password:

2,controller/setController.go

  1.  
    package controller
  2.  
     
  3.  
    import (
  4.  
    "github.com/gin-gonic/gin"
  5.  
    "github.com/liuhongdi/digv10/global"
  6.  
    "github.com/liuhongdi/digv10/pkg/result"
  7.  
    )
  8.  
     
  9.  
    type SetController struct{}
  10.  
     
  11.  
    //new
  12.  
    func NewSetController() SetController {
  13.  
    return SetController{}
  14.  
    }
  15.  
     
  16.  
    //发布一条消息到redis
  17.  
    func (u *SetController) Pub(c *gin.Context) {
  18.  
    resultRes := result.NewResult(c)
  19.  
    data:=c.Query("id")
  20.  
     
  21.  
    err := global.RedisDb.Publish("articleMsg", data).Err()
  22.  
    if err != nil {
  23.  
    resultRes.Error(400,err.Error())
  24.  
    return
  25.  
    } else {
  26.  
    resultRes.Success("发送成功")
  27.  
    }
  28.  
    }

3,bigcache/article.go

  1.  
    package bigcache
  2.  
     
  3.  
    import (
  4.  
    "encoding/json"
  5.  
    "fmt"
  6.  
    "github.com/liuhongdi/digv10/global"
  7.  
    "github.com/liuhongdi/digv10/model"
  8.  
    "strconv"
  9.  
    )
  10.  
     
  11.  
    //bigcache中索引的名字
  12.  
    func getArticleCacheName(articleId uint64) (string) {
  13.  
    return "article_"+strconv.FormatUint(articleId,10)
  14.  
    }
  15.  
     
  16.  
    //从bigcache得到一篇文章
  17.  
    func GetOneArticleBigCache(articleId uint64) (*model.Article,error) {
  18.  
    fmt.Println("bigcache:GetOneArticleBigCache")
  19.  
    key := getArticleCacheName(articleId);
  20.  
    val,err := global.BigCache.Get(key)
  21.  
    if (err != nil) {
  22.  
    return nil,err
  23.  
    } else {
  24.  
    article := model.Article{}
  25.  
    if err := json.Unmarshal([]byte(val), &article); err != nil {
  26.  
    return nil,err
  27.  
    }
  28.  
    return &article,nil
  29.  
    }
  30.  
    }
  31.  
    //向bigcache保存一篇文章
  32.  
    func SetOneArticleBigCache(articleId uint64,article *model.Article) (error) {
  33.  
    key := getArticleCacheName(articleId);
  34.  
    content,err := json.Marshal(article)
  35.  
    if (err != nil){
  36.  
    fmt.Println(err)
  37.  
    return err;
  38.  
    }
  39.  
    errSet := global.BigCache.Set(key,[]byte(content))
  40.  
    if (errSet != nil) {
  41.  
    return errSet
  42.  
    }
  43.  
    return nil
  44.  
    }

4,rediscache/article.go

  1.  
    package rediscache
  2.  
     
  3.  
    import (
  4.  
    "encoding/json"
  5.  
    "fmt"
  6.  
    "github.com/go-redis/redis"
  7.  
    "github.com/liuhongdi/digv10/global"
  8.  
    "github.com/liuhongdi/digv10/model"
  9.  
    "strconv"
  10.  
    "time"
  11.  
    )
  12.  
    //cache的过期时长
  13.  
    const ArticleDuration = time.Minute * 10
  14.  
     
  15.  
    //cache的名字
  16.  
    func getArticleCacheName(articleId uint64) (string) {
  17.  
    return "article_"+strconv.FormatUint(articleId,10)
  18.  
    }
  19.  
     
  20.  
    //从redis cache得到一篇文章
  21.  
    func GetOneArticleRedisCache(articleId uint64) (*model.Article,error) {
  22.  
    fmt.Println("redis:GetOneArticleRedisCache")
  23.  
    key := getArticleCacheName(articleId);
  24.  
    val, err := global.RedisDb.Get(key).Result()
  25.  
     
  26.  
    if (err == redis.Nil || err != nil) {
  27.  
    return nil,err
  28.  
    } else {
  29.  
    article := model.Article{}
  30.  
    if err := json.Unmarshal([]byte(val), &article); err != nil {
  31.  
    //t.Error(target)
  32.  
    return nil,err
  33.  
    }
  34.  
    return &article,nil
  35.  
    }
  36.  
    }
  37.  
    //向redis cache保存一篇文章
  38.  
    func SetOneArticleRedisCache(articleId uint64,article *model.Article) (error) {
  39.  
    key := getArticleCacheName(articleId);
  40.  
    content,err := json.Marshal(article)
  41.  
    if (err != nil){
  42.  
    fmt.Println(err)
  43.  
    return err;
  44.  
    }
  45.  
    errSet := global.RedisDb.Set(key, content, ArticleDuration).Err()
  46.  
    if (errSet != nil) {
  47.  
    return errSet
  48.  
    }
  49.  
    return nil
  50.  
    }

5,service/article.go

  1.  
    package service
  2.  
     
  3.  
    import (
  4.  
    "fmt"
  5.  
    "github.com/liuhongdi/digv10/bigcache"
  6.  
    "github.com/liuhongdi/digv10/dao"
  7.  
    "github.com/liuhongdi/digv10/global"
  8.  
    "github.com/liuhongdi/digv10/model"
  9.  
    "github.com/liuhongdi/digv10/rediscache"
  10.  
    "strconv"
  11.  
    )
  12.  
     
  13.  
    //得到一篇文章的详情
  14.  
    func GetOneArticle(articleId uint64) (*model.Article, error) {
  15.  
    //get from bigcache
  16.  
    article,err := bigcache.GetOneArticleBigCache(articleId);
  17.  
    if ( err != nil) {
  18.  
    //get from redis
  19.  
    article,errSel := rediscache.GetOneArticleRedisCache(articleId)
  20.  
    if (errSel != nil) {
  21.  
    //get from mysql
  22.  
    article,errSel := dao.SelectOneArticle(articleId);
  23.  
    if (errSel != nil) {
  24.  
    return nil,errSel
  25.  
    } else {
  26.  
    //set redis cache
  27.  
    errSetR := rediscache.SetOneArticleRedisCache(articleId,article)
  28.  
    if (errSetR != nil){
  29.  
    fmt.Println(errSetR)
  30.  
    }
  31.  
    //set bigcache
  32.  
    errSetB := bigcache.SetOneArticleBigCache(articleId,article)
  33.  
    if (errSetB != nil){
  34.  
    fmt.Println(errSetB)
  35.  
    }
  36.  
    return article,nil
  37.  
    }
  38.  
    //return nil,errSel
  39.  
    } else {
  40.  
    //set bigcache
  41.  
    errSet := bigcache.SetOneArticleBigCache(articleId,article)
  42.  
    if (errSet != nil){
  43.  
    return nil,errSet
  44.  
    } else {
  45.  
    return article,errSel
  46.  
    }
  47.  
    }
  48.  
     
  49.  
    } else {
  50.  
    return article,err
  51.  
    }
  52.  
    }
  53.  
     
  54.  
    func GetArticleSum() (int, error) {
  55.  
    return dao.SelectcountAll()
  56.  
    }
  57.  
     
  58.  
    //得到多篇文章,按分页返回
  59.  
    func GetArticleList(page int ,pageSize int) ([]*model.Article,error) {
  60.  
    articles, err := dao.SelectAllArticle(page,pageSize)
  61.  
    if err != nil {
  62.  
    return nil,err
  63.  
    } else {
  64.  
    return articles,nil
  65.  
    }
  66.  
    }
  67.  
     
  68.  
    //从redis更新bigcache
  69.  
    func UpdateArticleBigcache(articleId uint64) (error) {
  70.  
    //get from redis
  71.  
    article,errSel := rediscache.GetOneArticleRedisCache(articleId)
  72.  
    if (errSel != nil) {
  73.  
     
  74.  
    return errSel
  75.  
    } else {
  76.  
    errSetB := bigcache.SetOneArticleBigCache(articleId, article)
  77.  
    if (errSetB != nil) {
  78.  
    fmt.Println(errSetB)
  79.  
    return errSetB
  80.  
    }
  81.  
    return nil
  82.  
    }
  83.  
    }
  84.  
     
  85.  
    //订阅redis消息
  86.  
    func SubMessage(channel string) {
  87.  
    pubsub := global.RedisDb.Subscribe(channel)
  88.  
    fmt.Println("subscribe begin Receive")
  89.  
    _, err := pubsub.Receive()
  90.  
    if err != nil {
  91.  
    return
  92.  
    }
  93.  
    fmt.Println("subscribe begin channel")
  94.  
    ch := pubsub.Channel()
  95.  
    for msg := range ch {
  96.  
    fmt.Println("message:")
  97.  
    fmt.Println( msg.Channel, msg.Payload, "\r\n")
  98.  
    //把字符串转articleid
  99.  
    articleId,errUint := strconv.ParseUint(msg.Payload, 0, 64)
  100.  
    if (errUint != nil) {
  101.  
    fmt.Println(errUint)
  102.  
    } else {
  103.  
    //更新bigcache
  104.  
    errB := UpdateArticleBigcache(articleId)
  105.  
    if (errB != nil){
  106.  
    fmt.Println(errB)
  107.  
    }
  108.  
    }
  109.  
    }
  110.  
    }

6,main.go

  1.  
    package main
  2.  
     
  3.  
    import (
  4.  
    "github.com/gin-gonic/gin"
  5.  
    _ "github.com/jinzhu/gorm/dialects/mysql"
  6.  
    "github.com/liuhongdi/digv10/global"
  7.  
    "github.com/liuhongdi/digv10/router"
  8.  
    "github.com/liuhongdi/digv10/service"
  9.  
    "log"
  10.  
    )
  11.  
     
  12.  
    //init
  13.  
    func init() {
  14.  
    //setting
  15.  
    err := global.SetupSetting()
  16.  
    if err != nil {
  17.  
    log.Fatalf("init.setupSetting err: %v", err)
  18.  
    }
  19.  
    //mysql
  20.  
    err = global.SetupDBLink()
  21.  
    if err != nil {
  22.  
    log.Fatalf("init.setupDBEngine err: %v", err)
  23.  
    }
  24.  
    //redis
  25.  
    err = global.SetupRedisDb()
  26.  
    if err != nil {
  27.  
    log.Fatalf("init.SetupRedisDb err: %v", err)
  28.  
    }
  29.  
    //bigcache
  30.  
    err = global.SetupBigCache()
  31.  
    if err != nil {
  32.  
    log.Fatalf("init.SetupGlobalCache err: %v", err)
  33.  
    }
  34.  
     
  35.  
    //redis sub
  36.  
    go service.SubMessage("articleMsg")
  37.  
    }
  38.  
     
  39.  
     
  40.  
    func main() {
  41.  
    //设置运行模式
  42.  
    gin.SetMode(global.ServerSetting.RunMode)
  43.  
    //引入路由
  44.  
    r := router.Router()
  45.  
    //run
  46.  
    r.Run(":"+global.ServerSetting.HttpPort)
  47.  
    }

7,global/bigcache.go

  1.  
    package global
  2.  
     
  3.  
    import (
  4.  
    "github.com/allegro/bigcache"
  5.  
    "log"
  6.  
    "time"
  7.  
    )
  8.  
    //定义一个全局的bigcache
  9.  
    var (
  10.  
    BigCache *bigcache.BigCache
  11.  
    )
  12.  
     
  13.  
    //创建一个全局的bigcache
  14.  
    func SetupBigCache() (error) {
  15.  
    config := bigcache.Config {
  16.  
    Shards: 1024, // 存储的条目数量,值必须是2的幂
  17.  
    LifeWindow: 3*time.Minute, // 超时后条目被处理
  18.  
    CleanWindow: 2*time.Minute, //处理超时条目的时间范围
  19.  
    MaxEntriesInWindow: 0, // 在 Life Window 中的最大数量,
  20.  
    MaxEntrySize: 0, // 条目最大尺寸,以字节为单位
  21.  
    HardMaxCacheSize: 0, // 设置缓存最大值,以MB为单位,超过了不在分配内存。0表示无限制分配
  22.  
    }
  23.  
    var initErr error
  24.  
    BigCache, initErr = bigcache.NewBigCache(config)
  25.  
    if initErr != nil {
  26.  
    log.Fatal(initErr)
  27.  
    return initErr
  28.  
    }
  29.  
    //BigCache.Stats().
  30.  
    return nil
  31.  
    }

8,global/redisDb.go

  1.  
    package global
  2.  
     
  3.  
    import (
  4.  
    "github.com/go-redis/redis"
  5.  
    )
  6.  
     
  7.  
    var (
  8.  
    RedisDb *redis.Client
  9.  
    )
  10.  
     
  11.  
    //创建redis链接
  12.  
    func SetupRedisDb() (error) {
  13.  
     
  14.  
    RedisDb = redis.NewClient(&redis.Options{
  15.  
    Addr: RedisSetting.Addr,
  16.  
    Password: RedisSetting.Password, // no password set
  17.  
    DB: 0, // use default DB
  18.  
    })
  19.  
     
  20.  
    _, err := RedisDb.Ping().Result()
  21.  
    if err != nil {
  22.  
    return err
  23.  
    }
  24.  
    return nil
  25.  
    }

9,global/setting.go

  1.  
    package global
  2.  
     
  3.  
    import (
  4.  
    "github.com/liuhongdi/digv10/pkg/setting"
  5.  
    "time"
  6.  
    )
  7.  
    //服务器配置
  8.  
    type ServerSettingS struct {
  9.  
    RunMode string
  10.  
    HttpPort string
  11.  
    ReadTimeout time.Duration
  12.  
    WriteTimeout time.Duration
  13.  
    }
  14.  
    //数据库配置
  15.  
    type DatabaseSettingS struct {
  16.  
    DBType string

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Go-errors第三方包学习发布时间:2022-07-10
下一篇:
如何搞定eclipse go plugin gocode.exe guru.exe godef.exe发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap