ginchat:为原有消息表添加唯一id

由于原本是在单机下运行,且原本的消息id依赖与mysql的自增id

然而这样的id有较大的缺点:

1. 消息的条数会堆积很多,如果只由一张表来存储可能不够,所以后续也需要将消息表进行分表操作(待实现),这样使用自增id就会导致由重复id了。

2.自增id的规律比较明显,不安全。

3.使用mysql数据库自增id会影响数据库性能,当大量的消息来的时候需要进行大量的自增id操作,由于mysql操作时会加锁,这样会影响性能。

所以我决定将消息表改为全局唯一id。

方法一 使用redis生成唯一id

使用64位的数字来存储id,前32位为时间戳,后32位为序列号,使用redis来存储每个时间戳的最大序列号。当每个节点收到消息后,会访问redis来得到最新id,id的唯一性就由redis来保证了。这样能够保证每条消息的唯一性了。

由于id依赖于redis生成,性能较高。

方法二

使用雪花算法生成唯一id,雪花算法有时间戳(41),机器id(10),序列号(12),这样就不会在不同机器上生成相同id了。可以直接调用github.com/bwmarrin/snowflake包来获得id。

这种方法不依赖与redis,直接在应用程序中调用就行。在这里我使用第二种方法进行。

添加雪花算法生成id的方法

1.在utils包下创建snowflake.go文件

package utils

import (
	"time"

	sf "github.com/bwmarrin/snowflake"
)
 
var node *sf.Node
 
func InitSnowFlake(startTime string, machineID int64) (err error) {
	var st time.Time
	st, err = time.Parse("2006-01-02", startTime)
	if err != nil {
		return
	}
	sf.Epoch = st.UnixNano() / 1000000
	node, err = sf.NewNode(machineID)
	return
}
 
func GenID() int64 {
	return node.Generate().Int64()
}

2.接着在main函数种添加其初始化即可

func main() {
	//传入参数为端口号
	if len(os.Args) < 2 {
		fmt.Println("Usage: go run main.go <port_number>")
		return
	}
	//雪花算法初始化
	tempid, _ := strconv.Atoi(os.Args[1])
	machineid := int64(tempid) - 8080
	if err:=utils.InitSnowFlake("2020-09-10", machineid);err!=nil {
		fmt.Println("InitSnowFlak error")
		return 
	}
	utils.InitConfig()
	utils.InitMySQL()
	utils.InitRedis()
	InitTimer()

	r := router.Router()
	r.Run(":" + os.Args[1])
	// r.Run(viper.GetString("port.server")) // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

修改数据库的message表 

将gorm.model去掉,保留其原本的三个时间变量。再为其生成一个唯一messageid。

type Message struct {
	//消息id
	MessageId  int64  `gorm:"primarykey"`
	CreatedAt  time.Time
	UpdatedAt  time.Time
	UserId     int64     // 发送者
	TargetId   int64     //接收者
	Type       int       //发送类型 1私聊 2群聊 3心跳
	Media      int       //消息类型 1文字 2表情包 3语音 4图片
	Content    string    //消息内容
	CreateTime uint64    //创建时间
	ReadTime   uint64    //读取时间
	Pic        string    //图片
	Url        string    //URL相关
	Desc       string    //描述
	Amount     int       //其他数字统计
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值