Iris+Redis实战项目应用

 

目录

一、项目结构

二、服务器配置

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


项目搭建过程参考:

  • Iris搭建一个完整的go web项目过程——管理员登录功能开发:https://blog.csdn.net/qq_38151401/article/details/105907576

一、项目结构

Iris+Redis实战项目应用_第1张图片

二、服务器配置

在实战项目中使用Redis功能,首先需要进行Redis配置。本实战项目中,关与Redis的配置项包含:连接类型地址端口公共前缀。以上配置项被定义包含在Iris框架的redis包中的Config结构体中,主要包含如下内容:

  • Network: 连接类型。TCP
  • Addr: 即将连接的Redis服务主机IP。本实战项目的Redis服务部署在本机,因此主机ip为127.0.0.1。Redis服务默认端口为6379。因此,Addr在本实例项目中的配置值为127.0.0.1:6379。
  • Password: 登陆Redis的密码。默认配置为空。
  • Prefix:为要保存的所有的内容设置公共的前缀。默认设置为空。
  • IdleTimeout:设置Redis中的生效时长。这里我们设置time.Duration(24) * time.Hour。在实际的开发过程中,开发者可以根据自己的需求设定Redis的生效时长。

此处仅展示redis的配置

1、Redis在配置文件中的配置情况如下:config.json

Iris+Redis实战项目应用_第2张图片

2、读取配置文件初始化服务器配置:config.go

Iris+Redis实战项目应用_第3张图片

3、Redis连接对象实例化:redis.go

我们通过读取配置文件完成配置内容的读取,利用Redis配置信息实例化Redis对象,Redis实例化如下:

Iris+Redis实战项目应用_第4张图片

4、将Session存储方式设置为Redis:main.go

Iris+Redis实战项目应用_第5张图片

5、在Controller家口中使用redis:statis_controller.go

Iris+Redis实战项目应用_第6张图片

6、在main入口中注册:main.go

Iris+Redis实战项目应用_第7张图片

三、浏览器请求测试

命令行查看:

Iris+Redis实战项目应用_第8张图片

redis desktop manager查看:

Iris+Redis实战项目应用_第9张图片

四、过程踩坑

这个过程才了两个坑:

1、parse时间转换

在用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实战项目应用_第10张图片

2、iris版本

Iris+redis之版本踩坑,之前看的教程,引入redis的方法是:"github.com/kataras/iris/sessions/sessiondb/redis/service"

但是我试了的是V11和V12版本的iris,都不存在这个包!!!!坑人的地方在于,教程是2019件8月份之前的,可能使用的iris版本是V10之前的,之后已经没有service这个包了

Iris+Redis实战项目应用_第11张图片

可以看到v10的iris还是有这个包的,并且Config就定义config.go中;

而之后版本已经不存在service包了,Config直接定义在database.go中,并且具体的定义也有改动~~~

五、完整代码

1、config.json

{
  "app_name": "CmsProject",
  "port": "9000",
  "static_path": "/manage/static",
  "redis": {
    "network": "tcp",
    "addr": "106.15.202.182",
    "port": "6379",
    "prefix": ""
  },
  "mode": "dev"
}

2、config.go

/**
服务端配置
 */
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
}

3、engin.go

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
}

4、redis.go

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
}

5、statis_controller.go

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,
		},
	}
}

6、statis_service.go

//统计功能模块接口标准
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
}

7、main.go

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))
}

 

你可能感兴趣的:(golang)