本文章是由機器翻譯。

Windows Azure 內行人

構建多租戶應用程式在 Windows Azure

Bruno Terkaly
Ricardo Villalobos

下載代碼示例

那裡是一個龐大而充滿活力的生態系統的服務提供程式打包解決方案和承載它們在雲平臺上。一般來說,這些軟體作為服務 (SaaS) 公司使用多租戶的體系結構。你可以找到很多實際的例子在 bit.ly/vIPcyc。如果你想想它,如 Facebook 或 Hotmail,在 Web 上流行的應用程式的大部分是多租戶應用程式。這種方法使得從商業角度來說,因為可以通過多個訂閱伺服器之間共用它們最大化計算和存儲資源。所有的要點之一雲計算後是通過分享大量的計算和存儲資源,最大限度地提高效率。

我們得到的頻繁問題有關的最佳做法和實施使用 Windows Azure 的多租戶架構的模式。這是兩列,將向您介紹一些關鍵概念和原則,以及提供一些指導,你可以開始加快對一些核心構建基塊的實際操作技能的第一。

多租戶軟體的概念很簡單。它是一個單一的、 綜合性的系統,支援多個用戶端組織 (住戶),在每個租客運行安全地並行在相同的硬體和軟體,完全不知道有其他人。處理得當,它允許服務提供者在實現極為高效利用 Windows Azure 的同時向租戶提供大量的功能。租戶的重點安全、 低成本和良好的性能。

雲建築師必須仔細考慮一些關鍵的支柱,構建多租戶系統時:

  • 標識與安全
  • 資料隔離和隔離
  • 計量和性能分析
  • 同時維護 Sla 向上和向下縮放

我們將討論前兩個在這裡和我們的下一列中的後兩個。

識別

身份扮演多租戶的體系結構中的核心作用。對於初學者,租客必須保證其私有資料不能訪問其他使用者的目標是要在訂閱伺服器之間共用的情況除外。Microsoft SharePoint 提供一個示例。您可能有僅對特定的租客,可見的文檔,但你也可能會有一些共用的工作組 (兩個或更多租戶可以跨組織)。底線 — — 身份中央方面起作用的資料可見度。

在今天的世界中,身份管理系統必須是可交互操作,秉承開放標準 (如由本組織的結構化資訊標準提高地位或綠洲維護)、 WS 信任和 WS-安全等。在一起,這些標準允許多租戶系統評估的存在和經紀人相互之間的關係的房客和服務提供者的安全郵件交換中的信任。此外,多租戶的體系結構通常支援多個身份提供程式,如谷歌、 Facebook、 雅虎和微軟活。在更複雜的情況下,服務提供者將支援公司的標識,如活動目錄。對 Web 單一登入 (SSO) 的支援也是重要的。

基於聲明的身份管理

它被普遍接受基於索賠的標識管理辦法提供最大的價值。首先,基於索賠的方法將身份的不同部分集中到單個抽象標記組成的索賠和開證人或權力機構。這種辦法的價值是他們基於開放標準,高度互通性。基於聲明的身份管理允許服務提供者來解耦從巨大的、 低級的水暖代碼的標識管理的應用程式。不支援 Web 服務標準 (WS-信任,WS-聯邦、 WS-安全),權杖格式 (安全斷言標記語言 [SAML]、 JSON Web 鍵 [JWK],簡單 Web 權杖 [SWT]) 和加密 (X.509) 是微不足道。畢竟,這些標準始終不斷,所以封裝並提取身份管理是至關重要的。

所有這些挑戰的答案是 Windows Azure 活動目錄的存取控制服務 (ACS),從而從根本上簡化了實現基於聲明的身份管理系統。ACS 中移除此低級的水暖和因素放在服務提供程式的代碼,使其相對容易實現基於聲明的身份管理系統。使 ACS 如此強大的是很多工作可以通過基於 Web 的門戶。ACS,可大大簡化新租戶的資源調配。

