SAP ABAP 守护进程的实现方式
笔者本科学习《计算机操作系统》这门专业课时,了解到了守护进程的理念,当时我们是从 Linux 操作系统里的守护进程开始学习这个概念的:Linux 守护进程是运行在后台的一种特殊进程,独立于控制终端并且周期性地执行某种任务,或等待处理某些将要发生的事件。Linux 系统很多服务都通过守护进程实现,常见的守护进程有系统日志进程 syslogd,web 服务器 httpd,邮件服务器 sendmail 和数据库服务器 mysqld 等。
那么在 ABAP 里能否实现具有守护进程特性的报表?这个需求翻译成 ABAP 的术语,即是否能够开发一个满足下列特征的 ABAP 程序?
终端(SAPGUI 或 ABAP Development Tool)关闭后仍然能够继续运行,且能继续接收用户输入,处理并推送结果给用户。
很多朋友一定很快就会想到 ABAP 后台作业。没错,开发一个 ABAP 报表,以后台作业的方式启动,的确可以实现脱离终端运行的效果。然而这种后台作业无法再以普通方式接受用户输入,一种比较笨重的解决方式是采取生产者-消费者的思路,定义一个数据库表,充当任务队列;用户将请求插入到该数据库表里,而后台作业程序周期性地去查询该数据库表,如果非空,则取出请求并处理。
另一种思路就是在事务码 SICF 里创建一个新的节点并在其 handler class 里书写处理逻辑,这样消费者可以发送 HTTP 请求到该 ICF 节点负责的 url,并接收处理结果。
之前笔者的文章 一个15年ABAP老兵的建议:了解这些基础知识,对ABAP开发有百利而无一害介绍过,ABAP 服务器同外界通过 HTTP 交互,会经过 Internet Communication Manager(ICM)这个模块,通过这种方式实现的 ABAP 程序,表面上看也勉强模仿了守护进程的效果,但请求处理的性能和真正的守护进程相比相差甚远,并且本质上是借助 Web 服务器实现的。
一个好消息是,在 2018 年 SAP 发布的 ABAP Platform 1809 中,提到了一些激动人心的新特性,比如针对工业物联网(Industrial IoT)和 Machine-to-Machine 通信的增强,MQTT 的引入,以及对 ABAP Daemons 的原生支持。
本文我们就用 ABAP 平台 1809 新引入的 ABAP MQTT 和 ABAP Daemons 来实现一个 Hello World 级别的 ABAP 守护进程。
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)是一种基于发布/订阅模式的轻量级通讯协议,构建于 TCP/IP 协议上,因其低开销和低带宽占用的优点,在物联网、小型设备、移动应用等方面应用特别广泛。
关于 ABAP 平台 1809 新特性的更多介绍,请参阅 SAP 社区博客。
ABAP 守护进程和 MQTT 密切相关,因此我们先来了解 ABAP 平台 1809 新引入的对 MQTT 的支持。
设想一个简单的“一问一答”的场景,在 ABAP 平台上开发一个 MQTT 客户端,往第三方的 MQTT broker(代理)发送消息,并接收其回复。
新建一个 ABAP 类,实现 SAP 标准接口 IF_MQTT_EVENT_HANDLER 的对应方法。
至于 MQTT broker,我选择了一个基于 HiveMQ 的公开 Broker:broker.mqttdashboard.com,可以使用下面这个用 webSocket 实现的 MQTT客户端来操作该 broker.
这个 broker 专门用于测试用途,收到 MQTT 消息后,会原封不动地将其回复给发送方。
在 ABAP 类的构造函数里连接 MQTT broker,把返回的 MQTT 客户端实例存储在类的成员变量 mo_mqtt_client 里,接下来就能使用该实例的 publish 方法去发送消息,subscribe 方法订阅消息,on_message 方法接收消息。
打开 MQTT 客户端,订阅渠道:abaptopic/jerry/test
接着我首先在第 66 行,往该渠道发送一条 Hello World 的消息,broker 收到后会将其原封不动地返回,但因为我的 ABAP 类并没有订阅这个渠道,因此不会收到这条 hello world 消息的回复。
第 68 行订阅该渠道后,第 69 行发送第二条消息给 broker,这次就能收到其回复了。
回到 broker 客户端,看到从 ABAP 端发送过来的两条消息:
回到 ABAP 端,看到代码第 69 行发送的第二条消息的回复:
弄清楚 ABAP MQTT 的用法之后,我们就可以动手开发 ABAP 守护进程了。虽然 ABAP 守护进程并没有直接使用 MQTT 同使用者进行交互,但是掌握这种消息通知机制的用法,对我们了解 ABAP 守护进程的工作原理也有帮助。
新建一个 ABAP 类 zcl_jerry_simple_daemon,将 cl_abap_daemon_ext_base 设置成其父类。从基类继承的这些 ON 开头的方法,即 ABAP 守护进程生命周期事件发生时,开发人员能够实现自定义逻辑的位置,比如在系统 SHUTDOWN 时,开发人员实现的 ON_SYSTEM_SHUTDOWN 方法会触发,在此处完成守护进程的清理动作,实现优雅退出。
而最有用的方法,无疑就是 ON_MESSAGE,这也是守护进程接收用户输入并响应的地方。为简单起见,我的守护进程收到用户输入后,仅仅弹出一个弹出对话框,显示在 SAPGUI 里:
守护进程的启动则通过框架类 cl_abap_daemon_client_manager 的 start 方法实现,第 75 行 start 方法传入的参数 lo_pcp 作为守护进程启动参数一并传入,pcp 代表 Push Channel Protocol,一种用于消息传递的数据结构。
使用下列语句启动该守护进程,将其命名为 jerry_daemon:
在事务码 SMDAEMON 里可以看到所有正在运行的守护进程:
打开 SAPGUI,使用如下的方法向 jerry_daemon 这个 ABAP 守护进程发送一条消息,会立即在 SAPGUI 里看到守护进程的 on_message 方法里弹出的对话框:
因此将来我们如果遇到需要开发长时间脱离终端运行且仍需响应用户输入的 ABAP 程序,除了 ABAP 后台作业和 SICF 服务外,又多了 ABAP 守护进程这种选择。希望本文介绍的内容对你有用,感谢阅读。
版权声明: 本文为 InfoQ 作者【Jerry Wang】的原创文章。
原文链接:【http://xie.infoq.cn/article/3f877c2f8d42c058d293b55e1】。文章转载请联系作者。
评论