您的位置:首页 > 编程语言 > Java开发

Spring Cloud微服务交互设计总结

2017-07-13 13:14 246 查看

采用http协议进行数据交互

在spring cloud微服务交互中,基本上还是采用http协议进行数据交互。

与dubbo不同的是,http协议与编程语言无关,所以无法向dubbo一样,将抛出的Exception的内容进行序列化传到调用方,所以只能采用错误码的方式来传递异常消息。

数据的包装形式

统一数据格式

正常数据

{
"code": 2000,
"message": "bad server",
"data":{...}
}


错误数据

{
"code": 5000,
"message": "bad server"
}


区分数据与错误码

当调用正常的情况下,只需要返回完整的数据对象即可。

josnObject or jsonArray


当出现错误的情况下,只需要返回错误码即可。

在提供方接受到错误码后,可以再转化为java中的异常抛出

{
"code": 5000,
"message": "bad server"
}


总结

正常数据和错误码如果统一用一个包装类进行包装,会带来一些弊端

在取数据的时候还要进行同一的getData()操作,十分不便。

返回结果没有Exception的概念。使用try…catch的方式处理业务,可以让业务代码更集中,异常可以统一处理,避免了在业务代码中各种if…else语句乱飞,异常处理不能统一,不好组织代码。

业务场景分析

微服务间的数据调用一般可以分为

获取数据

验证数据

提交数据

数据查询

对于简单的查询,只关心查询结果数据,没必要再外包装一层getData()。

验证数据

比如authServer,在各个网关模块中都会引用authClient对前端提交过来的token进行校验。

在校验过程中可能会返回多种校验结果,校验成功并返回身份信息,token过期,token无效等。

token过期,token无效对于网关模块中并不需要进行处理,只要直接往上抛即可。

这种场景下,使用异常的异常的是比较适合的。

提交数据

在提交数据的时候,接口实现方为了流程的完整,对接受的参数进行校验,这种情况下,如果校验不通过,返回错误码。

使用try…catch很方便对业务进行统一判断,或者当前服务不知道如何处理这些异常,直接向上层服务抛出,如果使用if…else处理这些问题是有点力不从心。

try {
a.postData(obj);
a.postData(obj);
a.postData(obj);
} catch(Exception e) {
// doSomething or throw e
}


异常码是否应该统一问题

返回的业务异常码都应该有唯一的一个含义,对于上层的调用方,才能确定到底出了什么问题并决定是继续向上抛出或者处理它。

对于最外层的网关服务,给其他外部服务调用,基于以下需求,需要自定义一套异常码(外码)

当下游服务抛出很精确的异常码(内码),对于外部服务来讲,它是不关心的,或者基于之前和外部调用方定义的接口返回规范,我们必须异常信息转换。

例如,当insert数据失败抛出数据库错误,下游服务层层抛出,在网关中得到异常信息为

{
"code": 7894,
"message": "insert mysql error"
}


对外,我们并不需要提供这么明确的信息,或者这个内部使用的异常码并未在接口调用规范中声明,我们希望返回给调用者的信息为

{
"code": 5000,
"message": "bad server"
}


结论

异常码应该统一内码,外码可以与外部调用者进行协商定义自己的一套。

对于内部异常码和外部异常码的对应关系,在网关服务中声明好对应关系
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring
相关文章推荐