簡體   English   中英

高朗的多租戶

[英]Multi-tenancy in Golang

我目前正在Go中編寫服務,需要與多個租戶打交道。 我已經決定使用一個數據庫共享表方法,並使用“ tenant_id”定界符來分隔租戶。

服務的結構如下:

gRPC server -> gRPC Handlers -
                              \_ Managers (SQL)
                              /
HTTP/JSON server -> Handlers -

兩台服務器,一台gRPC(管理)和一台HTTP / JSON(公共API),每台服務器都在各自的例程中運行,並具有各自的處理程序,可以利用不同管理器的功能。 經理(讓我們稱其為“庫存經理”),全部生活在不同的根級包中。 據我所知,這些是我的域實體。

在這方面,我有一些問題:

  1. 我找不到任何支持多個租戶的ORM for Go。 在sqlx包之上編寫自己的代碼是否有效?

  2. 將來的其他服務也將需要多租戶支持,因此我想無論如何我都必須創建一些庫/包。

  3. 今天,我通過為公共API服務器使用ResolveTenantBySubdomain中間件來解決租戶。 然后,我將解析的租戶ID放在與調用一起發送給管理器的上下文值中。 在管理器的不同方法中,我從上下文值中獲取租戶ID。 然后將其與每個SQL查詢/ exec調用一起使用,如果缺少或無效的租戶ID,則返回錯誤。 我是否應該為此使用上下文?

  4. 解決gRPC服務器上的租戶,我相信我必須使用UnaryInterceptor函數進行中間件處理。 由於gRPC API接口只能由其他后端服務訪問,因此我認為此處不需要按子域進行解析。 但是我應該如何嵌入租戶ID? 在標題中?

真的希望我問正確的問題。 問候,卡爾。

我找不到任何支持多個租戶的ORM for Go。 在sqlx包之上編寫自己的代碼是否有效?

Go中的ORM是一個有爭議的話題! 一些Go用戶喜歡它們,另一些討厭它們,並且喜歡手動編寫SQL。 這是個人喜好問題。 詢問特定的庫建議在這里是sqlx ,無論如何,我不知道任何多租戶ORM庫-但是沒有什么可以阻止您使用sqlx包裝器的(我每天在一個工作正常的系統上工作這個)。

將來的其他服務也將需要多租戶支持,因此我想無論如何我都必須創建一些庫/包。

以適合您的編程和接口模式的方式從那些內部服務中抽象出這種行為是有意義的,但是這里沒有更多細節可以更具體地回答。

今天,我通過為公共API服務器使用ResolveTenantBySubdomain中間件來解決租戶。 然后,我將解析的租戶ID放在與調用一起發送給管理器的上下文值中。 在管理器的不同方法中,我從上下文值中獲取租戶ID。 然后將其與每個SQL查詢/ exec調用一起使用,如果缺少或無效的租戶ID,則返回錯誤。 我是否應該為此使用上下文?

context.Context主要是關於取消,而不是請求傳播。 根據WithValue函數的文檔 ,盡管您的使用是可以接受的,但使用當前實現為傳遞值的context包,它被廣泛 認為是一種不好的代碼味道。 與其使用缺乏類型安全性和許多其他屬性的隱式行為,不如通過將租戶ID傳遞給相關的函數調用來在下游數據層的函數簽名中顯式顯示?

解決gRPC服務器上的租戶,我相信我必須使用UnaryInterceptor函數進行中間件處理。 由於gRPC API接口只能由其他后端服務訪問,因此我認為此處不需要按子域進行解析。 但是我應該如何嵌入租戶ID? 在標題中? [原文如此]

gRPC庫沒有考慮您的設計選擇。 您可以使用標頭值(將租戶ID作為“環境”參數傳遞給請求),也可以將租戶ID參數顯式添加到需要它的每個遠程方法調用中。

請注意,以這種方式在服務之間傳遞租戶ID會在它們之間建立外部信任 -如果服務A提出服務B的請求並用租戶ID對其進行注釋,則您假定服務A已執行了必要的訪問控制檢查以驗證用戶該租戶確實在提出請求。 在此簡單模型中,沒有什么可以阻止流氓服務C向服務B詢問有關某些任意租戶ID的信息。 另一種實現方式是實施更復雜的無人信任策略,從而為每個服務提供足夠的訪問控制信息,以就是否應滿足針對特定租戶的特定請求做出自己的策略決策。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM