数据传输协议sftp(系统间数据对接传输)

数据传输协议sftp(系统间数据对接传输)(1)

数据传输协议sftp(系统间数据对接传输)(2)

一个系统装再多数据,不与其他系统交互,那也是孤岛系统,孤独没女朋友。

一个系统若很外向,不断撩拨周围的系统,也乐意被撩拨,成为了众系统中的“交际花”,那么这货基本就是中台的性质。

而更多的系统是介于上述两种极端之间的。像人一样,自己搞生产,也要参与社交——就是系统之间的数据对接。

对接的本质是为了实现数据信息的传输。

在后端产品的世界里,各子系统之间,或与外部系统之间的对接非常常见。

作为产品经理,不仅要知道数据从哪来,还要理清楚获取数据之后的握手方式、运算逻辑、异常规则、容错机制、数据日志等等。

本文尝试聊聊如下话题:

  • 数据传输的场景和意义

  • 数据传输的方式

  • 数据传输的处理机制

  • 数据传输的注意事项

原文地址:数据传输协议sftp(系统间数据对接传输)(3)

因为一些关键参数牵扯到业务的唯一性维度,这些都在产品经理调研的时候获知的,而这些可能开发根本不知道。因此产品经理要给出轮廓和大概方向。

7)数据流转的时效

接口创建之后,如果是接收的对方数据库中的信息,那么上线之后,要考虑先进行数据的初始化(保持基础数据一致)。然后确保后续双方是同步的。

同步的机制和要求是在定义方案的时候就确定的。那么怎么确保同步呢?方法是两种:触发式和定时任务。

触发式就是一旦一个参数值满足条件,则触发同步。

数据传输协议sftp(系统间数据对接传输)(4)

定时任务式一般用在不知道数据源什么时候更新,需求方就要设置一个定时任务的脚本,隔一段时间查询一次。请求的频率需要与更新的频率相协调。

8)总结接口的特点

优点:时效性强,可以触发式实时问答。容易控制权限,通过传输层协议https,加密传输的数据,使得安全性提高。通用性比较强,无论客户端是.net架构,java,python 都是可以的。

缺点:服务器和客户端必须同时工作,当服务器端不可用的时候,整个数据交互是不可进行。当传输数据量比较大的时候,严重占用网络带宽,可能导致连接超时。使得在数据量交互的时候,服务变的很不可靠。

9)相关概念扩展

API:即“应用程序编程接口”,是一些预先定义的函数,无需访问源码或理解内部工作机制的细节,即可调用的对象。比如和Windows系统沟通,需要调用Windows提供得API。和新浪微博进行沟通,需要调用新浪微博提供得Api。其实它就是一个软件系统对其他软件系统提供得服务。

open api:是指对外开发的接口,比如百度地图API、facebook的API等。

SDK(“软体开发工具包”):可以理解为api的集合,也就是封装后的API为,功能更完善。

http接口:是基于接口的传输方式(HTTP协议)来命名的,当然也有基于其他协议传输的接口。

比如:

和Windows系统沟通,需要调用Windows的API(CreateWindowEx, bitblt,等等),是C语言函数形式的接口。

和.Net框架进行沟通,需要调用.Net提供得Api,是以C#,VB函数/类形式的接口。和新浪微博进行沟通,需要调用新浪微博提供得Api,是以Http请求形式的接口。

API接口的叫法相对http接口叫法更笼统和概念化一些。因此在写方案的时候,http接口和API接口都可以,在具体的场景开发都可以理解的。

了解更多,也可以看下这本书:

2、数据库对库同步

接口完成的是信息的传输,相对来说比较保守,易于保护敏感信息。而数据库同步实际就是表对表的共享,相对接口就大方多了,因此多发生在企业内部两小无猜的系统之间。

数据库同步有这么几种办法:

1)使用中间表

例如:B系统要用A系统的数据,可以新建一个数据库DB,A系统将数据写入DB,B系统再到数据库中读取数据。

也就是将数据放进一个中间表中,A、B两个系统都对这个表有访问权限。这样的好处就是选择性地将一大批数据共享出去。

2)直接调取对方数据表

这个方式就是在B系统在开发时,在代码中加载A系统的数据表,直接从数据表中取数据。

这就是实时拉取对方的数据,B系统自己本地不做表保存。比较省,事但是耦合性较大,数据量大的时候不建议。

3)同步对方的数据表

直接将对方的数据表copy一份过来,并保持实时同步,otter技术就是常用的一个方法。

otte可以将mysql的数据同步至另外mysql或者oracle,也支持双向同步(即A库同步给B库,B库也同步给A库)、文件同步等,主要应用应用是多数据中心、BI系统抽取数据、灾备。

数据传输协议sftp(系统间数据对接传输)(5)

