写点什么

一个 15 年 ABAP 老兵的建议:了解这些基础知识,对 ABAP 开发有百利而无一害

作者:Jerry Wang
  • 2022 年 7 月 21 日
  • 本文字数:3829 字

    阅读完需:约 13 分钟

一个15年ABAP老兵的建议:了解这些基础知识,对ABAP开发有百利而无一害

在笔者之前的文章里,曾经提到了 SAP 社区上这样一篇博客:Proof of Concept: Deploying ABAP in Kubernetes



里面介绍了 SAP Linux 实验室的工程师们将 ABAP 应用服务器各组件进行容器化并部署到 Kubernetes 上的尝试。



本文简单回顾 ABAP Netweaver 应用服务器的主要组件。虽然即使不了解这些知识,也不影响 ABAP 开发人员完成日常工作,但是很多 ABAP 编程的最佳实践都和这些知识有着千丝万缕的联系,知其然知其所以然,能帮助大家写出更健壮更高效的 ABAP 应用。

什么是 ABAP Netweaver 应用服务器?

SAP Netweaver 应用服务器是 SAP ABAP 应用开发和运行平台,ABAP 开发人员在上面可以专注于具体业务逻辑的开发,凡涉及到更底层的基础设施相关任务,比如请求的负载均衡,进程的派生,同步和调度,内存管理,服务器多实例间缓存同步等等,统统交由 Netweaver 平台本身处理。如此一来,一个 ABAP 开发人员,即使不具备精深的计算机组成原理,操作系统,计算机网络等领域知识,也能胜任 SAP 应用的开发工作。

ABAP Netweaver 应用服务器和 SAP 解决方案的关系?

本文讨论的 SAP 解决方案,仅限于那些基于 ABAP 技术栈的 SAP 产品。Google 里根据关键字"SAP ABAP three layer"搜索,能找到很多基于 ABAP 技术的 SAP 解决方案的三层经典架构图:



随便点开一张查看:



SAP 客户位于图中最上面的展现层(Presentation Layer),通过 SAP GUI 这个客户端软件或者浏览器访问 SAP 系统;


SAP 系统的软件,安装在 ABAP Netweaver 服务器上,响应用户请求,完成对应的业务逻辑。ABAP Netweaver 服务器位于上图中间的应用层。最底层是数据库层,很多 SAP 产品都支持不同类型的数据库,比如 SAP HANA,Oracle 数据库,SQL Server 等。



部分 ABAP 开发人员觉得,我们既然能够直接在 ABAP Netweaver 里用 OPEN SQL 对数据库表进行读写操作,那么 Netweaver 应用服务器本身就包含了数据库层。这样理解其实不正确。我们在 Netweaver SE38 里编写的 OPEN SQL 代码,会通过 Netweaver 内部的数据库接口,转换成数据库提供商相关的原生 SQL 语句在数据库里执行,并且从最底层的数据库层,到应用层里的 ABAP 程序之间的数据传输,也是通过数据库接口完成的。



本文讨论的 ABAP Netweaver 服务器的组成部分,位于三层架构中的应用层。

ABAP Netweaver 服务器实例

运行在物理机器上的 ABAP 应用服务器,按照其用途的不同,又可分为两种实例:应用服务器实例和 ABAP SAP 中央服务实例(ABAP SAP Central Services instances, 缩写为 ASCS instances), 也就是下图两个灰色矩形框代表的实例。



一个典型的 SAP 系统一般由一到多个应用服务器实例和一个 ASCS 实例组成。从上图左边的矩形框里,能观察到 ABAP 应用服务器实例包含的主要组件有:


(1) Internet Communication Manager (ICM)(2) ABAP dispatcher(3) 工作进程(4) RFC Gateway(5) Start Service


下面是对这些组件的简要介绍。

Internet Communication Manager (ICM)

ICM 是 Netweaver 服务器里一个单独的进程,由 ABAP Dispatcher 启动并监控,负责 SAP 系统和外部的网络通信。基于收到请求 URL 的解析,ICM 会将请求分发给具体的 handler 进行处理。


