请问这个接口程序应该如何设计?

[复制链接]
查看11 | 回复10 | 2021-1-27 05:15:05 | 显示全部楼层 |阅读模式
使用Java语言开发一个接口程序,用来获取增量数据,请问这个接口应该如何设计,输入参数和输出参数分别是什么?
如何区分存量数据和增量数据,是通过主键ID,还是通过时间?
这个接口是对外的,外部客户调用该接口,不定期的把增量数据同步到我们的数据库中,要保证新插入的数据记录既不能多也不能少,既不能重复,也不能遗漏。
最好能给出示例代码,谢谢大家!
分 -->
回复

使用道具 举报

千问 | 2021-1-27 05:15:05 | 显示全部楼层
这个得根据实际情况,如果数据只有插入操作,类似于日志那种的,用id就可以了。如果数据还存在修改、删除等操作,那建议加一个版本字段,每次获取的时候带上版本号,版本号每次都自动往上递增,当有修改或者删除(逻辑删除)的时候记录版本号。这样可以根据版本号进行查询。
回复

使用道具 举报

千问 | 2021-1-27 05:15:05 | 显示全部楼层

/**
*合并数据,insert和update,主键可以多个
*
*@paramdbset数据库配置
*@paramtable表名
*@paramlist数据源
*@paramtargetMain表的主键
*@paramtargetColumn表的所有列(包含主键)
*@paramsourceMain数据源的主键
*@paramsourceColumn数据源中所有列(包含主键)
*@throwsException捕获异常
*/
publicstaticvoidmerge(DatabaseSetdbset,Stringtable,List>list,ListtargetMain,ListtargetColumn,
ListsourceMain,ListsourceColumn)throwsException{
if(Database.saphana.equals(dbset.database())){
Stringsql=SqlUtil.insert(dbset,table,targetColumn).replaceAll("insertinto","upsert")+SqlUtil.joinMain(dbset,targetMain);
sourceColumn.addAll(sourceMain);
BatchUtil.manage(dbset.connect(),sql,list,sourceColumn);
return;
}
ListsourceUpdateColumn=newArrayList();
for(Strings:sourceColumn){
if(!sourceMain.contains(s)){
sourceUpdateColumn.add(s);
}
}
sourceUpdateColumn.addAll(sourceMain);
Stringinsert=SqlUtil.insert(dbset,table,targetColumn),update=SqlUtil.update(dbset,table,targetColumn,targetMain);
List>inserts=newArrayList>(),
updates=split(dbset,list,inserts,table,targetMain,sourceMain);
Object[]values={inserts.size(),updates.size()};
log.info(EntityUtil.toJson(EntityUtil.create(Map.class,newString[]{"insert","update"},values,false)));
if(updates.size()>0){
manage(dbset.connect(),update,updates,sourceUpdateColumn);
}
if(inserts.size()>0){
manage(dbset.connect(),insert,inserts,sourceColumn);
}
}

回复

使用道具 举报

千问 | 2021-1-27 05:15:05 | 显示全部楼层
这个就要看你是想用什么方式来同步数据(主要是跟外部客户协调好)
我这边刚完成的一个on-premise到cloud的移植项目是以文件的方式(因为考虑到数据量可能很大)来同步增量数据的。也就是客户不定期的抽取增量数据(以时间戳为准,当然,如果你的主键ID是自动递增,用主键ID也可以)做成文件,上传到我这边的服务器,服务器监视到新文件就触发batch执行,把文件数据插入数据库。
新插入的数据记录既不能多也不能少,既不能重复,也不能遗漏,要保证这点,主要还是看你的实现方式了。我这边的做法是客户抽取数据的时间戳比上次抽取结束的时间戳稍往前一点(即抽出的数据做成的文件会有少量重复数据),batch的这边插入的时候过滤掉重复的数据。

回复

使用道具 举报

千问 | 2021-1-27 05:15:05 | 显示全部楼层
如果楼主没表达错误,并且我也没理解错的话,情况应该是:
1、你开发一个接口,给客户调用
2、数据本来是在客户那里,他定期通过调用接口,把增量数据传到你的平台上来
3、你保存增量数据
这种需求,建议:
1、开放一个http接口,让对方用http协议,以json的方式把数据发给你,当然也要考虑身份认证之类的问题
2、数据要有主键,如果客户不肯给主键,那也至少要有一个或者几个字段能够唯一确定一条记录,也就是候选键,这样才能确定发过来的数据,你是要进行更新还是进行插入
3、你收到数据时,最好给客户平台的充足的响应信息,比如对方发了100条过来,每条记录处理结果,如插入、更新、失败,这样便于对方重发。如果这样处理不方便,那么至少这100条数据的整体处理结果要响应给对方。
4、要考虑意外情况,比如客户发数据给你时,正好你的服务器当机,或者路由器死机、机房停电之类的非可抗因素造成的数据接收不了。这时你应该要求对方要有失败重发机制。

