如何做好上下游对接

循循善诱
• 阅读 1739

自己的模块,常常要对接上下游,如何在对接的过程中,保证正确性呢?
一般和上下游对接的有两种方式:

一:接口对接

在接口对接中,需要注意下面的点。
1,首先和上下游约定接口的功能是什么,这往往和承载的业务有关系,需要提前在产品宣讲阶段+产品评审阶段定义清楚,每个接口预期的功能都应该准确的描述在接口注释上。

2,约定好接口的功能后,紧接着就是约定好接口的入参和返回值数据结构,确定参数数据结构中哪些是必传的,哪些是不必传的,他们的传值范围是什么?
确定返回值的数据结构是什么。什么时候失败,什么时候成功等等,都需要定义清楚。这里比较推荐常用的yapi管理接口。
另外注意字典维护,比如sex中的"未知" "男" "女",是统一使用中文表示,还是0 1 2编码表示,还是英文表示。如此这类的,都要标准化。另外字段名称也尽量统一。
对于接口返回个人建议使用下面这种通用的数据结构

public class Message<T> {
 private boolean success
 private String errcode
 private String errmsg
 private T data

public Message(boolean success,String errcode,String errmsg,T data){
this.success=success;
this.errcode=errcode;
this.errmsg=errmsg;
this.data=data;
}

// 返回成功
 public Message success(T  data){
  return new Message(true,"0","",data);
 }

// 返回失败
 public Message fail(String msg){
   return new Message(false,"400","param is illegal",null);
 }
}

对于返回成功还是失败,这里有一些案例值得思考

pubilc User findOneUserById(Long userId){
// 这个userId应该是之前系统生成的,那么根据这个userId,在数据中应该一定能查到数据,但如果查不到呢?此时应该返会失败。
}

pubilc User findOneUserByName(String selectName){
//根据selectName去搜索的时候,在数据库中可能查不到,这种情况是正常的,因此要返回成功。提示没有数据。
}

还有比如根据用户手机号作为唯一标识,插入用户信息,如果第一个请求已经插入成功,当第二个请求携带相同的参数插入时,接口是返回成功,还是返回失败?这在上下游对接的过程中比较重要

3,接口处理
3.1在接口impl层面的第一件事情,先打印请求参数日志。在接口实现的关键点也需要打印日志。这样方便后续定位问题边界。

3.2紧接着第二件事就是按照约定的数据结构进行参数校验,对错误的参数请求做好拦截,防止他们捣乱系统,破坏数据。这一点可能很多人忽略,但其实是最重要的

3.3对于非必传参数,接口应该如何处理,也需要明确,这一点一般反应在该接口在不同的场景中使用。

3.4 处理异常,不要使用抛异常的方式退出某个方法,并毫无保留的把异常信息传递给上下游,除非方法有捕获异常,并且知道怎么处理。

3.5 明确返回值和错误信息:如果处理成功返回success=true。如果失败,不能仅仅返回失败就完事了,必须在返回信息明确的告知上下游是什么原因导致这次请求处理失败,是参数校验不通过,缺省哪些值?还是要操作的数据,在数据库中不存在?等等。

3.6 接口开发完毕,对接口进行单元测试,我个人认为这是很重要的一步:根据步骤1的注释,必须按照这些预期功能进行测试,如果预期提供的功能,在单元测试中成功通过,那么说明该接口提供的功能基本上是可靠的,可以和上下游对接了。但这还不够,单元测试的参数最好分各种各样的情况,如果你模拟的参数情况比真实用户发出的参数组合多,并且返回都按照预期响应,那么该接口可以说是合格的了。这样,你就可以拍着胸脯说没有bug了,可以去开发另外的接口了。

一般来说,接口对接做好上面就足够了,但是还不够 !接口设计的时候还必须考虑以下事情:

a,幂等:也就是说相同的请求来了(可能是多线程并发请求,也可能是重复请求),该接口如何实现这一点,这一般反应在增删改等接口。
接口该怎样支持幂等?一种方式是利用数据库的唯一索引来。还有利用分布式锁(为什么不用jvm锁?)