這意味著你開發人員,不需要處理很多複雜的應用程式內的標識管理。ACS 解決了困難,時間密集的問題,如:

  • 如何將未經身份驗證的請求重定向到空房的標識提供程式
  • 如何驗證傳入權杖頒發的身份標識提供程式
  • 如何分析 (閱讀索賠) 的傳入權杖
  • 如何執行授權檢查
  • 如何將標記轉換通過添加、 刪除或更改的索賠類型和值

我們建議您通過幾個基於 Web 的教程,可以開始運行。你會發現一個好上進行身份驗證的使用者 bit.ly/uyDLkt。如果你運行Visual Studio2012 年,維托裡奧 Bertocci 四部分哨所 bit.ly/12ZOwN9 將提供所需要的指導。Visual Studio內的模具繼續改善,讓開發人員不必手動編輯設定檔。您可以下載工裝和從 Sdk bit.ly/NN9NVE。

圖 1描述了多個身份提供程式支援與租客的經驗。

圖 1 支援多個身份提供程式

圖 2 表示真正發生的事情當你利用 ACS。租客是完全不知道,ACS 做幕後的所有工作。你看到在該工作流圖 2 以獲取安全權杖,通常在 SAML 2.0 格式的多租戶應用程式結束。真正的美是已標準化多租戶應用程式接收的權杖,無論所選擇的租客的身份標識提供程式。ACS 透明地經紀人向您指定在 ACS 門戶權杖格式轉化的身份標識提供程式特定的標記格式。


圖 2 高級視圖的存取控制服務門戶

有的 JavaScript,查詢為標識提供程式清單中您想讓您的應用程式支援,ACS 然後為每個標識提供程式生成的登錄連結。由系統處理所有必要的重定向都要獲取到您的應用程式的標準安全標記。"依賴方"是只需你多租戶應用程式中,因為多租戶應用程式依賴于發行人提供有關身份資訊。

如果你通過前面提到的教程,您將看到中顯示的螢幕圖 3。ACS 門戶的入門部分分為四個部分,簡化了將身份管理集成到一個基於雲計算、 多租戶應用程式的過程。節 1 允許您從清單中選擇您想要支援的身份提供程式。此預排,我們會選擇谷歌、 微軟的 Live ID 和 yahoo!作為標識提供程式。與一個小的額外工作,您還可以包括 Facebook 和 Active Directory 身份。節 2 是捆綁發生。它是您將在其中指定的 ACS 返回的安全權杖,通常應用程式的起始頁的 URL。畢竟,ACS 需要終結點,以傳遞到權杖所需的格式。第 2 節中您還可以指定所需的標記格式。


圖 3 Windows Azure ACS 門戶

第 2 節是在其中選擇索賠您想要包括安全權杖中的身份提供程式。依賴方 (服務提供者的多租戶應用程式) 將使用這些索賠都唯一地標識租客和作出授權決定,定義在服務範圍內的租客的特權。現有的索賠因身份標識提供程式 ; 而異 與谷歌不同 Windows Live,例如。與谷歌和雅虎,權杖中的索賠可以包括電子郵件地址、 使用者名稱、 nameidentifier 和提供程式名稱。對於微軟的 Live ID,不過,你只有 nameidentifier 和提供程式名稱,而不是電子郵件或使用者的名稱。你會需要處理那些在應用程式中的微妙之處。

節 4 允許您將一些中繼資料和代碼集成到該服務。這在Visual Studio內完成模具。您需要裡面的應用程式佈建檔,將綁定到 ACS 應用中繼資料。在Visual Studio2012年模具使這一步操作一個指向和點擊的經驗,而Visual Studio2010 你會需要手動編輯 web.config 的 sytem.web 部分。

微軟最近發佈了 Windows Azure Active Directory,允許您利用 Web SSO 與您的業務線 (LOB) 應用程式,對樓宇和在雲計算中。如果您的目標是要在 LOB 應用程式中實現身份管理,在應用程式運行這兩個處所和在雲計算,你就會想要閱讀的資訊在 bit.ly/157yVPR。本文檔說明了如何利用現有的 LOB 應用程式來使它可供其他 Windows Azure Active Directory 租客管理員在其組織中使用 Windows Azure 活動目錄。