该方式需要DB协助配置。也就是做了一个mysql的同步平台(带WEB管理界面),在界面上,你可以定义相应的映射规则,otter进程就会根据你定义的规则读取binlog,并更新到目标库中去。

该方式主要用于内部系统之间(一般一个公司的才这样)库对库的传输,可以实现数据的相互同步更新。建议应用在数据量大的时候,或者基础数据对周边兄弟系统提供基础支持的时候。优点是占用资源少,交互更加简单可靠。

当连接B的系统越来越多的时候,由于数据库的连接池是有限的,导致每个系统分配到的连接不会很多,当系统越来越多的时候,可能导致无可用的数据库连接。

这时候otter比较适合。而两个不同公司的系统,不太会开放自己的数据库给对方连接,因为这样会有安全性影响。

3、文件包共享方式

一些第三方公司为了保密,不愿意提供接口,那么会把文件存在类似网盘或网页上,供需求方下载。

双方系统约定文件服务器地址、密码、文件命名规则、文件内容格式等,通过上传文件到文件服务器,进行数据交互,对大数据量的也很适合。

这就是一种异步的上传下载机制,双方的操作割裂开,并且一旦上传可以被多个需求方使用。

数据传输协议sftp(系统间数据对接传输)(6)

比如:第三方支付公司与需求方约定好SFTP服务器(一种文件服务器,可以理解为网盘)的账号密码,然后支付公司将账单数据上传到SFTP服务器上,那么需求方就可以登陆SFTP客户端,进行下载、解析,然后保存使用。这也实现了数据在服务器之间的传输。

实际上这些数据本身也是加密的,所以只有协议的公司才能拿到解码钥匙。长期合作的公司就会持续更新,授权的公司就可以持续下载和解析。这里就有一个下载频率的问题,一般使用定时任务按一定频率去下载。并且要考虑丢包的机制。

案例:

到SFTP服务器抓取并解析WP支付平台的账单明细,方案如下:

到SFTP服务器找到文件路径,筛选出需要的类型文件,打开文件,按规则解析所需的字段,对应写入本地数据表。

脚本执行逻辑:每次抓取路径下‘修改时间’为前一天的文件。(这里有个隐患:如果出了故障,可能某天的数据就漏了)。

问题:怎么防止丢抓呢?

分析:因为是外部数据,所以这里无法对源数据做“是否被抓取过”的标注。因此建议防丢方案是增加断抓补抓机制。

断抓补抓机制:比如4号抓了修改时间为3号的数据。5号断抓,则6号继续抓取4、5号的数据。断抓补抓的机制就是说一旦某一天的数据中断了,发现不连续,那么系统就自动在下次重新抓一次,看看是否能补上。直到三次都未取到。则不再补救。

该方案可以降低我方抓取故障导致的抓空情况。有时候开发懒省事不愿意考虑这么多,这时候产品经理要提醒他。

4、消息队列MQ(Message Queue)

1)MQ概念

消息队列技术是分布式应用间交换信息的一种技术。目前市场上有很多开源的jms消息中间件,比如ActiveMQ, OpenJMS。

数据传输协议sftp(系统间数据对接传输)(7)

简单说就是一方不断把信息推到队列中,像排队进隧道一样,另一方依次消费这些信息。消息队列可驻留在内存或磁盘上,队列存储消息直到它们被应用程序读走。

该方式更适用于公司内部,数据量大,规律性强,批量往来的数据。主要解决应用解耦,异步消息,流量削锋等问题。

2)以异步处理举例说明

用户注册后,需要发注册邮件和注册短信。传统的做法有两种:a.串行的方式;b.并行方式

a、串行方式:

将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端。

数据传输协议sftp(系统间数据对接传输)(8)

b、并行方式:

将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间。

数据传输协议sftp(系统间数据对接传输)(9)

假设三个业务节点每个使用50毫秒钟,不考虑网络等其他开销,则串行方式的时间是150毫秒,并行的时间可能是100毫秒。

因为CPU在单位时间内处理的请求数是一定的,假设CPU1秒内吞吐量是100次。则串行方式1秒内CPU可处理的请求量是7次(1000/150)。并行方式处理的请求量是10次(1000/100)

小结:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢?

引入消息队列,异步处理。改造后的架构如下

数据传输协议sftp(系统间数据对接传输)(10)

按照以上约定,用户的响应时间相当于是注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,基本可以忽略,因此用户的响应时间可能是50毫秒。因此架构改变后,系统的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了两倍。

在设计方案的时候要注意异常情况的处理机制。比如:首次消费失败?

如果第一次数据消费的时候,无法识别没有匹配上,但是又想下次再消费一次看是否匹配的上怎么办?可以设定机制:无法识别的则重新插到队列后面继续推送。