b,分布式事务:比如该接口是一个扣减库存的接口,那么在和上下游对接的过程中,需要注意如何处理分布式事务。谁负责解决分布式事务?
在众多的项目经验,我得出一个结论,分布式事务,一定是利用最终一致性+ack的思想解决,两阶段,三阶段不适合大规模的系统

c,并发:这可能是最容易忽略的,很多神奇的问题,都是由于这个而找不到原因,跟个鬼一样。特别是在soa和微服务架构,往往会利用k8s部署多个pod情况下。所以对于提供的写操作接口,一定要研究有没有并发问题。如果有,往往是利用分布式锁解决(除非只运行一个pod)

d,性能:有些业务处理可能比较复杂,一次响应需要太久的时间,这对使用者来说,都是一次不好的体验,在上下游对接中,我们提供的接口可能仅仅是整个业务中的一环,因此需要注意接口的性能。
有书籍说"如果能够正常运行,就不要进行性能优化,否则会带来灾难",这句话不全对。
首先需要分析是慢在哪里了。其中我觉得需要快速得出结论,是否因为数据组织,系统架构不合理而导致查询本身就很慢,如果是,那么就需要快速的商讨对策了。为什么这一点很重要?如果在接口上线一段时间才发现这个问题,再去调整数据,调整系统架构那往往是灾难。
如果不是这些问题,那么可以建一些todo,或许是加缓存,或许是算法优化等等

e,请求量限制:
有的时候,可能时间很紧迫,上下游随便扔过来一个查询需求,如果没有时间做好需求调研,那么功能实现后,一定要加上限流的策略。这些组件有很多比入sentinel。一定要保护好自己的系统。

f,模块:
相同功能的接口,最好放在统一的模块中进行管理

二:消息对接

利用mq等中间件消息
消息对接和接口对接大部分都是相同的。

不同之处在于,消息处理完毕不会立刻返回上下游,此次消息的处理结果是什么。因此当前系统,必须对处理失败的消息,做好响应。

1,首先处理消息有个小技巧,接消息的类,不要进行进行任何业务逻辑处理,仅仅打印消息日志就好了。应该有单独的一个类的方法,来实现消息的处理。这样做的好处,在于把消息也看成一次普通的接口请求,这样也方便后续做单元测试。所以设计消息的处理,大部分可以参照接口的设计。

2,对重要的消息,一定做好记录,后续可查,中间件上的消息一般保存7天,如果某天被告知前7天的某条数据处理有问题,如果没有记录,就不得而知了。如果找不到原因,用户可不认这一点。

3,消息处理做好幂等。

4,处理失败的消息,记录好失败的原因,根据业务判断是否需要进行重试。

5,做好单元测试

如果做到以上,消息对接不会有太大的问题,但是还需要考虑以下事情:
a,消息是否有序:消息是否需要按照顺序来处理,如果和发送没有约定好这一点,可能会出现莫名奇妙的bug。可以利用kafka的分区有序性来实现

b,消息量大小:消息的数据级是什么?如果数据量太大,是按照pod扩容,还是说把相关代码单独维护出去,组成一个集群

c,延迟:一般来说,消息处理都是异步处理,所以它存在一定的并发问题,可能在消息处理的过程中,需要的数据还没有完成。那么该消息可能要进行延迟处理,而不是直接丢掉。

最后,记录点非技术的问题:
1,在和上下游对接中,要和同事搞好关系,在生产环境遇到问题不要甩锅,要及时帮忙排查问题出现的原因和提供技术解决方案。

2,以自己负责的业务为中心,梳理好所有相关的功能,这样当出现问题时,才能第一时间察觉到是哪个环节出现问题了。

