go语言web开发系列之八:gin框架中用go-redis缓存数据

article/2025/11/5 16:29:01

一,安装需要用到的库

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
)


http://chatgpt.dhexx.cn/article/lTujvEek.shtml

相关文章

go语言web开发系列之二十一:用go-qrcode库生成二维码

一,安装用到的库 1,go-qrcode库的地址 GitHub - skip2/go-qrcode: :sparkles: QR Code encoder (Go) 2,安装go-qrcode库 liuhongdiku:~$ go get -u github.com/skip2/go-qrcode/... 3,resize库的地址(在二维码中间放icon时太大时需要缩放…

go语言web开发出错

2019独角兽企业重金招聘Python工程师标准>>> err listen tcp :8080: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted. 原因:开了两个服务器,造成监听端口冲突 转载于:https://my.osc…

go语言有哪些web框架

前言 由于工作需要,这些年来也接触了不少的开发框架,Golang的开发框架比较多,不过基本都是Web”框架”为主。这里稍微打了个引号,因为大部分”框架”从设计和功能定位上来讲,充其量都只能算是一个组件,需要…

go语言服务器代码,Go语言开发简单web服务器

欢迎,来自IP地址为:182.103.254.107 的朋友 Go语言由于其方便的并发通信机制以及强大的网络支持,常常被用于服务器软件的开发。本文将示例使用Go语言来开发简单的Web服务器。 HTTP协议是应用层协议,协议模型位于TCP之上&#xff0…

Go语言WEB开发[html/template包]

Go语言Web开发 Go语言提供了html/template包来支持模板渲染。Go提供的html/template包对HTML模板提供了丰富的模板语言,主要用于Web应用程序。 模板中的变量 模板中的变量通过{{.}} 来访问。 {{.}} 称为管道和root。 在模板文件内,{{.}}代表当前变量&…

Go语言web开发

一. HTTP Http:无状态协议,是互联网中使用Http实现计算机和计算机之间的请求和响应 Http使用纯文本方式发送和接收协议数据,不需要借助专门工具进行分析就可以知道协议中数据 Http报文(message)组成部分 请求行(request-line)请求头(head)请求体(body)响应头响应体 HTTP 1.1 实…

Go进阶:Go语言最热门的开源Web开发框架总结

注意:后续技术分享,第一时间更新,以及更多更及时的技术资讯和学习技术资料,将在公众号CTO Plus发布,请关注公众号:CTO Plus Go语言是近年来备受关注的一种编程语言,它以其高效、安全、简洁的特…

Go语言五大主流web框架

以下 star数截止2023年7月份 1.Gin(69.7K) 项目简介:Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 它具有类似 Martini 的 API,但性能比 Martini 快 40 倍。 仓库地址:https://github.com/gin-gonic/ginhttps:…

Go语言web开发入门

创建两个文件main.go 和hello.txt main.go package mainimport ("fmt""io/ioutil""net/http" )func sayHello(w http.ResponseWriter, r *http.Request) {b, _ : ioutil.ReadFile("D:/桌面/goprojects/gin框架快速入门/gin框架与Go语言模…

GO 语言 Web 开发实战一

xdm,咱今天分享一个 golang web 实战的 demo go 的 http 包,以前都有或多或多的提到一些,也有一些笔记在我们的历史文章中,今天来一个简单的实战 HTTP 编程 Get 先来一个 小例子,简单的写一个 Get 请求 拿句柄 设置…

goweb开发实战笔记(一)

目录 🧡Gin简介 🧡Gin特性 🧡Gin环境搭建 🧡HTTP请求和参数解析 创建Engine Handle方法处理 Engine分类处理 表单实体绑定 ShouldBindQuery ShouldBind JSON 多数据格式返回请求结果 []byte切片 string JSON HTML…

golang学习之go web 开发

文章目录 一、hello world二、请求处理1、url参数处理2、form参数处理3、header参数处理 三、响应处理1、ResponseWriter 四、cookie五、session实现1、session id2、session的存储3、session过期4、实现代码1、session 操作代码2、web服务3、登录页面4、session数据展示页面 一…

FlexSlider图片轮播切换jQuery插件

下载地址 flexSlider是一款强大的图片轮播插件。参数说明animation: "slide", // String: ["fade"|"slide"],动画效果easing: "swing", // String: 滚动动画计时函数direction: "horizonta…

jQuery FlexSlider插件一些使用上的小tips

最近做的一个需求,用到了jQuery FlexSlider这个插件,本以为一个算是已经比较成熟的插件,用起来应该没什么难度,然而真正用起来才发现,其实还是有些坑的,不过好在这个插件源代码写的比较好,比较好…

jquery.flexslider-min.js实现banner轮播图效果

查看演示 立即下载 插件描述&#xff1a; jquery图片轮播插件仿支付宝2013版全屏图片幻灯片淡出淡进切换效果 实现方法 引用jquery和flexslider.js到你的页面 <script type"text/javascript" src"js/jquery-1.7.2.min.js"></script> <sc…

Vue+Element-ui实例_使用flexslider插件设计横向时间线

下面是做了一个类似时间线(history事件线)的页面&#xff0c;主要是记录一下log&#xff0c;或者history的操作记录。 主要难点&#xff1a; &#xff08;1&#xff09;一般的插件时间线例如(elementUI中的el-timeline)就是纵向的时间线&#xff0c;如果数据过多的话&#xf…

flexSlider 图片轮播插件的使用(附参数设置)

前提&#xff1a;下载插件&#xff08;官网下载地址&#xff1a;http://flexslider.woothemes.com/ 请用IE打开&#xff0c;chrome可能打不开&#xff1b;其他下载地址&#xff1a;点击打开链接&#xff09;&#xff0c;并引入flexslider.css和jquery.flexslider-min.js文件(缺…

flex

水平垂直居中也算是 CSS 领域最为常见的一个问题了&#xff0c;不同场景下的方法也各不相同&#xff0c;各有优劣。嗯&#xff0c;下面这种应该算是最便捷的了&#xff1a; <div class"g-container"><div class"g-box"></div> </div…

轮播插件——flexslider

轮播插件——flexslider, 首先&#xff0c;当我们需要轮播插件的时候呢&#xff0c;去浏览器中找自己需要的轮播插件&#xff0c;比如&#xff0c;搜索关键词“JQuery轮播插件”&#xff0c;就会出来很多网站&#xff0c;选一个点进去&#xff0c;预览效果&#xff0c;然后下载…

重现Struts1的操纵classLoader漏洞

注&#xff1a;本文仅限技术研究&#xff0c;探讨&#xff0c;测试使用. 2014年4月29日爆出的struts的可操纵classLoader的漏洞&#xff0c; 横跨struts1和struts2的所有版本。 影响面和问题的严重性几乎可以和heartbleed相媲美。 struts2要严重一些&#xff0c;对于struts1&am…