如果一直循环仍消费不掉信息积压怎么办?

设定处理机制:超过一定积压数据量或者循环时间过长则进行报警。

3)MQ、文件包共享、接口的对比

MQ推送过去之后,是否推送成功无需对方再用MQ返回,因为推到中间站就意味着我方能做的事情已经做完。

而接口是一来一往才知道是否成功的,也就是要返回一个信息。这点与mq是不一样的。但是如果非要对方再返回是否接受成功的话,那么就要做反向MQ,这相当于另一个独立的MQ。

文件包共享也不需要反馈机制,因此传到了文件服务器之后,数据方的事情就做完了。

队列的一个信息只能被消费一次,不同系统不能共同消费一个队列。因此如果对接多个系统则要多次创建MQ。而接口可以创建一个,让其他很多系统调取。

在订单系统对接各个销售网站和平台的时候就可以采用这样的机制,避免多次对接。文件包共享也是可以上传一次,供多个需求方下载。这点和接口有相似之处,是MQ所不具备的。

5、其他手段

数据传输包含了数据信息的获取和写入,其实除了线上的自动机制,还有很多土办法,在后端产品系统中也是常使用的。

1)导入导出

场景:没有办法做系统之间的对接,但是线下能获得数据。数据量不太大,且有规则数据。则可以通过导入的方式。

文档一般用csv格式,该格式文件较小,兼容性好,然后需要定义好excel表格对应字段的关系,比如A列对应字段‘name’,B列对应字段'age'。

上传时需要对文件检验,比如格式不对、必填项为空等,建议一旦一处错误,就全部不予导入。并返回错误提示,修改后继续导入。

若数据太大(与服务器的性能也有关系,比如超过一万条),可以采用异步上传机制,就是上传之后不立即执行写入,而是后台自动分批写入。

2)爬取

作为数据需求方,获取数据可以通过协商接口的方式、SFTP解析的方式、或者直接爬取的方式。比如需要获取第三方网站商标库中最新商标名称、注册地、logo、授权期限等信息,如果该网站不给于开放的接口授权,可能就需要我们开发写爬虫代码爬取(当然有的商业数据也是带有反爬机制的,这就看谁道高一尺魔高一丈了)。

三、数据传输的处理机制

1、数据同步的触发机制

前面提到了数据获取的方式,那么数据获取频次或者触发机制是怎么样的呢?这要根据应用场景来设定方案,但是一般都是要求持续获取的。

一种方式是操作事件触发,比如页面的按钮点击则触发传递最新状态。这种的时效性比较高,但是也会由于并发而增加系统负荷。

如果对时效要求不高就可以采用异步机制。比如使用脚本监控。设定脚本的运行频率,当读取到更新时间为频宽内的数据,则将其捕获并传输。定时脚本也叫定时任务等。定时脚本在后端是很常用的。

比如说每次获取A系统6小时内更新的数据,那么每2小时取一次的话是没问题的。但是若每7小时获取一次就会漏掉1小时的数据。因此一定是每次获取的数据时间区间,要高于数据获取的时间间隔。

当然用时间是一种维度,更安全的是用标示性字段。比如每次获取is_got为0的数据。前台是is_got做表索引(索引前面讲到过),这样遍历(遍历约等于全表查询)数据库的时候就不会太慢。

2、是否异步执行数据处理

如果获取后还要在本地进行规则运算,则最好先落地到中间表,再由中间表写入最终表。也就是异步写入。

比如:按照订单 包裹号维度,从物流系统获取运费到财务系统,然后财务系统再将其分摊到包裹的商品上面,算出每个商品分摊的运费金额。

这时候就很容易出错,因为分摊规则是个算法,算法就带有规则的可变动性。一旦分摊规则的参数不准确,或者算法结构变化,都会导致最终分摊的运费金额错误。那么这时候追查错误原因并修复数据就很麻烦。

所以在进行分摊之前,先落地到财务系统的临时表(中间表)中,然后获取数据完成。再进行写入分摊运费的操作。

除了上述方便查错误原因外(有种数据清洗的意思),这种异步操作同时也确保了较少的偶联,不至于一个环节出错,则联动出错。同时它作为一个基础数据,也可以被其他功能调用。若数据量万级以上的,必须这样做。

3、判重机制

数据通道搭建好之后,数据流往往是持续获的。而数据源在别人那里,可能会被增删改,因此常常有相似或相关的数据进来。

在写入本地表的时候,不管是覆盖、更新还是插入,都是以确定若干字段做为判重的标示为前题的。

比如职工信息表:(姓名 手机号 性别 家乡 身份证号)。(姓名 手机号 性别 家乡)这几个字段对一个职工不一定唯一,但是身份证号就是唯一的。因此如果我们更新这里的数据,就以身份证号为唯一标示。