点赞
收藏
评论区
推荐文章
VOP 消息仓库演进之路|如何设计一个亿级企业消息平台
VOP作为京东企业业务对外的API对接采购供应链解决方案平台,一直致力于从企业采购数字化领域出发,发挥京东数智化供应链能力,通过产业链上下游耦合与链接,有效助力企业客户的成本优化与资产效能提升。本文将介绍VOP如何通过亿级消息仓库系统来保障上千家企业KA客户与京东的数据交互。
Easter79 Easter79
3年前
Swagger生成的接口需要权限验证的处理方法
通常开发API的时候需要对接口进行权限验证,而我们在使用Swagger生成接口文档界面的时候,直接调用需要权限验证的接口会提示"当前用户没有登陆"!(https://oscimg.oschina.net/oscnet/b70cf279698211b11cb1c2530d42b4958c3.jpg)为了解决此问题,我们需要更改一下Swagger的配
Wesley13 Wesley13
3年前
GB28181对接视频流
   今天抽空写下以GB28181的方式获取摄像机视频流以备后用,同时也希望能帮助到正着手开发GB28181对接视频的同学,这块的资料实在不多。今天讲的内容不涉及到平台对接,平台对接下次有时间再讲,平台对接相对更麻烦点。通过GB28181获取摄像机视频流,首先需要摄像机支持GB28181,如何知道摄像机是否支持GB28181协议呢?请看下图:
Stella981 Stella981
3年前
C#在与java对接时候的UrlEncode的坑
最近与建行接口做对接和与一家短信运营商做对接时候遇到了这个坑在java中对UrlEncode时候哪些url非安全字符被转为%数字和大写字幕组合,比如:zhangsan/d会被转为 zhangsan%2Fd ,而在C中确被转为 zhangsan%2fd 。注意大小写的差异然后就导致了各种加密验签无法通过的情况。于是就自己在C原来的Url
Wesley13 Wesley13
3年前
MQ如何快速实现流量削峰填谷
问:站点与服务,服务与服务上下游之间,一般如何通讯?答:有两种常见的方式!(https://static.oschina.net/uploads/space/2017/0414/092333_BK2q_2441327.png)一种是“直接调用”,通过RPC框架,上游直接调用下游。!(https://static.oschina.net
Wesley13 Wesley13
3年前
API 资源隔离系统设计与实现
_(马蜂窝技术原创内容,公众号ID:mfwtech)_Part1背景大交通业务需要对接机票、火车票、租车、接送机等业务的外部供应链,供应商的数据接口大部分通过HTTP、HTTPS等协议进行通信。为了保证开发进度并支持集成测试时进行多场景支持,我们往往需要对供应商接口进行MOCK。之前我们在开发环境和
kenx kenx
2年前
爆肝一周,我开源了ChatGPT 中文版接口,官方1:1镜像支持全部 官方接口
这里实现我之前文章承诺承接上文现在ChatGPT提供了api接口可以让我自己对接去实现我们自己想要gpt应用,但是由于一些原因,国内也不开放接口,所以我就1:1自己对接了官方所有接口。大家可以通过我的接口轻松实现一个自己定制化的聊天ai应用小程序接口功能聊
邢德全 邢德全
1年前
ERP对接MES的3种类型的接口方式
在数字化工厂的规划建设中,信息化系统的集成,既是重点,但同时也是难点。ERP和MES对接时,ERP主要负责下达生产计划,万界星空MES是执行生产计划,二套系统在数据交互时,需要确保基础数据的一致性,这就涉及到基础数据的接口。
API 小达人 API 小达人
1年前
国投证券如何引领金融行业的 API 治理创新?
在开发、对接阶段,因为API资产统一托管在平台上,因此可以通过API文档快速生成MockAPI,前端开发人员只需要通过MockAPI就可以快速对接后端接口,将前后端开发工作解耦,提高工作效率。在测试阶段,测试人员可以基于API文档快速创建单元测试用例,API文档和测试用例之间自动形成绑定关系。当API发生变更的时候,平台可以将数据同步到测试用例,并且可以与CI/CD流程结合,实现单元测试用例的自动化回归测试工作,并且将测试报告推送给相应邮箱。
快速对接淘宝API接口的详细步骤
快速对接淘宝API接口,首先需要在淘宝开放平台注册成为开发者,创建应用获取必要的AppKey和AppSecret,然后根据淘宝API文档进行开发。下面是一些基本步骤和示例代码,帮助你快速开始:第一步:成为淘宝开放平台的开发者先去淘宝开放平台注册个账号,成为
反向海淘跨境代购”业务的平台或系统,并无缝对接淘宝/1688的官方API数据接口
反向海淘跨境代购”业务的平台或系统,并无缝对接淘宝/1688的官方API数据接口