ICM 常用的与 Internet 交互的协议有 HTTP,HTTPS,SMTP 等。下图是 ICM 的架构图。



  • Thread Control:该线程负责接收外界请求,从 ICM 线程池中取出空闲的工作线程,将请求的上下文交给工作线程。

  • 工作线程:负责请求的具体处理,包含一个 I/O 处理器,可以用来进行网络的输入和输出操作。对于不同协议类型的请求,Thread Control 会调度包含了对应协议插件的工作线程。

  • Watchdog:如果一个工作线程在任务处理时出现了等待某个响应直至超时的情况,Watchdog 会将该工作线程释放,避免其无限期的等待,这样该工作线程可以服务于其他请求。而 Watchdog 会继续等待尚未到来的响应。其后如果响应到达,Watchdog 会通知 Thread control, 后者会继续调用新的工作线程来处理。

  • Signal Handler:处理来自操作系统或者其他进程的信号。

  • Connection Info: 这张表维护了每个连接的状态信息,包括内存管道等。

  • Memory Pipes:内存管道是基于内存的通讯数据结构,用于将 ICM 接收到的外部请求包含的数据转交给工作线程。

  • Internet Server Cache:服务器端的缓存,对于重复的请求可以加快响应速度。

ABAP Dispatcher 和工作进程

二者的关系在下图体现得很清晰,ABAP 应用服务器上运行着许多工作进程(Work Process),这些进程类型各异,负责处理各种类型不同的请求。



事务码 SM50 里能看到当前应用服务器上的工作进程明细,比如下图显示用于处理用户普通事务请求的对话(Dialog)进程有 30 个,其中 29 个空闲;Update 进程负责执行数据库的更新操作;Background 进程处理后台作业,Spool 负责打印任务。而 ABAP 里数据库更新的操作有 V1 和 V2 两种级别(平时大家用的默认都是 V1 级别),分别由下图的 Update 和 Update Task2 两种类型的工作进程完成。


Gateway

这里的 Gateway 和 SAP Fiori 里的 Gateway 系统是两码事,后者指代安装了 SAP_GWFND 这个 Software Component 的 ABAP 应用服务器,而我们现在即将讨论的 Gateway,是 ABAP 应用服务器里的一个组件。


SAP 系统之间,以及 SAP 系统与外部系统间通过基于 TCP/IP 的 RFC(Remote Function Call,远程系统调用)进行通信,而 Gateway 作为 RFC 调用分发的入口,如下图所示:



值得一提的是,我们能够在 SAP 标准程序里看到 CALL FUNCTION 'XXX' DESTINATION 'NONE'的写法,这种写法使得函数 XXX 仍然在调用它的应用服务器实例内部执行,而非在其他服务器上远程执行。那么这种写法不是多此一举吗?


SAP 官网对这种用法的解释:Destination "NONE" has the effect that the function module is started on the same application server as the calling program, however through the RFC interface and in its own RFC context.


也就是说,通过这种方式调用的函数,即便是和调用者同处一个应用服务器实例内,也会像远程调用执行时一样,到 RFC 接口即 Gateway 组件里去走一遭。


付出这种在额外协议栈上执行开销的代价,有什么收益?那得从 ABAP Netweaver 里不同类型的会话说起。我们每用 SAP GUI 登录一次系统,会在服务器上生成一个用户会话(User Session). 每个 User Session 里通过命令行输入/o 可以生成新的 ABAP 会话,每个 ABAP 会话内的程序调用生成新的内部会话(Internal Session).



如果直接调用函数 CALL FUNCTION 'XXX', 在发起该函数调用的同一 ABAP 会话内,会派生一个新的内部会话去执行函数体的逻辑。如果用 CALL FUNCTION 'XXX' DESTINATION 'NONE', 则会派生一个全新的用户会话,此时这个全新的用户会话,和发起函数调用的原始用户会话是完全隔离的,不共享任何数据,参数传递也是通过 RFC 标准的参数传递方式进行。通过这种方式,能实现被调用函数和原始程序的异步调用效果,同时两个用户会话里的程序执行完全隔离,不会彼此影响。事务码 SM04 能看到 ABAP 应用服务器上所有的用户会话。双击某一用户会话,能看到该用户会话派生的所有 ABAP 会话。