比如获取到同一个身份证号的手机号与我们的数据库的不同,则更新。遇到我们的数据库不存在的身份证号码则插入。

某些时候无法确定那几个是唯一字段,则可以添加一个备用字段,人为定义其取值规则,然后作为去重字段,比如这个字段叫unique_code,取数据源表的主键 日期,(或者直接就取源表的id,也就是外键)。

有了判重字段(也就是数据唯一的字段),就可以进行更新、插入或者跳过规则设定了。

注意:若一段时间之后,改变了表的去重规则,则需要考虑到历史数据对新数据的影响,因为二者的判重维度不一样,可能会进来和以前的历史数据冲突的交叉数据。

4、获取到数据之后,如果使用?

一种是直接在页面展示,不保存在本地数据库中。相当于每刷新一次页面则通过接口调取一次对方的数据展示。但这种从性能和场景上都是比较少的,一般都是先保存到本地数据库上,自己本地各种调用。

对于先保存到本地的情况,有两个问题要考虑:是否异步保存,和如何确保同源同步。

5、处理日志

数据日志:目的是记录数据的来龙去脉,追溯以分析问题。

日志要记录三个主要事项:数据源系统是否提供数据、目标系统是否接收到数据、目标系统是否写入了数据。

产品经理告诉开发加数据捕获日志的时候,需要告知是否存到表里,因为系统一般都有一个类似缓存一样的日记,只是会定期清理的。只有保存下来才能一直记录和追溯。

开发后台本身是有数据log日志的,因为log4j开源代码定义了5个主要级别的log:FATAL、ERROR、WARN、INFO、DEBUG,一般情况下,开发都会自觉配置INFO或DEBUG级别的日志,以方便查数据。

但是代码中的kog保存时间不会太长,比如一个月就会清除了。因此如果需要保留的时间长,则可以将其保存到本地数据库。

根据实习需要,存了数据库就可以做成页面,展示给用户看,比如可以从以下维度展示:

四、数据传输的注意事项

1、目标数据表最好和中间表的维度一致

假设从A系统获取的数据存入B系统,先落地到中间表b,然后经过一些列运算后将数据从b写入到b'表。

注意b和b'表的去重字段要对应起来,并传递下去。因为维度相同,做到一对一,方便实现异常数据溯源。

2、不同入口写入同一类型数据时,如何与自身入口的数据去重,且与其他入口的数据互相去重?

案例:

有新旧两个不同的写入程序,写数据到利润表,写入的都是‘退件入库’利润类型,是殊途同归。不巧的是两个写入入口各自有本身的去重规则,彼此去重的规则不能通用:假设入口1对应的去重字段是A B,入口2写入的去重字段是B C。

这就意味着同一个数据如果分多次写入,有可能从两个入口都会写入。如何实现避免重复写入是核心问题。

我们首先考虑的是,如果一条源信息从一个入口已经写入了利润表,那么就不能从另一个入口再写。

其次,如果从入口1写入一次,那么后面源数据更新再次触发写入的时候(判重,确定是插入还是更新),就还要从入口1写。也就是一旦从一个入口写入,后面该数据的变更触发的再次写入也只能从这个入口继续变更。

只有这样才能保证这个数据不重复。好比先找到是哪家的孩子,再确定是第几个孩子,且只能是基于这家内部去确认。

方案一:比如入口1遇到一个待写入的数据,则先按自己的去重字段A B校验。如果发现不存在该数据,则再按照入口2的去重字段B C(这个事先是知道的)判断是否存在,若也不存在,则回到入口1写入。若存在,则入口1不在写入,且结束进程(因为入口2会触发写入该数据的)。

方案二:比如入口1遇到一个待写入的数据,则先按入口2的去重字段B C校验。

查看对方入口下是否有重复数据,有,则本入口不写(继续按对方的路径写);无,则自己的路径写。显然方案二的判断路径更短,相对好一点。

3、同步基础数据的时候是否提前过滤

这个在上面内容中也提到过。比如:A系统维护了员工的基础信息,其中有个状态为【是否有效】,只有有效状态的才能在整个系统中看得到才是生效的。B系统要取用员工信息的数据,但不做数据维护。那么是否只取启用状态的数据到B,还是不区分状态都取呢?

答案是:在数据量差异不大的情况下,取全量。

原因之一就是,若启用状态的用户忽然被A系统禁用,那么可能该用户在B系统的生产数据报错,这时候到中间表看状态就可以看出来问题,而不需跨系统或跨部门沟通查证。

阅读原文:系统间数据传输,产品经理视角的9千字总结:接口、otter、log4j、SFTP、MQ……

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页