大概八月份的时候作过一个有关两个SAP系统间成本分摊传输的项目,使用到了RFC(Remote Function Call)技术。由于以前有着医疗-CRM相关接口开发的经验,觉得本身对RFC很熟悉了,作起来会很顺利,不想仍是遇到了些问题。打算整理一下有关它们的内容,进一步学习。html
本文内容的主要来源是SAP的英文文档。会比较偏重基本概念上的东西,偶尔涉及实际的代码、配置。后续可能会根据个人实际使用状况更新更详细的介绍。算法
本文连接:http://www.cnblogs.com/hhelibeb/p/8066753.html数据库
对于SAP与SAP系统及SAP与非SAP系统之间的链接而言,远程函数调用(Remote Function Call,如下简称RFC)是一种标准的通讯方式,它能够实现对远程系统中函数的调用。编程
本文是对全部RFC变体的描述,它们有着不一样的特性和适合的使用场景。后端
同步RFC(Synchronous RFC,sRFC)是最基本的RFC形式。在sRFC调用中,调用者会等待远程被调用者的处理过程。服务器
它的语法形式是:架构
CALL FUNCTION func DESTINATION dest.
典型的使用场景包括:异步
异步RFC(Asynchronous RFC,aRFC)相似与tRFC,用户在继续调用会话以前,不须要等待它们的完成。不过,aRFC和tRFC之间也存在几点不一样的地方:数据库设计
你能够在当你须要创建和一个远端系统的链接、可是但愿在调用RFC后不但愿等待结果而是但愿继续处理时使用aRFC。aRFC也能够发送给相同的系统。在这种状况下,系统打开一个新的会话(窗口)。你能够在调用对话和被调用会话间切换。使用下面的语句开启一个aRFC:ide
CALL FUNCTION Remotefunction STARTING NEW TASK Taskname DESTINATION ... EXPORTING... TABLES ... EXCEPTIONS...
RECEIVE RESULTS FROM FUNCTION Remotefunction 用于一个子程序内接受aRFC的调用结果。可使用如下接收参数:
IMPORTING
TABLES
EXCEPTIONS
附加项KEEPING TASK阻止链接在接收处理结果后关闭。相关的远程上下文(滚动区域)保持能够重用的状态,直至调用者终止链接。
更多有关aRFC的信息能够从如下地方获取:
有关aRFC变体的描述:
在使用事务RFC( transactional RFC,tRFC)的时候,被调用的函数模块在被调用系统中正好运行一次(Exactly Once)。
远端系统不须要在RFC客户端程序运行tRFC的时候可用。tRFC组件将被调用的RFC函数和相关数据存储在SAP系统的数据库里,包含一个惟一的事务标识符(transaction identifier,TID)。
若是调用发送了,接收系统倒是宕机状态,调用会保留在本地队列中一段时间。调用对话程序能够在不等待远程调用成功/失败的状况下继续运行。若是接收系统在一段时间后仍然不可用,调用将被计划为后台做业运行。
tRFC使用后缀IN BACKGROUND TASK.
就和同步调用同样,参数 DESTINATION在远程系统定义了程序上下文。结果是,若是你对一个destination重复地调用一个函数(或者一次性调用多个函数),则能够在相同的上下文中访问被调用函数的全局数据。。
系统会在表ARFCSSTATE和表ARFCSDATA中记录远程链接请求和它们的所有参数值。你可使用事务SM58来查看。当调用程序到达COMMIT WORK语句时,远程调用会被转发到给对方系统。
在两个COMMIT WORK之间,全部的拥有同一个destination的tRFC属于同一个逻辑单元(LUW)。
tRFC处理流图示:
你能够在某些状况下使用使用tRFC,好比,对于须要在事务的不一样阶段更新相关数据库表的复杂的处理过程。
tRFC会确保全部的计划更新在程序到达COMMIT WORK语句时被执行。
(注意:tRFC的定义中不能有任何EXPORT参数,由于调用程序中若是有IMPORT参数,就会致使语法错误。此外,你也不能够对执行回调的程序进行异步调用)
系统可用性:
若是远程系统不可用,SAP系统会将报表RSARFCSE计划为后台做业,并将相关的事务ID做为变式,再进行处理。这个报表程序会重复地被调用,直到它成功地链接对方系统为止。
当被计划为后台做业时,RSARFCSE自动地以一个时间间隔运行(默认是每15分钟运行一次,最多尝试30次)。你能够经过加强程序SABP0000和SABP0003来自定义该时间间隔。
经过SM59配置destination,选择一个destination而且选择 编辑->TRFC选项,在这里定义链接尝试次数上限和重复链接尝试的时间间隔。
若是在尝试指定的次数后依然不可抵达相应的系统,系统会中止调用RSARFCSE,并写入状态CPICERR至表ARFCSDATA中。在另外一个指定的时间后(默认是8天),在表ARFCSSTATE内的条目也会被删除。固然也能够定制这个时间,或者手动在SM59启动相应的事务条目。
tRFC的缺点:
能够在这里查看tRFC语句的描述:
CALL FUNCTION IN BACKGROUND TASK
队列RFC(queued Remote Function Call,qRFC)是tRFC的一个扩展。它容许你将多个tRFC调用序列化为一个队列。
qRFC调用会首先被函数模块TRFC_SET_QUEUE_NAME进行序列化处理,而后这些调用被一个tRFC进行实际上的dispatch。
qRFC能够做为外向队列(由调用系统序列化)处理,或者是内向队列(由被调用系统序列化)。
如下是三种事务数据传输的场景(为何图片中的文字是德文?):
场景1:tRFC
该场景适用于数据彼此间独立发送的状况。系统1中存在一个调用应用(client)使用tRFC链接系统2中的被调用应用(r server)。在该场景中,数据由tRFC传输,意味着发送到目标系统的函数模块调用会被保证只运行一次。你不能够定义函数模块运行的顺序和时间。若是传输过程当中发生了错误,系统会计划一个后台做业,在15分钟后再次发送函数模块调用。
场景2:带有外向队列的qRFC
在该场景中,发送系统使用一个外向队列来序列化被发送的数据。这意味着发送系统的外向队列包含着存在依赖关系的函数模块调用。当数据发送时,会保持肯定的顺序,而且调用会以正好一次且有序的方式(exactly once in order)发送给目标系统。
注意:目标系统处理时不须要改变qRFC的顺序,可是,它必须开启tRFC功能。
场景3:带有内向队列的qRFC(以及外向队列)
在这个场景下,不只发送系统(client)有外向队列,目标系统也有内向队列。若是qRFC存在有内向队列,这也意味着它在发送系统上必然存在外向队列。内向队列在一段时间里只能处理系统资源容许处理的函数模块调用数量。它能够防止服务器被一个客户端阻塞。只有在服务系统单独存在一个内向队列的场景是不可能存在的,由于须要在客户端系统存在外向队列,来设置顺序并阻止单独的应用阻塞客户端系统的整个工做进程。
更多相关信息可见:
bgRFC(Background Remote Function Call)容许被调用程序稍晚一些接收数据,而不是同步接收。接收数据的时候,须要保证数据只出现一次且无序( transactional) 、或者只出现一次且有序(queued)。
使用bgRFC进行异步调用,会有以下优点:
bgRFC使用队列组织不一样的调用。当一个调用同时被放置在多个队列的时候,系统会为这些队列建立依赖。这带来了一个同步点(synchronization point),相似于锁。
若是一个调用处于依赖队列中,那么当且仅当它位于依赖队列的最上层时,它才会被处理。
对于同一个destination,不能够将bgRFC和tRFC、qRFC结合起来使用。不过,对于不一样的destination,你能够定义你想使用的通信类型。
语法:
CALL FUNCTION 'function_name' IN BACKGROUND UNIT unit EXPORTING ...
从qRFC转换为bgRFC的应用程序,必须支持建立qRFC中的队列与bgRFC中的队列之间的临时连接的迁移方案。经过这样的方案,能够保证正确的队列顺序,即使是在从qRFC变为bgRFC的时刻。
注意:从bgRFC改回qRFC是不可能的。
在SAP NetWeaver Release 7.11以及更高的版本上,bgRFC也能够和basXML(二进制ABAP序列化XML)通讯协议一块儿使用。
传统的qRFC模型只有在数据被RFC调度程序处理的时候才探测各个独立单元之间的依赖关系。对于每一个destination,外向调度程序都会开启一个调度程序来处理这个destination的数据。
与之相对的是,bgRFC的依赖关系在数据存储的时候就决定了。经过这样作,RFC调度程序能够一次性找到全部的须要被处理的单元,而且经过最小的努力(minimum effort)就能够找到它们之间的依赖关系。在存储数据的时候须要付出的额外努力,则能够在很大程度上由数据库设计中的高效率算法和优化补偿。
每一个客户端定义必定数量的外向计划,而且并行处理队列负载,虽然目标系统的负载会在一个较短的时间间隔后被肯定,可是也所以会更加精确。
单元和队列的删除程序:
和传统的程序不一样,若是有任何单元或队列被删除,依赖依然会保持。由于单元会被先打上标记,而且在这以后只是被调度程序删除。
如图,在删除了Unit4以后,Unit6只能在Unit3以后运行,由于Unit4只有在调度程序处理过Unit3以后才会被删除。若是你删除掉queue2,那么会发生下面的状况:
Unit6会在Unit2以后运行,全部选定的unit都会被调度程序删除。
注意:删除队列或者单元老是具备风险的。在咱们的例子里,它会致使Unit6遇到错误,或者致使目标系统的数据库不一致,由于它的前提Unit4由于被删除而没有运行。
Gateway:Gateway是另外一个潜在的性能瓶颈,在bgRFC中,它也获得了优化。bgRFC中的新的概念是会调节在一台应用服务器上同时运行的外向调度程序的最大数量,也会调节所有RFC调度程序可用的最大链接数。这个限制会保护本地的Gateway使之不至于过载。
每一个发送系统的并行的外向调度程序数量和它们的最大链接数也是可配置的,所以对于destination的Gateway也存在过载保护。
性能的影响:新bgRFC实现的优化在高负载、多依赖的状况下特别明显。首次运行的时候,线性对数可伸缩性(a linear logarithmical scalability)的RFC数据处理成为可能(视系统兼容性而定)。
函数队列的事务特性使得,在处理单独的单元时,bgRFC不太容易取得明显的性能提高,可是在应用更多或者更快的硬件的时候,则能够明显提高吞吐量。限制因素会是数据库的性能和这些单元的处理速度。
此外,新的API也是优化的一部分。一些多余的函数被移除,某些旧的API也再也不应用。这使得相关的工做更加平滑和有效率,减小支持团队和开发团队的工做量。
更多信息:
更多有关bgRFC的信息, 请看:
本地数据队列(Local Data Queue )是一种特别的RFC通讯。在这种应用状况下,系统不会主动发送数据。相反,根据拉取规则,系统会把数据存储在本地,直到被外部系统调用(好比移动设备)。
LDQ能够代替先前由qRFC在不发送场景下提供的功能(qRFC No Send)。相比之下它提供了更有效率的数据模型。
更多内容:
scheduler:调度程序
outbound queue:外向队列
inbound queue:内向队列
相关文章:ABAP RFC远程调用