:NW RFC SDK開發(fā)與排錯指南)
簡介NW RFC SDK for Windows 7.50.15是SAP官方推出的遠(yuǎn)程函數(shù)調(diào)用開發(fā)套件面向Windows平臺上的C/C與.NET開發(fā)者用于打通外部系統(tǒng)與SAP系統(tǒng)間的RFC通信可實現(xiàn)同步/異步調(diào)用、事務(wù)性RFC、隊列RFC及后臺RFC覆蓋企業(yè)系統(tǒng)集成、數(shù)據(jù)同步與自動化運維等場景。壓縮包為RAR格式體積約14.9MB共29個文件包含C/C頭文件、靜態(tài)庫和動態(tài)鏈接庫、示例源碼、可執(zhí)行程序、配置文件及說明文檔并按bin、include、lib、samples四個目錄清晰組織便于定位所需文件。目前已有418人學(xué)習(xí)下載適合正在搭建SAP RFC開發(fā)環(huán)境或需要排查通信問題的中高級開發(fā)者。資源內(nèi)含完整的函數(shù)庫、官方示例及文檔支持Visual Studio 2019/2022與.NET Framework/Core環(huán)境配置好環(huán)境變量即可直接編譯運行示例幫助讀者快速掌握NW RFC的調(diào)用流程和常用接口用法。同時包含多種調(diào)用場景的示例代碼如客戶端連接、性能測試、深度表讀取等可參考學(xué)習(xí)連接參數(shù)配置、函數(shù)調(diào)用和性能測試方法。 做過SAP集成開發(fā)的兄弟們都懂不管你是做ERP外圍接口、MES對接還是數(shù)據(jù)中臺同步SAP對外通信最成熟的路徑始終繞不開RFCRemote Function Call這套協(xié)議。而NW RFC SDK就是SAP官方提供給開發(fā)者的標(biāo)準(zhǔn)通信開發(fā)包它把底層的SAP RFC協(xié)議封裝成C/C、C#、Java等語言可以直接調(diào)用的接口庫。我最近在Windows平臺上做S/4HANA集成項目選用的正是NW RFC SDK 7.50.15這個版本這個版本屬于NetWeaver 7.50補丁周期的穩(wěn)定版解決了不少老版本在64位Windows環(huán)境下的內(nèi)存和TLS連接問題。這篇文章我會從安裝配置、環(huán)境準(zhǔn)備、第一個RFC調(diào)用寫到排錯經(jīng)驗盡量把實際操作中那些文檔里不會寫的東西一起講掉給正在搞SAP集成的朋友一個完整的參考。1. 項目概覽為什么NW RFC SDK仍是SAP集成的核心武器1.1 SAP對外集成的幾種通道對比做SAP外部系統(tǒng)集成的開發(fā)者面對的第一個選擇往往是“用哪種技術(shù)跟SAP通信”。目前主流的方案有RFC、REST/OData、SOAP Web Service和IDoc幾種。OData和SOAP上手簡單SAP Gateway發(fā)布服務(wù)以后用HTTP協(xié)議直接調(diào)JSON或者XML前端和后端團(tuán)隊都很熟悉。但真正到了企業(yè)級高并發(fā)、事務(wù)性強、需要頻繁調(diào)用大量BAPIBusiness Application Programming Interface的場景RFC依然是壓艙石般的存在。RFC協(xié)議的優(yōu)勢在于它直接嵌入了SAP NetWeaver的應(yīng)用服務(wù)器通信棧天然支持事務(wù)管理、隊列處理和負(fù)載均衡。你可以同時發(fā)起多個會話支持同步調(diào)用和異步調(diào)用還支持SAP系統(tǒng)之間常見的tRFC和qRFC機制。這些能力在對接SAP ECC、S/4HANA、CRM等核心系統(tǒng)時非常關(guān)鍵。NW RFC SDK正是將這些底層能力開放給外部開發(fā)者的官方工具包支持的開發(fā)語言也很廣C、C、C#、Java、Python通過PyRFC封裝都能直接對接。1.2 NW RFC SDK 7.50.15版本的核心特性我這次選7.50.15不是隨便挑的版本號。SAP在7.50這條NetWeaver分支上的補丁迭代一步一步補齊了很多在Windows生產(chǎn)環(huán)境里會遇到的實際問題。這個版本有幾個點值得關(guān)注64位Windows下穩(wěn)定性增強早期一部分7.50.x版本在Windows Server 2016/2019上長時間跑會有句柄泄漏和內(nèi)存緩慢增長的隱患7.50.15對這塊做了針對性修復(fù)。TLS加密連接更可靠新版SDK對SAP系統(tǒng)啟用了SNCSecure Network Communications或TLS加密的場景下握手過程和證書解析的兼容性更高。我在S/4HANA 2020上啟用TLS后沒有出現(xiàn)之前那種偶發(fā)的斷連情況。Unicode數(shù)據(jù)轉(zhuǎn)換優(yōu)化對中文、日文等多字節(jié)字符的編碼轉(zhuǎn)換邏輯做了優(yōu)化在非Unicode的SAP系統(tǒng)之間同步數(shù)據(jù)時亂碼的概率明顯降低。和后續(xù)版本的兼容性雖然現(xiàn)在已經(jīng)有了更高版本的NW RFC SDK比如7.53、7.55但7.50.15依然被大量生產(chǎn)系統(tǒng)使用兼容性經(jīng)過了好幾輪驗證是個“穩(wěn)”字當(dāng)頭的選擇。2. Windows環(huán)境下的安裝與配置2.1 下載渠道與文件選擇NW RFC SDK的下載入口在SAP Support Portal需要SAP賬號并有對應(yīng)的產(chǎn)品授權(quán)。登錄后在Software Downloads里搜索“NW RFC SDK”會選擇對應(yīng)的平臺Windows x64或x86和版本號。需要注意下載頁面上可能會同時出現(xiàn)“SAP NW RFC SDK 7.50”和“SAP NW RFC SDK 7.53/7.55”等不同版本選7.50分支下的最新補丁即可。下載下來的壓縮包通常包括兩個核心目錄lib目錄是實際的動態(tài)鏈接庫文件sapnwrfc.dllinclude目錄是頭文件examples目錄有C/C的示例代碼doc目錄里放著API參考文檔。如果做Java開發(fā)還會看到sapjco3.jar和對應(yīng)的本地庫文件但NW RFC SDK和JCo是兩套獨立產(chǎn)品這里主要說的是原生C/C和C#的調(diào)用場景。2.2 安裝步驟與系統(tǒng)環(huán)境變量配置其實NW RFC SDK本身沒有傳統(tǒng)意義上的安裝程序它的“安裝”就是解壓到你想要的工作目錄然后讓程序能正確找到DLL和配置文件。省事的做法是把整個SDK目錄放到一個不帶空格和中文的路徑下比如D:\sap\nwrfc750然后在系統(tǒng)環(huán)境變量PATH里添加D:\sap\nwrfc750\lib這樣運行時就能自動找到sapnwrfc.dll。如果你的項目是用C#開發(fā)并引用了對應(yīng)的.NET封裝還要確保Visual Studio的“平臺目標(biāo)”和SDK位數(shù)一致。比如SDK是64位的項目在AnyCPU狀態(tài)下跑在64位系統(tǒng)上沒問題但如果目標(biāo)平臺是x86就要下載32位的SDK。這個細(xì)節(jié)很多人忽略等到運行時彈出“無法加載DLL”才意識到架構(gòu)不匹配。2.3 驗證SDK是否工作正常解壓和配置完環(huán)境變量以后建議先用SDK自帶的示例程序做一次連通性驗證。在examples目錄下找到C語言的調(diào)用示例編譯運行時需要傳入SAP連接參數(shù)。最直接的方式是寫一個極簡的C#控制臺加載Interop.SAPLogonCtrl或者直接P/Invoke調(diào)用sapnwrfc.dll先測試建立連接。如果連SAP系統(tǒng)都沒有也可以先在本地搭建一個SAP NetWeaver Trial環(huán)境或者連接公司已有的SAP測試服務(wù)器。注意運行時如果提示缺少libsapnwrfc.dll或msvcp140.dll先安裝Visual C Redistributable for Visual Studio 2015-2022這是最常見的坑SDK依賴VC運行庫。3. 核心開發(fā)實例從連接到調(diào)用3.1 配置RFC目標(biāo)SM59在寫代碼之前SAP端必須先把RFC目標(biāo)配置好。這個操作通常是SAP Basis管理員來做但開發(fā)者也應(yīng)該知道流程。事務(wù)代碼SM59進(jìn)入RFC目標(biāo)配置界面創(chuàng)建一個新的“TCP/IP連接”類型的目標(biāo)填上你的外部程序名稱這個名稱要和代碼里的Program ID或者連接參數(shù)對應(yīng)設(shè)置好通信類型和網(wǎng)關(guān)主機保存激活。如果SAP系統(tǒng)啟用了SNC還需要配置SNC Partner Name和加密選項。我在實際項目中見過很多次因為SM59配置錯誤導(dǎo)致的外部程序連接被拒。最常見的問題是目標(biāo)類型選錯外部程序通過NW RFC SDK主動連接SAP時SM59里的目標(biāo)類型通常應(yīng)該是TTCP/IP連接方式選Registered Server Program這時SAP網(wǎng)關(guān)會等外部程序注冊也就是常說的“服務(wù)器模式”還有一種GHTTP或者其他方式用于不同的通信場景不要搞混。3.2 C#調(diào)用SAP函數(shù)模塊SDK本身的原生接口是C API但通過P/Invoke或者第三方封裝C#也能方便地使用。這里我寫一個最簡示例展示如何使用C#調(diào)用SAP的RFC_PING函數(shù)模塊來驗證連接。這個函數(shù)就是SAP內(nèi)部一個“測試連通性”的標(biāo)準(zhǔn)函數(shù)什么都不過多參與非常適合當(dāng)hello world。using System; using SapNWRFC; using SAP.Middleware.Connector; class Program { static void Main() { var destParams new RfcDestinationParameters { // 這些參數(shù)對應(yīng)SDK的配置文件也對應(yīng)SM59里的連接信息 RfcConfigProperties.AppServerHost 192.168.1.10, RfcConfigProperties.SystemNumber 00, RfcConfigProperties.Client 800, RfcConfigProperties.User RFC_USER, RfcConfigProperties.Password your_password, RfcConfigProperties.Language EN }; try { RfcDestination dest RfcDestinationManager.GetDestination(destParams); dest.Ping(); Console.WriteLine(RFC連接成功); } catch (RfcCommunicationException ex) { Console.WriteLine($通信異常: {ex.Message}); } catch (RfcInvalidStateException ex) { Console.WriteLine($狀態(tài)異常: {ex.Message}); } } }這個代碼里的RfcConfigProperties.AppServerHost、SystemNumber、Client是連接SAP的基本參數(shù)。AppServerHost是SAP應(yīng)用服務(wù)器的IP或主機名SystemNumber是實例號比如00Client是客戶端編號User和Password是RFC專用賬號。這里如果用RfcConfigProperties.SystemID加上消息服務(wù)器的地址還可以走負(fù)載均衡的方式連接適合在集群環(huán)境下使用。3.3 傳遞表結(jié)構(gòu)和復(fù)雜參數(shù)實際的業(yè)務(wù)場景基本都不會停在只調(diào)一個RFC_PING的程度更多時候是要給函數(shù)模塊傳表、傳結(jié)構(gòu)體。RFC里的表Table對應(yīng)到C#就是二維數(shù)組或DataTable結(jié)構(gòu)Structure對應(yīng)自定義的類或結(jié)構(gòu)體。下面的示例演示了調(diào)用一個帶輸入表、輸出表的標(biāo)準(zhǔn)BAPI。RfcFunction fn dest.CreateFunction(BAPI_MATERIAL_GETLIST); RfcStructure importParam fn.GetStructure(IMPORTDATA); importParam.SetValue(MATERIAL_SHORT_TEXT, 測試物料); RfcTable tableParam fn.GetTable(MATNRLIST); tableParam.Append(); tableParam.SetValue(MATERIAL, 100001); tableParam.SetValue(MATERIAL_TYPE, FERT); fn.Invoke(dest); RfcTable resultTable fn.GetTable(MATNRLIST); for (int i 0; i resultTable.RowCount; i) { resultTable.CurrentIndex i; Console.WriteLine($物料號: {resultTable.GetString(MATERIAL)}); }這段代碼里有個關(guān)鍵點是CreateFunction之后必須先獲取結(jié)構(gòu)體引用并賦值再獲取表的引用執(zhí)行Invoke之后再去讀輸出表的內(nèi)容。如果你調(diào)用的函數(shù)是BAPI_TRANSACTION_COMMIT這類事務(wù)型BAPI還要注意在Invoke之后調(diào)用BAPI_TRANSACTION_COMMIT提交事務(wù)否則數(shù)據(jù)不會真正寫入SAP系統(tǒng)。4. 實戰(zhàn)中的典型問題與解決方案4.1 連接異常排查我在多個項目上積累了一套排查RFC連接問題的思路這里整理成速查表比你對著日志亂猜要快得多。現(xiàn)象大概率原因排查/解決辦法RfcCommunicationException: connection refusedSAP網(wǎng)關(guān)未啟動或端口不對檢查SAP實例的網(wǎng)關(guān)端口默認(rèn)為33xxxx是實例號檢查防火墻是否放行RfcLogonException: user / password invalid賬號問題確認(rèn)RFC賬號在SU01里有權(quán)限是否勾選了“RFC”類型的授權(quán)RfcLibException: snc mode activated but no SNC nameSNC配置缺失SM59里配置好SNC Partner Name代碼中設(shè)置RfcConfigProperties.SncMode 1及證書信息RfcBufferException: system ID inconsistency連接參數(shù)或負(fù)載均衡配置錯誤檢查SystemID、Message Server地址以及是否選擇了正確的連接方式RfcStateException: function module not found調(diào)用的函數(shù)模塊名稱錯誤或不存在用SE37確認(rèn)函數(shù)模塊名注意大小寫其中最讓人頭大的就是SNC相關(guān)問題它往往和證書、加密算法都有關(guān)系。如果你公司SAP系統(tǒng)強制啟用SNC代碼里需要額外設(shè)置SncPartnerName和SncQop這兩個值可以從SAP安全團(tuán)隊那里拿。調(diào)試階段可以把SncQop設(shè)成1也就是最低加密級別但生產(chǎn)環(huán)境一定要用更高的QOP級別。4.2 DLL加載失敗與運行時崩潰很多開發(fā)者在Windows環(huán)境跑NW RFC SDK時都會遇到“無法加載DLL‘sapnwrfc.dll’”或者莫名其妙的崩潰。這類問題絕大部分可以歸結(jié)為三個原因路徑?jīng)]配對SDK的DLL不在當(dāng)前程序的搜索路徑里或者環(huán)境變量PATH沒有生效。64位程序和32位SDK混用也會造成加載失敗。VC運行庫缺失NW RFC SDK依賴Visual C運行庫缺了會報0xC000007B之類的錯誤。解決辦法是安裝對應(yīng)的VC Redistributable包最好是2015-2022合一的版本。認(rèn)證和權(quán)限問題如果你的程序運行在IIS或Windows服務(wù)宿主下運行賬戶可能沒有訪問SDK目錄的權(quán)限。把SDK放到一個公共目錄并給運行賬戶加上讀取/執(zhí)行權(quán)限。如果你用C#寫的是Web API建議把RFC調(diào)用封裝成獨立的后臺服務(wù)而不是直接掛在Web請求線程里。RFC調(diào)用在某些異常情況下會長時間阻塞容易把線程池打滿。我以前在IIS里直接調(diào)RFC高峰期出現(xiàn)了連接池耗盡的問題后來改成獨立的Windows服務(wù)用消息隊列接收請求再通過RFC批量執(zhí)行BAPI性能和穩(wěn)定性都有明顯改善。4.3 性能調(diào)優(yōu)心得RFC調(diào)用雖然可靠但不是免費的午餐。每次建立RFC連接都需要經(jīng)過SAP網(wǎng)關(guān)的握手認(rèn)證如果外部程序頻繁開關(guān)連接性能損耗非常明顯。我在項目里通常用一個靜態(tài)連接池或者持久連接的方式復(fù)用同一套連接參數(shù)來多次調(diào)用BAPI。NW RFC SDK在連接復(fù)用方面支持得不錯只要通過RfcDestinationManager.GetDestination拿到的對象多次調(diào)用CreateFunction不會每次新建會話。實際操作中我會把連接池大小控制在5到20之間這個數(shù)字取決于SAP服務(wù)器上可用的工作進(jìn)程數(shù)和應(yīng)用服務(wù)器的壓力。連接太多會讓SAP端的調(diào)度出現(xiàn)瓶頸連接太少在高并發(fā)時排隊時間又會上升。比較好的做法是先壓測測出單連接每秒能處理的RFC調(diào)用數(shù)再根據(jù)預(yù)期的QPS反推連接數(shù)通常留出30%的冗余即可。另外批量獲取數(shù)據(jù)時盡量用SAP端封裝的批處理函數(shù)模塊比如BAPI_MATERIAL_GETLIST本身支持傳入多個物料編號而不是在循環(huán)里一個個調(diào)BAPI_MATERIAL_GET_DETAIL。減少RFC往返次數(shù)是性能優(yōu)化收益最大的手段。5. 寫給初入SAP集成的開發(fā)者如果你之前完全沒有接觸過SAP RFC第一次拿到NW RFC SDK的壓縮包時可能會有點懵滿眼的dll和頭文件不知道從哪下手。我的建議是分三步走先理解SAP的通信模型搞清楚RFC函數(shù)模塊、BAPI、IDoc的區(qū)別和聯(lián)系。BAPI是標(biāo)準(zhǔn)化的業(yè)務(wù)對象接口RFC函數(shù)模塊的范圍更廣IDoc主要用于異步數(shù)據(jù)交換。理解這些之后你才能知道代碼里該調(diào)什么。手寫一遍最簡單的連接和調(diào)用不要一開始就依賴各種高級封裝庫把RFC_PING跑通感受一下連接參數(shù)怎么影響通信過程。再進(jìn)入實際業(yè)務(wù)代碼的開發(fā)這時候你再看那些封裝好的框架心里就有底了。我在實際使用中最明顯的一個體會是NW RFC SDK的官方示例代碼風(fēng)格偏底層C的示例看著很繁瑣但正是這種復(fù)雜度讓我對RFC通信的機制有了更深的理解。后來換到C#或者PyRFC反而覺得一切都是順理成章的。最后再分享一個細(xì)節(jié)如果你是做長期運行的服務(wù)中間件別忘了在異常處理中捕獲RfcAbapException和RfcServerException這些異常表示ABAP層拋出的業(yè)務(wù)錯誤和系統(tǒng)錯誤二者處理策略完全不同。業(yè)務(wù)錯誤通常要反饋給調(diào)用方修改參數(shù)或者重新執(zhí)行系統(tǒng)錯誤則更可能是SAP環(huán)境問題建議記錄日志并告警。把這些分類做好生產(chǎn)環(huán)境的排障效率能提升一個量級。本文還有配套的精品資源點擊獲取