Bertocci 博客張貼 (前面提到的) 將您帶到在螢幕圖 4,其中顯示了身份和訪問可用於在多租戶應用程式中添加配置代碼。Visual Studio2012年完全消除了,需要手動編輯任何設定檔。正如你所看到的我們選擇三個身份提供程式和定義領土和多租戶應用程式返回的 URL。領土是只是一個 URI,標識應用程式使用者登錄到。此 URI 還允許您將應用程式和答覆位址的索賠相關聯。你就會改變領土和返回 URL,一旦您部署到 Microsoft 資料中心的應用程式。最後,您將添加一個管理金鑰,你從 ACS 門戶到數位記號標記為安全目的。


圖 4Visual Studio2012年身份和訪問對話方塊

將代碼添加到應用程式

多租戶應用程式需要保存到永久存儲的已登錄的使用者。這是最初所需的資源調配的過程,但也可能是必要的如果租客活動進行跟蹤。在這篇文章中使用的資料存儲區是 Windows Azure 的 SQL 資料庫,但您可以輕鬆地更改此到 Windows Azure 表,可能還包括房地上的資料存儲。在 Page_Load 方法中的 Default.aspx.cs 檔,我們可以輕鬆地閱讀的安全權杖和解析索賠中,如下所示:

protected void Page_Load(object sender, EventArgs e)
{
  // Grab the ClaimsIdentity object.
Think of it as a token
  // and set of claims for the currently logged in user.
ClaimsIdentity ci =
    Thread.CurrentPrincipal.Identity as ClaimsIdentity;
  // Create a TenantTokenManager object that parses the claims.
TenantTokenManager tenantTokenManager = new TenantTokenManager(ci);
  // Save logged in user to persistent storage.
tenantTokenManager.SaveTenantToDatabase();
}

將此邏輯封裝,我們會向我們的雲專案,所示來添加一個 TenantTokenManager 類圖 5

圖 5 TenantTokenManager 類

public class TenantTokenManager
{
  // Claims that uniquely identify tenants.
public System.Security.Claims.ClaimsIdentity SecurityToken { get; set; }
  public string IdentityProviderName                         { get; set; }
  public string IdentityProviderNameIdentifier               { get; set; }
  public string IdentityProviderEmail                        { get; set; }
  public string TenantId                                     { get; set; }
  public string TenantName                                   { get; set; }
  public TenantTokenManager(System.Security.Claims.ClaimsIdentity ci)
  {
    try
    {
      // Save a copy of the ClaimsIdentity security token.
this.SecurityToken = ci;
      // Extract the provider name (Yahoo, Google, Microsoft Live).
IdentityProviderName = (from c in ci.Claims
        where c.Type ==
        "http://schemas.microsoft.com/accesscontrolservice/
        2010/07/claims/identityprovider"
        select c.Value).SingleOrDefault();
      // Extract the nameidentifier (a unique identifier of
      // a tenant from the identity provider).
IdentityProviderNameIdentifier = (from c in ci.Claims
        where c.Type ==
          "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"
        select c.Value).SingleOrDefault();
      // Extract the emailaddress (not available in Microsoft Live ID).
IdentityProviderEmail = (from c in ci.Claims
        where c.Type ==
          "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
        select c.Value).SingleOrDefault();
      // Create a unique TenantId based on nameidentifier
      // and provider name.
TenantId =
        IdentityProviderName + "-" + IdentityProviderNameIdentifier;
      // Extract name from security token (not available
      // from Microsoft Live ID).
TenantName = SecurityToken.Name == 
        null ? "
Not Avail." : SecurityToken.Name;
    } catch (Exception ex) { throw ex; }
  }
  public void SaveTenantToDatabase() {
   IdentityDataStore.SaveTenantToDatabase(this); 
  }
}

TenantTokenManager 類封裝了兩項重要職能。 第一,它所分析的安全權杖從索賠。 在我們的例子,該權杖的格式是 SAML,但它可能只是簡單地智威湯遜或 SWT。 注意可以使用簡單的LINQ查詢來提取個人索賠從權杖。 並注意代碼中,對於微軟 Live ID,你不能得到任何名稱或電子郵件的資料。 在這種情況下,空值將返回從LINQ查詢。 代碼中的注釋解釋索賠的意思。 我們也加入了 TenantTokenManager 使用 SaveToDatabase 方法,以便可以調配並跟蹤租戶對節能的支援。

