远程函数调用 (RFC) 是用于不同系统的应用程序之间的通信,包括SAP系统之间以及SAP系统与非SAP系统之间的连接通信。
根据类型分为Synchronous RFC,Asynchronous RFC (aRFC),Transactional RFC (tRFC),Queued RFC (qRFC),Background RFC (bgRFC),Local Data Queue (LDQ),所有 RFC 类型都通过 CPI-C或 TCP/IP 传输。
异步通信,接收系统不一定必须在从发送方系统分派函数调用时可用。接收系统可以稍后接收和处理调用。如果接收系统不可用,则函数调用保留在发送系统的出站队列中,从那里定期重复调用,直到接收系统可以处理它。
1. 创建function时在属性页签勾选远程启用的模块
2. 参数的参考类型必须勾选值传递,且不能使用通用类型
和正常函数调用相比,带有附加的 DESTINATION、 STARTING NEW TASK或 IN Background TASK、 IN Background UNIT ..等语句。
RFC 接口进行的每个远程功能模块调用都在目标系统中定义了自己的上下文。功能模块的功能组被加载到上下文的内部会话中,并被保留。这意味着,如果重复调用属于同一目的地和同一功能组的功能模块,则可以集中访问该功能组的全局数据。
功能模块 RFC_CONNECTION_CLOSE可用于显式关闭连接。
RFC不支持“通过引用”传输。因此,必须将整个表传回在 RFC 客户端和 RFC 服务器之间来回切换。第一次调用传递时,创建一个本地副本,并赋予ID,之后再调用只会更新本地副本。
对于使用同步 RFC 进行的每个调用,都会执行一次隐式数据库提交
在远程调用的功能模块中,不能使用关闭当前上下文并因此关闭连接的语句。比如语句 LEAVE PROGRAM,或者 SUBMIT没有添加 RETURN。
RFC 仅使用按值传递,因此当确实发生异常时,无法在生成同步 RFC 时访问中间结果。
SYSTEM_FAILURE如果在远程调用的功能模块执行过程中发生运行时错误,则会发生 异常 。
COMMUNICATION_FAILURE如果无法与伙伴系统建立连接,或者在通信期间连接中断,则会发生 异常 。
运行时异常
1. SM59配置,可在表RFCDES 中查看
2 系统内置“NONE” 功能模块在与调用程序相同的应用服务器上启动,不用账号密码,如果SM59设置本地为目的地需要账号密码 。(DESTINATION 'NONE' runs in its own roll area 保留远程上下文 )
3 系统内置“BACK” 在远程调用的功能模块中使用,并链接回调用方,只能在已同步调用的功能模块中指定此项,在回调时,系统总是会在建立新的 RFC 连接之前尝试使用现有的 RFC 连接。
4. 基于CL_DYNAMIC_DESTINATION 实现的动态DESTINATION
5. 直接指定的目的地,格式为“hostname_sysid_sysnr”。“hostname”是指应用服务器的名称,“sysid”是SAP系统的名称,“sysnr”是系统编号。
aRFC 需要具有可用的dialog进程(不是SM50中空闲dialog进程,需减去配置参数rdisp/rfc_min_wait_dia_wp设置保留为其他用途的进程数)
bgRFC最少工作进程数目
bgRFC 处理的性能不一定取决于调度程序的数量。在工作负载水平较低的情况下,可以使用更少的调度程序获得更大的吞吐量。
同步RFC(sRFC)直接执行函数调用,等待被调用函数模块的回复。调用前调用数据不会写入数据库用来调用处理。因此,当使用同步 RFC 时,被调用系统必须可用。调用只进行一次。如果被调用系统不可用或出现问题,则调用失败。
注意点
1. 同步 RFC 调用的功能模块的执行不会导致更新功能中的数据库提交(属于隐式提交)
2. 使用附加 TABLES 传输表比使用其他附加要快得多,因为内部使用二进制格式而不是 XML 格式。
在执行同步RFC之前,数据未更新
执行完同步rfc后,当前luw数据被提交更新,更新函数未触发
执行完commit,更新函数被触发,数据更新。RFC的隐式提交不会触发更新函数。
异步 RFC (aRFC) 实际上并不是严格意义上的异步函数调用。虽然函数在被调用后直接返回到调用程序,但调用数据并没有真正写入数据库用来调用处理。因此,只能在直接可用的系统上进行调用。如果被叫系统不可用,则调用失败。
特点:
函数在调用后直接返回调用程序,用户不必等待其完成即可继续调用对话
异步 RFC 的参数不记录到数据库,而是直接发送到服务器
异步 RFC 允许用户与远程系统进行交互式对话
当调用方启动 aRFC 时,被调用服务器 必须可以接受请求。
调用程序可以接收来自异步 RFC 的结果
CALL FUNCTION Remotefunction STARTING NEW TASK Taskname
PERFORMING RETURN_FORM ON END OF TASK.
FORM RETURN_FORM USING TASKNAME.
RECEIVE RESULTS FROM FUNCTION Remotefunction
IMPORTING
F1 = a1
EXCEPTIONS
SYSTEM_FAILURE MESSAGE SYSTEM_MSG.
ENDFORM.
KEEPING TASK:
在接收返回结果后保持RFC连接,保留当前远程上下文,此时如果指定相同的任务名称,则可以重复使用远程上下文和滚动区域(比如被调用RFC中的全局变量,静态变量)。
保持上下文:
任务 ID 对于每个调用必须是唯一的,并被传递给回调例程以识别函数。每个任务 ID 定义了一个单独的 RFC 连接,具有自己的上下文,这意味着在重复调用相同任务 ID 的功能模块的情况下,如果连接仍然存在,则可以访问相关功能组的全局数据。
直接调用异步RFC,上下文效果不会保留,如下
TYPES: BEGIN OF task_type,
name TYPE string,
number TYPE i,
END OF task_type.
DATA: snd_jobs TYPE i,
rcv_jobs TYPE i,
exc_flag TYPE i,
info TYPE rfcsi,
mess TYPE c LENGTH 80,
indx TYPE c LENGTH 4,
name TYPE c LENGTH 8,
task_list TYPE STANDARD TABLE OF task_type,
task_wa TYPE task_type.
DO 3 TIMES.
indx = sy-index.
CONCATENATE 'Task' indx INTO name.
CALL FUNCTION 'YLC_FUNC002'
STARTING NEW TASK name
PERFORMING rfc_info ON END OF TASK
EXCEPTIONS
system_failure = 1 MESSAGE mess
communication_failure = 2 MESSAGE mess
resource_failure = 3.
CASE sy-subrc.
WHEN 0.
snd_jobs = snd_jobs + 1.
WHEN 1 OR 2.
MESSAGE mess TYPE 'I'.
WHEN 3.
IF snd_jobs >= 1 AND
exc_flag = 0.
exc_flag = 1.
WAIT UNTIL rcv_jobs >= snd_jobs
UP TO 5 SECONDS.
ENDIF.
IF sy-subrc = 0.
exc_flag = 0.
ELSE.
MESSAGE 'Resource failure' TYPE 'I'.
ENDIF.
WHEN OTHERS.
MESSAGE 'Other error' TYPE 'I'.
ENDCASE.
ENDDO.
WAIT UNTIL rcv_jobs >= snd_jobs.
LOOP AT task_list INTO task_wa.
WRITE: / task_wa-name, task_wa-number.
ENDLOOP.
FORM rfc_info USING name.
DATA: lv_number TYPE i.
task_wa-name = name.
rcv_jobs = rcv_jobs + 1.
RECEIVE RESULTS FROM FUNCTION 'YLC_FUNC002'
IMPORTING
number = lv_number
EXCEPTIONS
system_failure = 1 MESSAGE mess
communication_failure = 2 MESSAGE mess.
IF sy-subrc = 0.
task_wa-number = lv_number.
ENDIF.
APPEND task_wa TO task_list.
ENDFORM.
此时执行结束,由于不同的task名字,使用不同的上下文及滚动区域,因此获取到的值是一样的。
循环中设置indx为1,使用相同的任务名称调用异步RFC,且增加KEEPING TASK关键字,注意相同任务名称在同一个程序下不能同时打开,因此这里只用了一个进程。
TYPES: BEGIN OF task_type,
name TYPE string,
number TYPE i,
END OF task_type.
DATA: snd_jobs TYPE i,
rcv_jobs TYPE i,
exc_flag TYPE i,
info TYPE rfcsi,
mess TYPE c LENGTH 80,
indx TYPE c LENGTH 4,
name TYPE c LENGTH 8,
task_list TYPE STANDARD TABLE OF task_type,
task_wa TYPE task_type.
DO 3 TIMES.
indx = sy-index.
indx = 1.
CONCATENATE 'Task' indx INTO name.
CALL FUNCTION 'YLC_FUNC002'
STARTING NEW TASK name
PERFORMING rfc_info ON END OF TASK
EXCEPTIONS
system_failure = 1 MESSAGE mess
communication_failure = 2 MESSAGE mess
resource_failure = 3.
CASE sy-subrc.
WHEN 0.
snd_jobs = snd_jobs + 1.
WHEN 1 OR 2.
MESSAGE mess TYPE 'I'.
WHEN 3.
IF snd_jobs >= 1 AND
exc_flag = 0.
exc_flag = 1.
WAIT UNTIL rcv_jobs >= snd_jobs
UP TO 5 SECONDS.
ENDIF.
IF sy-subrc = 0.
exc_flag = 0.
ELSE.
MESSAGE 'Resource failure' TYPE 'I'.
ENDIF.
WHEN OTHERS.
MESSAGE 'Other error' TYPE 'I'.
ENDCASE.
WAIT UNTIL rcv_jobs >= snd_jobs.
ENDDO.
LOOP AT task_list INTO task_wa.
WRITE: / task_wa-name, task_wa-number.
ENDLOOP.
FORM rfc_info USING name.
DATA: lv_number TYPE i.
task_wa-name = name.
rcv_jobs = rcv_jobs + 1.
RECEIVE RESULTS FROM FUNCTION 'YLC_FUNC002' KEEPING TASK
IMPORTING
number = lv_number
EXCEPTIONS
system_failure = 1 MESSAGE mess
communication_failure = 2 MESSAGE mess.
IF sy-subrc = 0.
task_wa-number = lv_number.
ENDIF.
APPEND task_wa TO task_list.
ENDFORM.
异步RFC并行处理
1. 并行处理不适用于必须顺序处理的数据
2. 使用 CALL FUNCTION STARTING NEW TASK 之后,不能再使用 SUBMIT 或 CALL TRANSACTION。
3. SAP 系统中的服务器必须至少有 3 个空闲对话工作进程
4. 并行处理时不能使用相同的任务名称
SPBT_INITIALIZE 检查group下的进程资源是否足够
SPBT_GET_PP_DESTINATION 在RFC调用之后获取运行任务的服务器的名称
使用服务器组并行调用示例
TYPES: BEGIN OF task_type,
name TYPE string,
dest TYPE string,
END OF task_type.
DATA: snd_jobs TYPE i,
rcv_jobs TYPE i,
exc_flag TYPE i,
info TYPE rfcsi,
mess TYPE c LENGTH 80,
indx TYPE c LENGTH 4,
name TYPE c LENGTH 8,
task_list TYPE STANDARD TABLE OF task_type,
task_wa TYPE task_type.
DO 10 TIMES.
indx = sy-index.
CONCATENATE 'Task' indx INTO name.
CALL FUNCTION 'RFC_SYSTEM_INFO'
STARTING NEW TASK name
DESTINATION IN GROUP DEFAULT
PERFORMING rfc_info ON END OF TASK
EXCEPTIONS
system_failure = 1 MESSAGE mess
communication_failure = 2 MESSAGE mess
resource_failure = 3.
CASE sy-subrc.
WHEN 0.
snd_jobs = snd_jobs + 1.
WHEN 1 OR 2.
MESSAGE mess TYPE 'I'.
WHEN 3.
IF snd_jobs >= 1 AND exc_flag = 0.
exc_flag = 1.
WAIT UNTIL rcv_jobs >= snd_jobs
UP TO 5 SECONDS.
ENDIF.
IF sy-subrc = 0.
exc_flag = 0.
ELSE.
MESSAGE 'Resource failure' TYPE 'I'.
ENDIF.
WHEN OTHERS.
MESSAGE 'Other error' TYPE 'I'.
ENDCASE.
ENDDO.
WAIT UNTIL rcv_jobs >= snd_jobs.
LOOP AT task_list INTO task_wa.
WRITE: / task_wa-name, task_wa-dest.
ENDLOOP.
FORM rfc_info USING name.
task_wa-name = name.
rcv_jobs = rcv_jobs + 1.
RECEIVE RESULTS FROM FUNCTION 'RFC_SYSTEM_INFO'
IMPORTING
rfcsi_export = info
EXCEPTIONS
system_failure = 1 MESSAGE mess
communication_failure = 2 MESSAGE mess.
IF sy-subrc = 0.
task_wa-dest = info-rfcdest.
ELSE.
task_wa-dest = mess.
ENDIF.
APPEND task_wa TO task_list.
ENDFORM.
SM59unicode页签下设置和非unicode系统之间的RFC通信代码页转换,一般用在和国外系统对接的场景,比较少见。
信任系统
调用事务SM59并选择Extras Trusted Systems(或输入事务代码 SMT1)。
分析监控
STAD 查看调用 RFC 和 ICF 的各种统计数据
blog.csdn.net/xiefireworks/article/details/126257186