戰(zhàn):50MW 電站接入中的 Token 刷新與斷流重連)
去年 11 月我們?cè)跒橐粋€(gè)華東區(qū)域的資產(chǎn)方做 150 個(gè)工商業(yè)電站的集中監(jiān)控平臺(tái)。本以為華為 FusionSolar 的 Northbound API 文檔寫得夠厚對(duì)接起來(lái)應(yīng)該很穩(wěn)結(jié)果上線第一周就遭遇了「凌晨?jī)牲c(diǎn)的報(bào)警地獄」。當(dāng)時(shí)最詭異的現(xiàn)象是明明程序在跑但數(shù)據(jù)就是斷斷續(xù)續(xù)查看日志全是 407 錯(cuò)誤。這就引出了我們今天要聊的第一個(gè)硬骨頭——身份認(rèn)證的保活機(jī)制。很多剛做華為 API 對(duì)接的同學(xué)最容易掉進(jìn)「Token 刷新」和「請(qǐng)求頻率限制」這兩個(gè)坑里。華為的 OpenAPI 不是那種隨便寫個(gè) Curl 就能一直跑的簡(jiǎn)單接口它有一套非常嚴(yán)謹(jǐn)甚至有些繁瑣的狀態(tài)機(jī)邏輯。認(rèn)證?;顒e被文檔里的 30 分鐘給騙了華為 FusionSolar 的北向接口采用的是 Token 認(rèn)證文檔里明確說(shuō) Token 有效期是 30 分鐘。常規(guī)思路是寫個(gè)定時(shí)任務(wù)每 25 分鐘去請(qǐng)求一次/thirdparty/v1/auth/login。但實(shí)戰(zhàn)中你會(huì)發(fā)現(xiàn)如果你短時(shí)間內(nèi)頻繁觸發(fā)登錄系統(tǒng)會(huì)直接把你關(guān)進(jìn)黑名單報(bào)「頻率受限」。關(guān)鍵點(diǎn)在于華為提供了一個(gè)/thirdparty/v1/auth/keepAlive接口。我們的經(jīng)驗(yàn)是千萬(wàn)不要重復(fù)登錄而是要學(xué)會(huì)「?;睢?。# 偽代碼邏輯正確的?;钭藙?shì)defmaintain_connection():tokenget_stored_token()last_activeget_last_time()# 不要等到 30 分鐘建議 10-15 分鐘?;钜淮蝘ftime.now()-last_active900:try:responsepost(/thirdparty/v1/auth/keepAlive,headers{XSRF-TOKEN:token})ifresponse.code401:# Token 全面失效才重新登錄re_login()exceptExceptionase:logger.error(f?;钍?{e})這里有個(gè)隱藏的坑華為的 API 區(qū)分「專業(yè)版」和「普通版」不同版本的接入地址前綴BaseURL是不一樣的。很多開(kāi)發(fā)者在測(cè)試環(huán)境調(diào)通了換到正式環(huán)境就 404往往是因?yàn)闆](méi)注意intl.fusionsolar.huawei.com這種細(xì)微的后綴差異。在處理 50MW 級(jí)的大量電站時(shí)建議把 Token 存在 Redis 里并給它加上一個(gè)分布式鎖。否則你的多個(gè)采集節(jié)點(diǎn)同時(shí)去刷 Token百分之百會(huì)觸發(fā)平臺(tái)的安全限流導(dǎo)致全線崩潰。大規(guī)模數(shù)據(jù)拉取的異步藝術(shù)當(dāng)你解決了認(rèn)證問(wèn)題真正的挑戰(zhàn)才剛開(kāi)始。我們要拉取 100 多個(gè)電站、上千臺(tái)逆變器的實(shí)時(shí) KPI 數(shù)據(jù)華為的 API 限制了單次請(qǐng)求的設(shè)備數(shù)量通常是 100 個(gè)設(shè)備。如果你采用同步輪詢一個(gè)接一個(gè)請(qǐng)求你會(huì)發(fā)現(xiàn) 5 分鐘的采樣周期根本跑不完一遍。去年那個(gè)項(xiàng)目我們初期用單線程跑輪完一遍花了將近 8 分鐘導(dǎo)致時(shí)序數(shù)據(jù)庫(kù)里的數(shù)據(jù)全是斷層的。這時(shí)候必須上異步任務(wù)隊(duì)列。我們當(dāng)時(shí)的解法是設(shè)備打散按照廠商給的 API 額度把上千臺(tái)設(shè)備拆成 10-20 個(gè) Batch。并發(fā)控制控制并發(fā)請(qǐng)求數(shù)在 10qps 以內(nèi)。華為的網(wǎng)關(guān)非常敏感一旦瞬時(shí)并發(fā)過(guò)高不僅會(huì)丟包還會(huì)觸發(fā) 10 分鐘的靜默期。數(shù)據(jù)對(duì)齊這是最頭疼的。華為 API 返回的時(shí)間戳是電站當(dāng)?shù)貢r(shí)間如果你在做跨時(shí)區(qū)的平臺(tái)比如同時(shí)管著國(guó)內(nèi)和歐洲的站一定要在入庫(kù)前統(tǒng)一轉(zhuǎn)換成 UTC 或 Unix 時(shí)間戳。我們當(dāng)時(shí)就因?yàn)闆](méi)處理好時(shí)區(qū)偏移導(dǎo)致凌晨的數(shù)據(jù)全都錯(cuò)位到了前一天。數(shù)據(jù)歸一化的「血淚史」做多品牌逆變器集成的工程師都知道華為的數(shù)據(jù)字段命名有它自己的邏輯。比如「逆變器狀態(tài)」它返回的是一個(gè)整型數(shù)值。文檔里寫著 0 是待機(jī)1 是運(yùn)行2 是故障……但實(shí)際對(duì)接中你會(huì)發(fā)現(xiàn)有些型號(hào)的逆變器會(huì)蹦出文檔里沒(méi)寫的代碼。我們整理了一張核心字段對(duì)照表這是在接入了 3000 多臺(tái)華為設(shè)備后總結(jié)出來(lái)的字段名 (華為)含義常見(jiàn)坑點(diǎn)active_power有功功率注意單位是 kW 還是 W不同 API 版本有差異day_cap日發(fā)電量凌晨 0 點(diǎn)不一定清零會(huì)有幾分鐘的延遲刷新dev_status設(shè)備狀態(tài)必須做異常值兼容遇到未定義代碼建議設(shè)為“未知”elec_freq電網(wǎng)頻率偶爾會(huì)出現(xiàn) 0 或 5000 這種異常跳變需要做濾波清洗尤其是day_cap日發(fā)電量華為的云端統(tǒng)計(jì)邏輯是在其服務(wù)器端計(jì)算的。如果你發(fā)現(xiàn) API 返回的數(shù)據(jù)和逆變器本地 App 看到的數(shù)據(jù)有幾度電的誤差別驚訝這是正常的。因?yàn)樵贫舜嬖谘a(bǔ)傳和計(jì)算延時(shí)。如果你的業(yè)務(wù)對(duì)電費(fèi)結(jié)算非常敏感建議還是抓取累計(jì)電量Total Yield自己在后端做差值計(jì)算而不是直接信賴 API 返回的日發(fā)電量。異常重試與補(bǔ)傳如何應(yīng)對(duì)「數(shù)據(jù)黑洞」光伏電站的現(xiàn)場(chǎng)網(wǎng)絡(luò)環(huán)境通常很惡劣4G 信號(hào)波動(dòng)是常態(tài)。這就導(dǎo)致華為云平臺(tái)上的數(shù)據(jù)也經(jīng)常有空洞。如果你在拉取/thirdparty/v1/history/getStationHistoryData時(shí)發(fā)現(xiàn)某一段數(shù)據(jù)是空的千萬(wàn)別直接跳過(guò)。我們的做法是建立一個(gè)「重試池」。對(duì)于 24 小時(shí)內(nèi)缺失的數(shù)據(jù)程序會(huì)自動(dòng)每隔 1 小時(shí)嘗試重新拉取。因?yàn)槿A為的云平臺(tái)在接收到前端逆變器的補(bǔ)傳數(shù)據(jù)后會(huì)異步更新其北向接口的數(shù)據(jù)。你當(dāng)時(shí)拉不到不代表 1 小時(shí)后拉不到。這種「延遲補(bǔ)拉」機(jī)制讓我們的數(shù)據(jù)完整度從 85% 提升到了 99% 以上。說(shuō)實(shí)話每家逆變器廠家的 API 都是一肚子苦水。華為算好的起碼文檔還算規(guī)范。要是碰到某些二線品牌文檔只有 3 頁(yè) PDF那才叫盲人摸象。我們后來(lái)為了省事把這套多廠商華為、陽(yáng)光、古瑞瓦特、錦浪等的 API 對(duì)接、字段歸一化、以及最麻煩的 Token 維護(hù)和補(bǔ)傳邏輯全部封裝成了一個(gè)獨(dú)立的中間件。在內(nèi)部我們叫它 ZenovaConnect它的作用就是把不同品牌那些亂七八糟的接口統(tǒng)一成一套干凈的 Webhook 或者 Kafka 流上層應(yīng)用只管接數(shù)據(jù)再也不用管什么 Token 刷新或者 407 報(bào)錯(cuò)了。我們的工程判斷在做華為 API 集成時(shí)最核心的取舍在于你是要實(shí)時(shí)性還是要穩(wěn)定性很多老板要求「秒級(jí)監(jiān)控」但在 API 層面這幾乎是不可能的。華為云的北向同步頻率通常在 5 分鐘左右強(qiáng)行通過(guò)高頻調(diào)用 API 去實(shí)現(xiàn)秒級(jí)監(jiān)控只會(huì)導(dǎo)致賬號(hào)被封禁。我們的建議是實(shí)時(shí)性交給現(xiàn)場(chǎng)的采集器如 SmartLogger而云端 API 只負(fù)責(zé) 5-15 分鐘級(jí)的資產(chǎn)管理和能效分析。最后留個(gè)問(wèn)題給各位同行你在對(duì)接華為 API 時(shí)有沒(méi)有遇到過(guò)XSRF-TOKEN校驗(yàn)失敗但明明 Token 還沒(méi)過(guò)期的情況你是通過(guò)強(qiáng)制重新登錄解決的還是有更優(yōu)雅的?;畈呗詺g迎在評(píng)論區(qū)交流踩坑心得。了解 ZenovaConnect 完整方案