redis缓存数据库安装与golang中使用
二月 22, 2019
最近公司在写数据可视化平台的一个项目,提供给公司运营内部使用。关于运营用户这方面,打算直接使用对应app的运营管理平台(另外一个使用java服务端)调用登陆接口,java服务端已经编写好接口,这边golang直接调用他们那的接口,这边处理存储请求获取到的用户信息和存储token的功能,就有了redis缓存相关的操作。在测试中,本来是用的运营管理平台的redis缓存服务器,不过我打算在我自己的服务器,直接搭建个redis缓存数据库。仅记此文章,作为查询和学习的记录。
安装
- 在redis官网中下载tar.gz压缩包,保证最新版,在你当前的目录下(我的是在/home/download/中)
1
2
3
4
5# 解压缩
tar xzf redis-x.x.xx.tar.gz
# cd进去进行编译
cd redis-x.x.xx.tar.gz
make - 编译完,在当前目录下会生成src的目录,编译完成的所有项都在这里面(redis-server、redis-cli)
1
2
3
4
5# 当前目录:/home/download/redis-x.x.xx
# 将redis文件移动到/usr/local/目录下,不移动也可以,我不打算做环境变量,保证我每次都能记得文件包在哪
# 请务必记得也移动redis.conf配置文件
cp -r ./src /usr/local/redis
cp ./redis.conf /usr/local/redis/config/配置
- 修改redis.conf配置文件
1
2
3
4
5
6
7# /usr/local/redis/config/redis.conf
vi redis.conf
# 关于redis.conf中的项,可以去查询文档,这边修改这些项
requirepass xxxxxxxx # 开启auth密码验证(如果在服务端中设置了密码登陆,这边不设置的话,会出现“ERR Client sent AUTH, but no password is set”)
bind 0.0.0.0 # 如果在服务器厂商那开放了6379端口,任然不能从本地连接服务器redis的话,可以进行设置
daemon yes # 设置为守护进程,这个不多说
使用
- 开启持久化和配置文件启动
1
2# /usr/local/redis
./redis-server ./config/redis.conf --appendonly yes - 关于redis持久化的文章:谈谈Redis持久化(下)——AOF(Append Only File)
1
2
3# 接上
# 使用redis终端进行测试
./redis-cli - 在本地中的使用,本地使用的是windwos端的RedisDesktopManager
Golang代码编写
直接上代码吧
1 | # Config/config.ini |
1 | // Middlewares/Cache/redis.go |
在登陆控制器中使用
- ViewModel 返回数据格式声明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// ViewModel/Login/v_login.go
package Login
type ResultData struct {
CreateTime int64 `json:"createTime"`
UserId int `json:"userId"`
Token string `json:"token"`
RealName string `json:realName`
}
type Vresult struct {
Code int `json:"code"`
Data ResultData `json:"data"`
}
type Verror struct {
Code int `json:"code"`
ThrowType string `json:"throwType"`
Message string `json:"message"`
} - LoginController 登陆接口方法编写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187// Controllers/LoginController.go
package Controllers
import (
"encoding/json"
"fmt"
"github.com/astaxie/beego/validation"
"github.com/kataras/iris"
"io/ioutil"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"virtual-data/Middlewares/Cache"
"virtual-data/Middlewares/setting"
VMlogin "virtual-data/ViewModel/Login"
)
func Login(ctx iris.Context) {
userName := ctx.Request().FormValue("username")
passWord := ctx.Request().FormValue("password")
valid := validation.Validation{}
valid.Required(userName, "username").Message("账号不能为空")
valid.Required(passWord, "password").Message("密码不能为空")
if !valid.HasErrors() {
result, err := requestJavaServerService(userName, passWord)
if err != nil {
ctx.JSON(Result(http.StatusBadGateway, err))
} else {
ctx.JSON(result)
}
} else {
ctx.JSON(Result(http.StatusBadRequest, valid.Errors[0].Message))
}
}
/**
* 请求java服务端接口,返回请求成功或错误的值
* @method requestJavaServerService
* @param username string
* @param password string
* @return interface{}
* @return error
*/
func requestJavaServerService(username, password string) (interface{}, error) {
client := &http.Client{}
var err error
var urlAddr string
userInfo := url.Values{}
userInfo.Add("userName", username)
userInfo.Add("password", password)
sec, err := setting.Cfg.GetSection("request")
if err != nil {
fmt.Errorf("Fial to get config section 'request': %s\n", err)
}
// 在配置文件中配置好的请求地址
urlAddr = sec.Key("url").String()
request, err := http.NewRequest(
"POST",
urlAddr,
strings.NewReader(userInfo.Encode()),
)
request.Header.Set("Content-type", "application/x-www-form-urlencoded")
request.Header.Set("cms-token", "null")
request.Header.Set("cms-channel", "0")
if err != nil {
return nil, err
}
parseObj, err := parseResponseBody(client, request)
if err != nil {
return nil, err
}
return parseObj, nil
}
type tempBody struct {
Code int `json:"code"`
Data interface{} `json:"data"`
}
/**
* 处理请求成功的body
* @method parseResponseBody
* @param client *http.Client
* @param request *http.Request
* @return obj interface{}
* @return err error
*/
func parseResponseBody(client *http.Client, request *http.Request) (obj interface{}, err error) {
var resultObj VMlogin.Vresult
var errorObj VMlogin.Verror
var tempObj tempBody
resp, err := client.Do(request)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
err = json.Unmarshal(body, &tempObj)
if err != nil {
return nil, err
}
if tempObj.Code == 200 {
_ = json.Unmarshal(body, &resultObj)
obj = resultObj
if err = cacheManagerService(resultObj); err != nil {
return nil, err
}
} else {
_ = json.Unmarshal(body, &errorObj)
obj = errorObj
}
return obj, nil
}
/**
* 设置处理缓存的工厂
* @method cacheManagerService
* @param resultObj VMlogin.Vresult
* @return error
*/
func cacheManagerService(resultObj VMlogin.Vresult) error {
var oldResultObj VMlogin.Vresult
var redisKey string
var redisValue string
var err error
// 组合查询用户信息的声明和赋值
redisKey = FormatRedisString(REDIS_KEY_USER, resultObj.Data.UserId)
redisJsonValue, _ := json.Marshal(resultObj.Data)
redisValue = string(redisJsonValue)
// 查询是否存在此用户
infoVal, _ := Cache.Instance().Get(redisKey)
// json反序列化查询到的json字符串,将存储在缓存中的值赋值到一个变量上
_ = json.Unmarshal([]byte(infoVal), &oldResultObj.Data)
// 如果返回空字符串,则是新用户,创建新的缓存
// 否则根据缓存的token组合去将旧的缓存删除,覆盖新的用户信息和创建新的token
if infoVal == "" {
// 设置新的用户信息缓存
err = Cache.Instance().Set(redisKey, redisValue, 744 * time.Hour)
if err != nil {
return err
}
// 设置新的token信息缓存
redisKey = FormatRedisString(REDIS_KEY_TOKEN, resultObj.Data.Token)
redisValue = strconv.Itoa(resultObj.Data.UserId)
err = Cache.Instance().Set(redisKey, redisValue, 744 * time.Hour)
if err != nil {
return err
}
} else {
// 声明并赋值旧的token信息
oldToken := oldResultObj.Data.Token
// 删除旧的token
err = Cache.Instance().Del(FormatRedisString(REDIS_KEY_TOKEN, oldToken))
if err != nil {
return err
}
// 设置覆盖新的用户信息
err = Cache.Instance().Set(redisKey, redisValue, 744 * time.Hour)
if err != nil {
return err
}
// 设置新的token
redisKey = FormatRedisString(REDIS_KEY_TOKEN, resultObj.Data.Token)
redisValue = strconv.Itoa(resultObj.Data.UserId)
err = Cache.Instance().Set(redisKey, redisValue, 744 * time.Hour)
if err != nil {
return err
}
}
return nil
}
查看评论