目录
一、项目结构
二、服务器配置
1、Redis在配置文件中的配置情况如下:config.json
2、读取配置文件初始化服务器配置:config.go
3、Redis连接对象实例化:redis.go
4、将Session存储方式设置为Redis:main.go
5、在Controller家口中使用redis:statis_controller.go
6、在main入口中注册:main.go
三、浏览器请求测试
四、过程踩坑
1、parse时间转换
2、iris版本
五、完整代码
1、config.json
2、config.go
3、engin.go
4、redis.go
5、statis_controller.go
6、statis_service.go
7、main.go
项目搭建过程参考:
在实战项目中使用Redis功能,首先需要进行Redis配置。本实战项目中,关与Redis的配置项包含:连接类型、地址、端口、公共前缀。以上配置项被定义包含在Iris框架的redis包中的Config结构体中,主要包含如下内容:
此处仅展示redis的配置
我们通过读取配置文件完成配置内容的读取,利用Redis配置信息实例化Redis对象,Redis实例化如下:
命令行查看:
redis desktop manager查看:
这个过程才了两个坑:
在用Go语言对时间字符串进行parse的时候踩坑,Golang time error: month out of range
经过试验,“2016-12-25 00:00:00”这种格式是可以的,“2016-12-25“这种格式在试验的时候可以,然而在某些情况却会报错,比如说当parse”2018-01-28”的时候,就会报 “month out of range”.原因不清楚,需要继续看源码研究,所以以后parse的时候,使用time模块自带的那几种格式,和“2016-12-25 00:00:00”这种格式都是ok的, 如下。
date, err := time.Parse("2006-01-02 15:04:05", "2020-05-03 19:32:15")
而这样写:d, err := time.Parse("2006-01-02", "2020-05-03")有时候正确,有时候错误,很迷啊【month out of range】
Iris+redis之版本踩坑,之前看的教程,引入redis的方法是:"github.com/kataras/iris/sessions/sessiondb/redis/service"
但是我试了的是V11和V12版本的iris,都不存在这个包!!!!坑人的地方在于,教程是2019件8月份之前的,可能使用的iris版本是V10之前的,之后已经没有service这个包了
可以看到v10的iris还是有这个包的,并且Config就定义config.go中;
而之后版本已经不存在service包了,Config直接定义在database.go中,并且具体的定义也有改动~~~
{
"app_name": "CmsProject",
"port": "9000",
"static_path": "/manage/static",
"redis": {
"network": "tcp",
"addr": "106.15.202.182",
"port": "6379",
"prefix": ""
},
"mode": "dev"
}
/**
服务端配置
*/
type AppConfig struct {
AppName string `json:"app_name"`
Port string `json:"port"`
StaticPath string `json:"static_path"`
Mode string `json:"mode"`
Redis Redis `json:"redis"`
}
/**
* Redis 配置
*/
type Redis struct {
NetWork string `json:"net_work"`
Addr string `json:"addr"`
Port string `json:"port"`
Password string `json:"password"`
Prefix string `json:"prefix"`
}
var ServConfig AppConfig
//初始化服务器配置
func InitConfig()*AppConfig {
file,err := os.Open("config.json")
if err != nil {
panic(err.Error())
}
decoder := json.NewDecoder(file)
conf := AppConfig{}
err = decoder.Decode(&conf)
if err != nil {
panic(err.Error())
}
return &conf
}
import (
"QianfengCmsProject/models"
_ "github.com/go-sql-driver/mysql" //不能忘记导入
"github.com/go-xorm/xorm"
)
func NewMysqlEngine() *xorm.Engine {
engine, err := xorm.NewEngine("mysql", "root:123456@/iris?charset=utf8")
err = engine.Sync2(
/*new(models.Permission),*/
/*new(models.City),*/
new(models.Admin),
/*new(models.AdminPermission),
new(models.User),
new(models.UserOrder),*/
)
if err != nil {
panic(err.Error())
}
//设置显示sql语句
engine.ShowSQL(true)
engine.SetMaxOpenConns(10)
return engine
}
import (
"QianfengCmsProject/config"
iris "github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/sessions/sessiondb/redis"
)
//返回redis实例
func NewRedis() *redis.Database{
var database *redis.Database
//项目配置
cmsConfig := config.InitConfig()
if cmsConfig !=nil{
iris.New().Logger().Info(" hello ")
rd := cmsConfig.Redis
iris.New().Logger().Info(rd)
database = redis.New(redis.Config{
Network: rd.NetWork,
Addr: rd.Addr + ":" + rd.Port,
Password: rd.Password,
Database: "",
MaxActive: 10,
Timeout: redis.DefaultRedisTimeout,
Prefix: rd.Prefix,
})
}else {
iris.New().Logger().Info(" hello error ")
}
return database
}
type StatisController struct {
//iris框架自动为每个请求都绑定上下文对象:可作为接受参数
Ctx iris.Context
//admin功能实体:引入Service接口
Service service.StatisService
//session对象:存储session信息
Session *sessions.Session
}
var (
ADMINMODULE = "ADMIN_"
USERMODULE = "USER_"
ORDERMODULE = "ORDER_"
)
/* /statis/admin/2019-03-10/count*/
func (sc *StatisController) GetCount() mvc.Result {
path := sc.Ctx.Path()
var pathSlice []string
if path != "" {
pathSlice = strings.Split(path, "/")
}
//不符合请求格式
if len(pathSlice) != 5 {
return mvc.Response{
Object: map[string]interface{}{
"status": utils.RECODE_FAIL,
"count": 0,
},
}
}
//将最前面的去掉
pathSlice = pathSlice[1:]
model := pathSlice[1]
date := pathSlice[2]
var result int64
switch model {
case "user":
fmt.Println("GetCount--->user")
case "order":
fmt.Println("order--->user")
case "admin":
adminStatis := sc.Session.Get(ADMINMODULE + date)
if adminStatis != nil {
adminStatis = adminStatis.(float64)
return mvc.Response{
Object: map[string]interface{}{
"status": utils.RECODE_OK,
"count": adminStatis,
},
}
} else {
result = sc.Service.GetAdminDailyCount(date)
sc.Session.Set(ADMINMODULE, result)
}
}
return mvc.Response{
Object: map[string]interface{}{
"status": utils.RECODE_OK,
"count": result,
},
}
}
//统计功能模块接口标准
type StatisService interface {
GetAdminDailyCount(date string) int64
}
//统计功能服务实现结构体
type statisService struct {
Engin *xorm.Engine
}
func NewStatisService(engin *xorm.Engine) StatisService {
return &statisService{
Engin: engin,
}
}
func (ss *statisService) GetAdminDailyCount(date string) int64 {
if date == "NaN-NaN-NaN" { //当日增长数据请求
date = time.Now().Format("2006-01-02")
}
//查询如期data格式解析
startDate, err := time.Parse("2006-01-02 15:04:05", date+" 00:00:00")
if err != nil {
return 0
}
endDate := startDate.AddDate(0, 0, 1)
result, err := ss.Engin.Where("create_time between ? and ? and status = 0",
startDate.Format("2006-01-02 15:04:05"),
endDate.Format("2006-01-02 15:04:05")).Count(models.Admin{})
if err != nil {
return 0
}
fmt.Println(result)
return result
}
func main() {
app := newApp()
//应用App设置
configation(app)
//路由设置
mvcHandle(app)
config := config.InitConfig()
addr := "localhost:" + config.Port
app.Run(
iris.Addr(addr), //在端口8080进行监听
iris.WithoutServerError(iris.ErrServerClosed), //无服务错误提示
iris.WithOptimizations, //对json数据序列化更快的配置
)
}
//构建App
func newApp() *iris.Application {
app := iris.New()
//设置日志级别 开发阶段为debug
app.Logger().SetLevel("debug")
//注册静态资源
app.HandleDir("/static", "./static")
app.HandleDir("/manage/static", "./static")
app.HandleDir("/img", "./static/img")
//注册视图文件
app.RegisterView(iris.HTML("./static", ".html"))
app.Get("/", func(context context.Context) {
context.View("index.html")
})
return app
}
/**
* 项目设置
*/
func configation(app *iris.Application) {
//配置 字符编码
app.Configure(iris.WithConfiguration(iris.Configuration{
Charset: "UTF-8",
}))
//错误配置
//未发现错误
app.OnErrorCode(iris.StatusNotFound, func(context context.Context) {
context.JSON(iris.Map{
"errmsg": iris.StatusNotFound,
"msg": " not found ",
"data": iris.Map{},
})
})
app.OnErrorCode(iris.StatusInternalServerError, func(context context.Context) {
context.JSON(iris.Map{
"errmsg": iris.StatusInternalServerError,
"msg": " interal error ",
"data": iris.Map{},
})
})
}
//MVC 架构模式处理
func mvcHandle(app *iris.Application) {
//启用session
sessManager := sessions.New(sessions.Config{
Cookie: "sessioncookie",
Expires: 24 * time.Hour,
})
//获取redis实例
redis := datasource.NewRedis()
//设置session的同步位置为redis
sessManager.UseDatabase(redis)
//实例化mysql数据库引擎
engine := datasource.NewMysqlEngine()
//管理员模块功能
adminService := service.NewAdminService(engine)
admin := mvc.New(app.Party("/admin")) //设置路由组
admin.Register(
adminService,
sessManager.Start,
)
//通过mvc的Handle方法进行控制器的指定
admin.Handle(new(controller.AdminController))
//统计功能模块
statisService := service.NewStatisService(engine)
statis := mvc.New(app.Party("/statis/{model}/{date}/"))
statis.Register(
statisService,
sessManager.Start,
)
statis.Handle(new(controller.StatisController))
}