SAP Start Service

该服务运行在部署了 SAP 应用服务器实例的服务器上,实现载体是 Windows 的系统服务(sapstartsrv.exe)和 Unix 系统的 Daemon 进程(sapstartsrv).


SAP Start Service 实现的功能有:(1) 启动和终止 SAP 应用服务器实例,及其运行状态的监控(2) 应用服务器日志,跟踪和配置文件的读取与管理


ABAP SAP 中央服务实例(ABAP SAP Central Services instances, ASCS)主要包含 Enqueue 服务器和消息服务器。

Enqueue Server

数据库层面的锁由数据库管理,而 ABAP 应用程序级别的锁,比如锁一个订单,锁一个物料主数据,则通过应用程序提出锁申请,由 Enqueue Server 完成和管理锁。应用服务器实例上所有用户当前会话持有的锁,都维护在 Enqueue 服务器的锁信息管理表中,该表维护在 Enqueue 服务器的内存中,不会进行持久化,因此 Enqueue 服务器成为了 ABAP 系统的单点故障源之一:当 Enqueue 服务器由于各种原因运行时发生故障需要重启时,维护在内存中的锁信息表的数据会丢失。



因此为了确保 Enqueue 服务器的高可用性,通常将其放到单独的物理主机上部署,甚至引入遵循主从机制的多台 Enqueue 服务器,将 Master Enqueue 服务器上的锁信息管理表同步到其他 Enqueue 服务器上。



事务码 SM12 查看某个用户持有的应用锁:



SE11 里打开任意一个锁对象,点击 Lock Modules,进入自动生成的 ABAP 函数内部,就可以了解锁请求是如何从应用服务器发送到 Enqueue 服务器的。


SAP Message Server

每个 SAP 系统只能包含一个消息服务器,该组件负责完成以下任务:(1) 作为 SAP 系统内多个应用服务器实例间通讯的中央渠道(2) 对来自客户端通过 SAP GUI 和 SAP RFC 登录请求的负载分发当一个应用服务器实例启动后,其 Dispatcher 进程就会联系消息服务器,向其报告自己能够提供的服务类型。SAP 系统的消息服务器地址,可以在 SAP GUI 里维护该系统登录信息的 Message Server 字段里查询到。



上图我登录的 AG3 系统有多个应用服务器实例,我登录的实例编号为 54,使用事务码 SM53 发现这个系统还有另外两个实例,编号为 55 和 56.



忽视 SAP 系统可以由多个应用服务器实例组成这一点,有时候可能会遇到一些无法按照自己期望工作的场景.比如数据库性能测量工具 ST05,如果在实例 A 上打开跟踪,而业务代码实际执行在实例 B 上,那么待分析性能的应用执行完毕后,在实例 A 上关闭跟踪后,当然看不到性能数据。这种情况下,最保险的做法就是,在激活跟踪时,选择“在所有实例上”打开跟踪开关。


总结

本文详细介绍了 ABAP 服务器的各大组成部分和其职责所在。了解这些底层系统知识,有助于 ABAP 开发人员写出更健壮的 ABAP 应用,同时工作过程中遇到相关问题,也能更加明确从哪些方向入手进行问题的分析和定位。

发布于: 刚刚阅读数: 5
用户头像

Jerry Wang

关注

🏆InfoQ写作平台-签约作者🏆 2017.12.03 加入

SAP成都研究院开发专家,SAP社区导师,SAP中国技术大使。2007 年从电子科技大学计算机专业硕士毕业后加入 SAP 成都研究院工作至今。工作中使用 ABAP, Java, JavaScript 和 TypeScript 进行开发。

评论

发布
暂无评论
一个15年ABAP老兵的建议:了解这些基础知识,对ABAP开发有百利而无一害_后台开发_Jerry Wang_InfoQ写作社区