在應用程式中的下一個邏輯步驟是做出授權決定基於身份或身份的角色成員資格。 例如,如圖所示,在圖 6,該存儲的過程只返回基於 TenantId 的記錄。 這說明了如何你可能開始思考的資料隔離和隔離。

圖 6 預存程序返回基於 TenantId 的記錄

CREATE PROCEDURE [dbo].[GetTenantData]
  @TenantId nvarchar(max)
AS
BEGIN
  SELECT
    [id],
    [TenantId],
    [TenantName],
    [ProviderName],
    [NameIdentifier],
    [Email],
    [SomeTenantData1],
    [SomeTenantData2]
  FROM TenantRecords
  WHERE TenantId = @TenantId
  return;
END

資料隔離和隔離

當它來到的身份結合資料在多租戶系統中時,有一些重大問題要解決。 第一,建築師必須想出如何保持完全孤立的其他租戶的敏感性資料。 很明顯,你不能讓事情-信用卡號碼、 社會安全號碼,電子郵件等等,將以任何方式洩露。 每個租客必須絕對保證是其資料保持窺探。 與此同時,可能還需要資料中的租客,如共用日曆、 照片或簡單文本消息的共用。 另一個需要解決的問題是資源調配的審核跟蹤,藉以服務提供者可以跟蹤租戶的用法和登錄模式。 這允許組織跟蹤由管理員級別的使用者,説明解決意外的應用程式行為所做的更改。

在任何多租戶系統中,有更多的技術挑戰,使要使成本效益最大化同時為租戶提供性能良好、 靈活的資料服務和資料模型的服務提供程式。 這一挑戰尤其是由於很難純粹各種資料類型。 考慮單獨的 Windows Azure 支援大量的存儲選項,如表、 斑點、 佇列、 SQL 資料庫、 Hadoop 和更多。 為服務提供者面臨的技術挑戰是重要的因為是非常不同的每種存儲類型。 建築師需要平衡成本、 性能、 可伸縮性以及最終的租戶對資料的需求。

讓我們看的四個常見的 Windows Azure 存儲類型快速看。 Blob 用來存儲非結構化的文本和二進位資料。 通常,blob 是圖像、 音訊或其它多媒體物件,儘管作為一個 blob 存儲有時二進位可執行代碼。 佇列用於存儲消息可能被訪問的租客。 他們提供的縮放實例多租戶應用程式的可靠消息。 表提供了 NoSQL 功能需要存儲大量的非結構化資料的應用程式。 最後,SQL 資料庫提供一個功能全面的關係資料庫作為一種服務 (DBaaS) 的應用程式需要這個。

Blob 這些是比較容易理解 Windows Azure 表或 SQL 資料庫。 你可以閱讀更多有關在 blob bit.ly/VGHszH。 Windows Azure 帳戶可以有許多的 blob 容器。 Blob 的容器可以有許多的 blob。 大多數服務提供者將有多個帳戶。 所採取的典型方法是指定每個租客的容器名稱。 這使您能夠定義的存取權限、 衡量績效和量化的 blob 服務消費。 最近,微軟已修訂其網路拓撲結構,大大提高了計算和存儲資源,支援高達 10Gbps 的存儲節點網路速度之間的頻寬。 更多關於這在 bit.ly/PrxhAW

命名約定為 blob 可能會強制您保持容器名稱到 TenantIds 的地圖。 您可以使用電子郵件地址,因為他們是唯一的但 Windows Live ID 並不提供這種說法在範圍內的安全權杖。 對於谷歌和雅虎,您需要刪除"@"符號和"."因為 blob 容器只能包含字母、 數位和破折號。