回复

使用道具 举报

千问 | 2021-1-27 05:15:05 | 显示全部楼层
还有简单点的办法是,你们订个数据格式,然后你开个ftp服务器,对方把数据传到你的FTP服务器上来,然后你定期扫描有没有新文件
回复

使用道具 举报

千问 | 2021-1-27 05:15:05 | 显示全部楼层
一般会建几张表来存放相关数据。
1.接口请求表,每次调用接口都要进行记录,客户端的id,调用时间,传输的数据量(数据记录的条数),传输批次号(可以取自增主键的值,也可以自定义),传输的数据类型(用于不同类型的数据,服务端进行不同方式的处理,也就是多态)等等。
2.接口数据表,存放每次接口传输的数据以及数据的处理状态,是做批量插入操作的,将1表中的批次号也带上,方便数据追踪,当每条数据处理完成后,更新数据状态。随着时间的推移,表长度会增加,后期考虑数据迁移,或者数据销毁。
接口设计思路。
1.要确定一次请求是传输一条记录,还是一次请求传输多条记录(多条记录时要设置最大传输条数)。
2.请求的数据中需要一个唯一标识一条记录的字段(也可以是多个字段组合形成的,业务逻辑上能够标明一条数据的ID值),用于区分是否是重复传输的数据。
3.请求数据是否有认证的需求,防止外来其他目的的数据进行非法提交。一般是通过融入tocken来进行认证。
4.请求数据是否有验证的需求,以防数据在传输过程中被别人拦截,更改后再传入服务器。一般是通过对数据和客户端ID之类的数据进行MD5(数字签名)后放入请求记录中,服务端采用相同算法进行验证。
5.请求的数据是否有加密的需求,防止数据传输过程中,被第三方机构或者程序查看,造成数据泄露。
6.上述接口的设计思路是采用推送的方式,由客户端不定时的推送的,所以,会要求客户端对推送的数据,采用失败重传的机制,方式数据丢失,服务端接收数据,要区分出哪些是重传的数据才行。
7.推送方式的接收数据,会有一个服务端过载的问题,如果同时接收的数据过大,服务端有时候会处理不过来,造成客户端推送任务的超时等异常,所以,如果可能,服务端最好是有一个判断服务端负载状况的方案,当服务端过载时,不做数据处理,直接告诉客户端,稍后再试。
8.应答数据内容,一般情况下会包含错误代码和文字解释。在接口协议的文档里面,会有一个附录,里面有错误代码表,说明,什么样的错误代码,表示什么场景下的错误。客户端可以根据错误代码,完善业务流程。
以上是楼主说的推送的方式进行数据传递。
其实,还可以拉取的方式,就是,服务器定时轮询各个数据源,如果它们有增量数据就顺便传输过来,如果没有,就应答一个没有的代码给你。

回复

使用道具 举报

千问 | 2021-1-27 05:15:05 | 显示全部楼层
这个肯定要通过ID来区分,时间的话不靠谱,可能某段时间传来的是几天前漏传的数据
回复

使用道具 举报

千问 | 2021-1-27 05:15:05 | 显示全部楼层
我感觉楼主最大的问题是如何定义增量,不是什么如何定义接口,什么数据库,什么json,什么http等。所以如何定义增量才是前提。这些要根据实际业务情况才能定义什么是增量数据。
回复

使用道具 举报

千问 | 2021-1-27 05:15:05 | 显示全部楼层
既然是别人调用接口推送数据过来做增量,就定义一个String类型的参数,接收一个JSONArray格式的字符串,再把这个JSONArray格式的字符串转成List>,这不就是增量数据么,再调用我那个方法把数据合并到数据库,就搞定了
全量也是一样,无非就是数据多一点,如果数据量特别大,就让对方多调几次接口
如果源数据删除也要同步,就再定义一个String类型的参数,接收一个JSONArray格式的字符串,再根据这个参数值做delete就行
出于安全考虑,接口最好做验签
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行