Jerry大學學習《計算機作業系統》這門專業課時,了解到了守護程序的理念,當時我們是從Linux作業系統裡的守護程序開始學習這個概念的:Linux守護程序是運作在背景的一種特殊程序,獨立于控制終端并且周期性地執行某種任務,或等待處理某些将要發生的事件。Linux系統很多服務都通過守護程序實作,常見的守護程序有系統日志程序syslogd,web伺服器httpd,郵件伺服器sendmail和資料庫伺服器mysqld等。
當時Jerry上這門專業課時,《暗黑破壞神II》在國内各大高校的戰網上正進行得如火如荼,Jerry也和其他暗黑愛好者一樣,天天在戰網上KB,KC, 刷暴躁外皮。
暗黑破壞神II裡有很多對惡魔(Demon)造成額外傷害的武器,比如下面這把用符文之語悔恨(Grief)制成的幻化之刃,對惡魔生物造成額外185%傷害:
當時Jerry在戰網上刷怪的時候,心想,Linux守護程序的名稱咋這麼酷?Demon Process - 惡魔程序。第二天翻開教材仔細一看,頓時尴尬了,原來守護程序的英文應該是Daemon Process...
那麼在ABAP裡能否實作具有守護程序特性的報表?這個需求翻譯成ABAP的術語,即是否能夠開發一個滿足下列特征的ABAP程式?
終端(SAPGUI或ABAP Development Tool)關閉後仍然能夠繼續運作,且能繼續接收使用者輸入,處理并推送結果給使用者。
很多朋友一定很快就會想到ABAP背景作業。沒錯,開發一個ABAP報表,以背景作業的方式啟動,的确可以實作脫離終端運作的效果。然而這種背景作業無法再以普通方式接受使用者輸入,一種比較笨重的解決方式是采取生産者-消費者的思路,定義一個資料庫表,充當任務隊列;使用者将請求插入到該資料庫表裡,而背景作業程式周期性地去查詢該資料庫表,如果非空,則取出請求并處理。
另一種思路就是在事務碼SICF裡建立一個新的節點并在其handler class裡書寫處理邏輯,這樣消費者可以發送HTTP請求到該ICF節點負責的url,并接收處理結果。
之前Jerry的文章一個13年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社群部落格:
https://blogs.sap.com/2018/10/01/abap-platform-for-sap-s4hana-1809/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:
http://www.hivemq.com/demos/websocket-client/這個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:
zcl_jerry_simple_daemon=>start( iv_daemon_name = 'jerry_daemon' ).
在事務碼SMDAEMON裡可以看到所有正在運作的守護程序:
打開SAPGUI,使用如下的方法向jerry_daemon這個ABAP守護程序發送一條消息,會立即在SAPGUI裡看到守護程序的on_message方法裡彈出的對話框:
是以将來我們如果遇到需要開發長時間脫離終端運作且仍需響應使用者輸入的ABAP程式,除了ABAP背景作業和SICF服務外,又多了ABAP守護程序這種選擇。
希望本文介紹的内容對你有用,感謝閱讀。
本文來自雲栖社群合作夥伴“汪子熙”,了解相關資訊可以關注微信公衆号"汪子熙"。