中的代碼圖 7 演示了資源調配 blob 容器的方法。 此代碼可能是租客的註冊和資源調配過程的一部分。 請注意 TenantId 作為容器名稱。 在真實世界的情況下,當然,可能有某種類型的查閱資料表,提供基於 TenantIds 的容器名稱。 在代碼中的圖 7,服務提供者選擇了一個單獨的 Windows Azure 帳戶 (AccountTenantImages) 來存儲圖像的租戶。 請注意,代碼"blobClient.GetContainerReference(tm.TenantId),"這就是為新租客置備一個 blob 容器是哪裡。

圖 7 為租客調配資源 Blob 的容器

// Grab the ClaimsIdentity object.
Think of it as a token
// and set of claims for the currently logged in user.
ClaimsIdentity ci =
  Thread.CurrentPrincipal.Identity as ClaimsIdentity;
// Parse the claim.
TokenManager tm = new TokenManager(ci);
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
  Microsoft.WindowsAzure.CloudConfigurationManager.GetSetting(
  "AccountTenantImages"));
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve a reference to a container.
CloudBlobContainer container = blobClient.GetContainerReference(tm.TenantId);
// Create the container if it doesn't already exist.
container.CreateIfNotExists();

另一個重要的一點是 blob 支援使用者定義的中繼資料,這意味著每個 blob 可以支援一個或多個名稱 / 值對。 然而,blob 存儲不允許您查詢全球範圍內對其中繼資料的 blob。 在中繼資料中查找資訊,你有兩個選項。 第一次是從一個 blob 容器獲取所有 blob 和他們,然後枚舉搜索的名稱-值對。 可擴充性更強的方法是在表存儲,和 blob URL 中存儲的中繼資料。 這種方法允許您查詢表存儲,以查找所需的 blob,然後從存儲中檢索 blob 和查詢直接從單個 blob 的中繼資料。

佇列因為佇列通常用作機制提供可靠、 非同步消息傳遞多租戶應用程式內,住戶一般從他們絕緣。 說到這,帳戶有許多佇列和佇列有很多消息。 可以想像,雲建築師可以為每個租戶提供單獨的佇列。 但這一決定將基於多租戶應用程式的特定需要。 請記住,這種做法不可能很好地擴展和可能變得難以管理作為租戶數目上升超出 100。

有很多的資料隔離和隔離選項在 Windows Azure 表內可用。 例如,服務提供者可以提供一個存儲帳戶每租客。 因為每個存儲帳戶顯示為在 Windows Azure 帳單上的行專案,這種方法可以是很有用的如果你想要識別每租客的確切費用。 另一個選項是結合在一個單一的存儲帳戶中的多個租戶。 這種方法使您能夠組租戶由地理區域、 監管要求和潛在的複製的要求。 但是,您仍然需要這樣一個帳戶內的租戶不會對其他租戶的資料訪問層中的分區方案 — — 除非,當然,需要資料共用的戰略。 承載多個租戶在單一帳戶的一種辦法是,表名稱中包括 TenantId 和給自己的表的副本的每個租客。

然而,另一種方法是把多個租戶在單個表中,在這種情況下您可能需要使用表內置分區鍵和從另一個單獨的行鍵來保持租戶的資料。 它是常見的是使用 TenantId 作為分區鍵,因為它擴展也同時提供了極好的查詢的性能。

中的代碼圖 8 演示如何多個租戶可以共用單個表。 代碼闡釋了如何租客可能檢索使用 Windows Azure 表的電子郵件地址和電話號碼。 請注意 PartionKey 基本上是 TenantId,可以從登錄憑據,或直接或通過另一個查閱資料表。

圖 8 分離資料在 Windows Azure 表使用 PartionKey 和 RowKey

// Grab the ClaimsIdentity object.
Think of it as a token
// and set of claims for the currently logged in user.
ClaimsIdentity ci =
  Thread.CurrentPrincipal.Identity as ClaimsIdentity;
// Parse the claim.
TokenManager tm = new TokenManager(ci);
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
  Microsoft.WindowsAzure.CloudConfigurationManager.GetSetting(
  "AccountTenantTables"));
// Create a cloud table client object.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
// Create an email address table object.
CloudTable emailAddressTable =
  tableClient.GetTableReference("EmailAddressTable");
// Set up the filter for the partition key.
string pkFilter = TableQuery.GenerateFilterCondition("PartitionKey",
  QueryComparisons.Equal, tm.TenantId);
// Set up the filter for the row key.
string rkFilter = TableQuery.GenerateFilterCondition("RowKey", 
  QueryComparisons.Equal, tm.IdentityProviderName);
// Combine the partition key filter and the Row Key filter.
string combinedFilter = TableQuery.CombineFilters(rkFilter,
  TableOperators.And, pkFilter);
// Construct a query.
TableQuery<EmailAddressEntity> query =
  new TableQuery<EmailAddressEntity>().Where(combinedFilter);
// Execute the query.
EmailAddressEntity emailAddressEntity =
  emailAddressTable.ExecuteQuery(query).First();
// Pull the data out that you searched for;
// do something with emailAddress and phoneNumber.
string emailAddress = emailAddressEntity.EMailAddress;
string phoneNumber = emailAddressEntity.PhoneNumber;

總結

構建多租戶應用程式需要對身份和資料的分離和隔離問題很好理解。服務提供者可以使自己免受不必寫了大量的與管理有關的身份通過利用的 ACS 的低級水暖代碼。多租戶應用程式可以支援多種身份提供程式,並避免其代碼庫的困惑與一些這裡提供的技術。此外,強健的身份管理,簡化了隔離或共用租客資料所需的工作。

在下個月的專欄中,我們會處理的多租戶架構的其他關鍵支柱 — — 計量和業績分析和縮放。同時,我們建議更多的資訊感興趣的讀者閱讀"發展中國家多租戶雲計算,第 3 版,應用"可在 bit.ly/asHI9I

Bruno Terkaly 是微軟開發者福音傳教士。他淵博的知識是來自在該領域使用眾多平台、語言、架構、SDK、程式庫和 API 撰寫程式碼的多年經驗。他花時間編寫代碼,寫博客,給現場演示上構建基於雲計算的應用程式,具體地使用 Windows Azure 平臺。他出版了兩個應用程式對 Windows 存儲區:教孩子音樂和孩子們的車的顏色。您可以閱讀他的博客在 blogs.msdn.com/b/brunoterkaly

Ricardo Villalobos 是經驗豐富的軟體架構設計師,在為供應鏈管理產業的公司設計和建立應用程式擁有 15 以上的經驗。他從達拉斯大學工商管理持有不同的技術認證,以及碩士學位,為微軟工作作為一個雲建築師在 Windows Azure CSV 孵化組。您可以閱讀他的博客在 blog.ricardovillalobos.com

Terkaly 和比利亞洛沃斯共同提出大行業會議 ; 可用性,電子郵件在他們 bterkaly@microsoft.comRicardo.Villalobos@microsoft.com.

衷心感謝以下技術專家對本文的審閱:派翠克 · 巴特勒 Monterde (Microsoft) 和 · 布尚 · 內內 (Microsoft)
派翠克是在微軟的雲建築師。在他當前的角色,他是負責開發雲戰略和 Microsoft 服務的雲 IP。之前這一作用,派翠克 · 工作作為全球範圍內的 Windows Azure 技術銷售他在那裡負責全球企業客戶能夠順利通過 Windows Azure 平臺提供支援。派翠克還擔任在 MCS 專門從事企業應用程式開發中的高級顧問。
在加入之前微軟,派翠克 · 舉行若干職位從開發、 管理、 軟體體系結構。他帶來了十二年的企業管理諮詢經驗橫跨多個行業,包括 ; 軍事、 衛生保健、 石油和天然氣、 政府和法律。他主要從事 Windows Azure 平臺,SQL Azure、.NET 開發、Microsoft SQL Server和專案管理。派翠克 · 持有學士學位在電腦科學從常青州立學院和多發性硬化症在從Phoenix大學的電腦資訊系統。讀派翠克的最新進展在:HTTP://blogs.msdn.com/b/patrick_butler_monterde/  

· 布尚 · 內內帶領雲建築師團隊在 Microsoft 可以説明戰略 ISV 合作夥伴開發 Windows Azure 上的應用程式。· 布尚 · 已發表的技術文章數、 引用的應用程式,和合著一本的書。他還提出了在雲事件的數目。