用Go写业务系统需要制造哪些轮子?

如果之前主要是用Java做业务系统 ,那么想用go重写的话还是比较痛苦的,最主要的原因就是你会发现要啥没啥,需要自己重写(造轮子)。下面列举了一些需要施工的基础设施。

错误处理

在Java中,只要你没有刻意的使用4参数的Exception构造方法去定义自己的异常类,那么默认情况下都是会记录调用栈的,这样基本上就能马上定位到事故第一现场,排查效率很高。Go则不然,如果使用默认的error机制,那么在报错的时候你得到的只是一个简单的字符串,没有任何现场信息。我在调试的时候最大的痛苦也是如此,报错了,但一时很难快速定位到出错的代码,如果是比较陈旧的项目,那就更不知道这个错误是在哪返回的了。不仅如此,因为go里如果遇到panic且没有被"捕获",那么就会直接导致进程退出,整个服务直接崩溃,这也是不可接受的。
为了解决错误现场的问题,我们可以自己定义一个结构体,它在实现error接口的同时,再添加一个PrevError的字段用于记录上层错误,类似于Java Exception的cause()方法:

type Error struct {
   
	Message string
	PrevError error
}

然后定义一个Wrap()方法,在遇到错误时,先将先前的错误传进去,然后再填写一条符合本层逻辑的描述信息:

// prevError: 原始错误
// src: 可以填写源文件名
// desp: 新error对象的错误描述
func Wrap(prevError error, src string, desp string) error {
   
	var msg string
	if "" != src {
   
		msg = "[" + src + "] " + desp
	} else {
   
		msg = desp
	}

	err := &Error{
   
		Message: msg,
		PrevError: prevError,
	}

	return err
}
if nil != err {
   
	return er.Wrap(err, sourceFile, "failed to convert id")
}

注意第二个参数src, 这里可以直接通过硬编码的形式将当前源文件名传进去,这样日志中就会出现

[xxxx.go] failed to convert id

方便错误排查。相比较标准库的runtime.Call()方法我更倾向于自己手动把文件名传进来,由于行号会经常变动就不传了,而文件名很少改动,因此这是开销最低的记录现场的方法。
有了自定义的错误以后,在最上层(一般是你的HTTP框架的H

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值