1,Log问题(吃过亏才会重视)
游戏上线后,随着玩家数据量的剧增,许多bug就会随之出现,但同时有些bug是很难复现的,这时候定位问题就不可能通过打断点来进行查找,这时候完整的log信息才是定位问题的关键。
log等级:
Trace:突出强调程序运行过程
Debug:調試信息
Info:突出一些关键信息打印
Warn:出现一些按理不该出现的问题
Fatal:严重问题,影响程序运行
2,recover使用(循环时处理/加锁时处理)
循环时处理:当在一个循环中出现panic时,需要在循环内部进行recover,以保证重新接管该线程时逻辑继续,而不至于线程销毁,逻辑不再执行。如下:
go Start()
//错误代码,如果Start函数上层没有for循环,当发生错误时,recover接管线程后再也进不了这个逻辑中,从而出现问题
func (this *TMail) Start () error {
defer func() {
if err := recover(); err != nil {
logger.Fatal("error is %v", err)
}
}
for {
select {
case A:
//dosomething
case B:
//dosomething
default:
//dosomething
}
}
return nil
}
//正确代码
func (this *TMail) Start () error {
for {
_start()
}
return nil
}
func (this *TMail) _start() error {
defer func() {
if err := recover(); err != nil {
logger.Fatal("error is %v", err)
}
}()
select {
case A:
//dosomething
case B:
//dosomething
default:
//dosomething
}
return nil
}
加锁时处理:加锁后,出现panic,导致未解锁,出现问题。如下
在这里插入代码片
3,线程panic崩溃,使得channel读端出错,导致channel写端阻塞,主线程阻塞。
解决方案:给channel加个大的buffer(1000左右),当buffer写满时(不一定是bug引起(网络),但需要打log进行报警,因为很大可能是读端出错)。所以这里需要注意:在有channel操作时,需要加default打对应Log.如下:
func SendMail(mail *TMail) {
select {
case: MyChannel <- mail:
default:
Loggler.Warning("channel is full!!!")
}
}
4,某一时刻,系统向每一位在线玩家邮件发奖,峰值太大。
解决方案:系统向每一位玩家广播红点,玩家看到红点后点击查看领取时再对其进行发奖,这样的操作由“网络延迟”和“玩家自身操作”来分散峰值。