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