咱們的文件(用戶的身份證件,隱私視頻等)都放在 阿里雲 OSS,OSS Bucket Name 存儲空間 的讀寫權限 設置爲 私有,表明 屬於這個 bucket name 的文件 都須要通過 身份認證 才能訪問。前端
目前文件 uri 分佈在各個服務中,前端 若是須要操做或顯示圖片,都要經過 OSS SDK 生成可預覽 URL 纔有權限訪問。spring
那麼這個問題就變成,「經過 OSS SDK 生成可預覽 URL」 這個職責 應該 交給誰(前端 or 後端)來承擔更合適?數據庫
假設這個問題由後端解決,那麼就會有如下用例:後端
給定 /test 接口bash
而且 /test 接口返回如下數據架構
{
"name": "越前龍馬",
"url": "yqlm.jpeg",
"testItem": {
"imageUrl": "test111111.png",
"name": "test111111"
},
"testItems": [
{
"imageUrl": "test-image.jpeg",
"name": "test-image"
}
]
}
複製代碼
當 前端調用 /test 接口微服務
那麼 前端將獲得如下數據單元測試
{
"name": "越前龍馬",
"url": "https://endpoint/yqlm.jpeg?Expires=1571308870&OSSAccessKeyId=xxx&Signature=BdNd1zAcr3r4GZyupVW134W2UQ0=",
"testItem": {
"imageUrl": "https://endpoint/test111111.png?Expires=1571308870&OSSAccessKeyId=xxx&Signature=pQUh8SzS+kQnxOkGwoS6NaRTmJs=",
"name": "test111111"
},
"testItems": [
{
"imageUrl": "https://endpoint/test-image.jpeg?Expires=1571308870&OSSAccessKeyId=xxx&Signature=KAcEkGb2P68/mFpLoJcak42kMtw=",
"name": "test-image"
}
]
}
複製代碼
優點:後端不須要額外調用 OSS SDK API(特別是分頁接口比較繁瑣)。測試
劣勢:把問題拋給前端,前端有 IOS、Android、和 WEB,致使每一個端都須要關注這個問題。阿里雲
總體上這個方案可行,不過對各個前端不友好,還不是理想的解決方案。
優點:各個前端 不須要關注 如何對文件進行身份認證。
劣勢:把問題 拋給各個服務的負責人,每一個服務 都須要集成 OSS SDK,還須要瞭解 如何正確使用;並且很明顯這些都是 重複代碼。
這個方案跟第一個方案差很少,把問題 從前端 拋給了 各個服務,還不是理想的解決方案。
優點:職責更加合理,各個服務經過 Feign 或 RPC 跟 文件服務 交互,具體的細節封裝在 文件服務 中。
劣勢:各個服務 仍是須要關注 什麼時候 該調用 文件服務 生成可預覽 URL。
經過 增長 文件服務 來承擔 生成文件可預覽 URL 的職責,消除各個服務的重複的關注點,很是適合私有文件比較少的場景,明顯 方案 3 比以前兩個方案 都要合理一些,算是一個備選方案。
優點:各個前端 和 各個後端服務 都不須要關注 什麼時候須要生成可預覽的 URL,什麼時候 以及 如何生成 統一交給 API 網關處理。
劣勢:API 網關 須要維護好 與 文件服務的調用關係,還須要分析每一個請求的 response body 並修改 response body,這些操做處理起來都須要謹慎當心,作好充足的單元測試 和 API 測試,避免影響全部的 API 接口。
筆者在寫這邊文章的時候,就已經基於 spring cloud gateway 實現了方案 4,該方案確實特別方便,實現起來也沒什麼難度,不過須要先後端約定好保存到數據庫的 file uri 的格式。
基於微服務架構風格,該問題 筆者已經總結了 4 種解決方案(真實狀況遠遠不止 4 種),每種解決方案都有利弊,若是還有更好的解決方案,歡迎一塊兒交流。