Поддержание сходства между группой подписок и сервером почтовых ящиков в ExchangeMaintain affinity between a group of subscriptions and the Mailbox server in Exchange

Сведения о поддержке сходства между группой подписок и сервером почтовых ящиков.Find out about maintaining the affinity between a group of subscriptions and the Mailbox server.

Сходство это ассоциация последовательности запросов и ответных сообщений с определенным сервером почтовых ящиков.Affinity is the association of a sequence of request and response messages with a particular Mailbox server. Для большинства функциональных возможностей Exchange сервер обрабатывает сходство.For most functionality in Exchange, affinity is handled by the server. Однако уведомления являются исключением.Notifications, however, are an exception. Клиент отвечает за поддержание сходства с сервером почтовых ящиков для подписок на уведомления.The client is responsible for maintaining the affinity with the Mailbox server for notification subscriptions. Это сходство позволяет серверам подсистемы балансировки нагрузки и клиентского доступа между клиентом и сервером маршрутизировать подписки на уведомления и связанные запросы на сервер почтовых ящиков, который обслуживает подписку.This affinity enables the load balancer and Client Access servers between the client and the server to route notification subscriptions and related requests to the Mailbox server that maintains the subscription. Без сходства запрос может направляться на другой сервер почтовых ящиков, который не включает подписки клиента, что может привести к возвращению ошибки еррорсубскриптионнотфаунд .Without affinity, the request might get routed to a different Mailbox server that does not include the client's subscriptions, which can cause an ErrorSubscriptionNotFound error to be returned.

Как поддерживается сходство?How is affinity maintained?

Сходство в Exchange — на основе файлов cookie.Affinity in Exchange is cookie based. Клиент запускает создание файла cookie, включая определенные заголовки в запросе на подписку, а затем ответ на подписку содержит файл cookie.The client triggers the creation of the cookie by including specific headers in the subscription request, and then the subscription response contains the cookie. Затем клиент отправляет этот файл cookie в последующих запросах, чтобы убедиться, что запрос перенаправляется на подходящий сервер почтовых ящиков.The client then sends that cookie in subsequent requests to ensure that the request is routed to the right Mailbox server.

Точнее, сходство в Exchange обрабатывается следующим образом:More specifically, affinity in Exchange is handled by the following:

  • X-AnchorMailbox — HTTP-заголовок, включенный в начальный запрос на подписку.X-AnchorMailbox — An HTTP header that is included in the initial subscription request. Он определяет первый почтовый ящик в группе почтовых ящиков, которые совместно используют сходство с одним и тем же сервером почтовых ящиков.It identifies the first mailbox in a group of mailboxes that share affinity with the same Mailbox server.

  • X-Преферсервераффинити — HTTP-заголовок, который включается в начальный запрос подписки с помощью заголовка X-AnchorMailbox и имеет значение true, чтобы указать, что клиент запрашивает сопоставление соответствия с сервером почтовых ящиков.X-PreferServerAffinity — An HTTP header that is included in the initial subscription request with the X-AnchorMailbox header and is set to true to indicate that the client is requesting that affinity be maintained with the Mailbox server.

  • X-Баккендоверридекукие — файл cookie, который включен в первоначальный ответ подписки и содержит файл cookie, используемый сервером балансировки нагрузки и сервером клиентского доступа для маршрутизации последующих запросов на один сервер почтовых ящиков.X-BackEndOverrideCookie — A cookie that is included in the initial subscription response and contains a cookie that the load balancer and Client Access server use to route subsequent requests to the same Mailbox server.

Как сохранить сходство с помощью управляемого API EWS или EWS?How do I maintain affinity by using the EWS Managed API or EWS?

Вы можете использовать одни и те же действия для сохранения сходства для нескольких подписок почтовых ящиков и их серверов почтовых ящиков независимо от того, используете ли вы уведомления о потоках, опрашивающей или Push-связи, независимо от того, используете ли вы локальный сервер Exchange или Exchange Online.You can use the same steps to maintain affinity for multiple mailbox subscriptions and their Mailbox servers, regardless of whether you are using streaming, pull, or push notifications, and regardless of whether you're targeting an Exchange on-premises server or Exchange Online.

  1. Для каждого почтового ящика вызовите службу автообнаружения и получите параметры Граупингинформатион и екстерналевсурл пользователя.For each mailbox, call Autodiscover and get the GroupingInformation and ExternalEwsUrl user settings. Для автообнаружения SOAP вы используете элемент Setting , а для службы автообнаружения POX — элемент граупингинформатион .For SOAP Autodiscover, you use the Setting element, and for POX Autodiscover, you use the GroupingInformation element.

  2. С помощью параметров Граупингинформатион и Екстерналевсурл из откликов автообнаружения помещайте почтовые ящики с одинаковым значением Екстерналевсурл и Граупингинформатион сцепления в одну группу.Using the GroupingInformation and ExternalEwsUrl settings from the Autodiscover responses, place mailboxes with the same ExternalEwsUrl and GroupingInformation concatenated value in the same group. Если в одной из групп больше 200 почтовых ящиков, разделите их, чтобы в каждой группе было не более 200 почтовых ящиков.If any groups have more than 200 mailboxes, break the groups down further so that each group has no more than 200 mailboxes.

  3. Создайте и используйте один объект ExchangeService для оставшейся части процедуры.Create and use one ExchangeService object for the rest of the procedure. При использовании одного и того же объекта ExchangeService файлы cookie и заголовки (при их задании) автоматически сохраняются.When you use the same ExchangeService object, cookies and headers (when they are set) are automatically maintained. Обратите внимание, что если вы не планируете группировать почтовые подписки в единое подключение, вы можете создать отдельный объект ExchangeService для каждого олицетворенного пользователя.Note that if you do not intend to group streaming subscriptions into a single connection, you are free to create a different ExchangeService object for each impersonated user.

  4. Отправьте запрос на подписку для пользователя, имя которого отображается в алфавитном порядке, когда все пользователи в группе сортируются в алфавитном порядке (этот пользователь будет называться пользователь почтовых ящиков привязки).Send a subscription request for the user whose user name appears first when all users in the group are sorted alphabetically (we'll refer to this user as the anchor mailbox user). Выполните указанные ниже действия.Do the following:

  • Включите заголовок X-AnchorMailbox со значением, равным SMTP-адресу пользователя закрепленного почтового ящика.Include the X-AnchorMailbox header with a value set to the SMTP address of the anchor mailbox user.

  • Включите заголовок X – Преферсервераффинити со значением true.Include the X-PreferServerAffinity header with a value set to true.

  • Используйте роль ApplicationImpersonation (тип ексчанжеимперсонатион ).Use the ApplicationImpersonation role (the ExchangeImpersonation type).

  1. В ответе на подписку получите значение X – Баккендоверридекукие.In the subscription response, get the X-BackEndOverrideCookie value. Включите это значение в каждую из последующих запросов подписки для пользователей в этой группе.Include this value in each of the subsequent subscription requests for users in this group.

  2. Для каждого дополнительного пользователя в группе отправьте запрос на подписку и выполните следующие действия:For each additional user in the group, send a subscription request and do the following:

  • Включите заголовок X-AnchorMailbox со значением, равным SMTP-адресу пользователя закрепленного почтового ящика пользователя для группы.Include the X-AnchorMailbox header with a value set to the SMTP address of the anchor mailbox user for the group.

  • Включите заголовок X – Преферсервераффинити со значением true.Include the X-PreferServerAffinity header with a value set to true.

  • Включите X – Баккендоверридекукие, возвращенный в ответе на подписку пользователя привязанного почтового ящика.Include the X-BackEndOverrideCookie that was returned in the anchor mailbox user's subscription response.

  • Используйте роль ApplicationImpersonation (тип ексчанжеимперсонатион ).Use the ApplicationImpersonation role (the ExchangeImpersonation type).

    Обратите внимание, что сервер использует значения X – Преферсервераффинити и X Баккендоверридекукие для выполнения маршрутизации на сервер почтовых ящиков.Note that the server uses the X-PreferServerAffinity and X-BackendOverrideCookie values together to perform the routing to the mailbox server. Заголовок X-AnchorMailbox также необходим, но он игнорируется сервером, если остальные два значения являются допустимыми.The X-AnchorMailbox header is also required, but is ignored by the server if the other two values are valid. Если X-AnchorMailbox и X-Преферсервераффинити находятся в запросе, а X-Баккендоверридекукие не включено, то для маршрутизации запросов используется значение X-AnchorMailbox.If X-AnchorMailbox and X-PreferServerAffinity are in a request and X-BackendOverrideCookie is not included, the X-AnchorMailbox value is used to route the requests.

    Так как значения X-Преферсервераффинити и X-Баккендоверридекукие выполняют маршрутизацию, если почтовый ящик привязки когда-либо перемещается в другую группу или на другой сервер, то логика не изменяется, так как X-Баккендоверридекукие направляет запрос на правильный сервер для группы.Because the X-PreferServerAffinity and X-BackendOverrideCookie values perform the routing, if the anchor mailbox ever moves to another group or server, the logic does not change because the X-BackendOverrideCookie will route the request to the correct server for the group.

  1. Отправьте отдельные запросы GetStreamingEvents или Events для группы и выполните следующие действия:Send a single GetStreamingEvents or GetEvents requests for the group, and do the following:
  • Включите значения SubscriptionId , возвращенные в каждом из ответов на отдельные подписки для почтовых ящиков в группе.Include the SubscriptionId values returned in each of the individual subscription responses for mailboxes in the group.

  • Если для группы существует более 200 подписок, создайте несколько запросов.If more than 200 subscriptions exist for the group, create multiple requests. Максимальное число значений SubscriptionId , включаемых в запрос: 200.The maximum number of SubscriptionId values to include in a request is 200.

  • Если требуется больше подключений, чем доступно для целевого почтового ящика, используйте учетную запись службы для олицетворения почтового ящика привязки для группы; в противном случае не используйте олицетворение.If you need more connections than are available to the target mailbox, use the service account to impersonate the anchor mailbox for the group; otherwise, do not use impersonation. В идеале необходимо олицетворять уникальный почтовый ящик на запрос GetStreamingEvents или Events , чтобы никогда не применялись ограничения на регулирование.Ideally, you want to impersonate a unique mailbox per GetStreamingEvents or GetEvents request so that you never encounter throttling limits.

  • Используйте ApplicationImpersonation, если вам требуется больше подключений, чем доступно для целевого почтового ящика; в противном случае не используйте ApplicationImpersonation.Use ApplicationImpersonation if you need more connections than are available to the target mailbox; otherwise, do not use ApplicationImpersonation.

  • Включите заголовок X – Преферсервераффинити и задайте для него значение true.Include the X-PreferServerAffinity header and set it to true. Это значение автоматически включается при использовании объекта ExchangeService , созданного на шаге 2.This value is automatically included if you are using the ExchangeService object that you created in step 2.

  • Включите X-Баккендоверридекукие для группы (X-Баккендоверридекукие, которая была возвращена в ответе на подписку пользователя привязанного почтового ящика).Include the X-BackEndOverrideCookie for the group (the X-BackEndOverrideCookie that was returned in the anchor mailbox user's subscription response). Это значение автоматически включается при использовании объекта ExchangeService , созданного на шаге 2.This value is automatically included if you are using the ExchangeService object that you created in step 2.

  1. Передайте возвращенные события в отдельный поток для обработки.Pass the returned events to a separate thread for processing.

Какие значения регулирования необходимо учитывать?What throttling values do I need to take into consideration?

При планировании реализации уведомлений необходимо учитывать два значения: количество подключений и число подписок.As you plan your notification implementation, you'll want to take two values into consideration: the number of connections, and the number of subscriptions. В следующей таблице приведены значения по умолчанию для каждого параметра регулирования и способов использования этих параметров.The following table lists the default values for each throttling setting and how the settings are used. Для каждого значения бюджет размещается в целевом почтовом ящике.For each value, the budget is allocated to the target mailbox. По этой причине использование олицетворения для получения дополнительных подключений является обязательным шагом во многих сценариях.For this reason, using impersonation to gain additional connections is a required step in many scenarios.

Таблица 1. Значения регулирования по умолчаниюTable 1. Default throttling values

Область рассмотренияArea of consideration Параметр регулированияThrottling setting Значение по умолчаниюDefault value ОписаниеDescription
Потоковое подключениеStreaming connections
Предельное число подключений по умолчаниюDefault hanging connection limit
10 для Exchange Online10 for Exchange Online
3 для Exchange 20133 for Exchange 2013
Максимальное число одновременных потоков подключений, которые могут быть открыты учетной записью на сервере в один момент времени.The maximum number of concurrent streaming connections that an account can have open on the server at one time. Для работы с этим пределом используйте учетную запись службы с ролью ApplicationImpersonation, назначенной для целевых почтовых ящиков, и олицетворяет первого пользователя в каждой группе ИДЕНТИФИКАТОРов подписки, когда вы получаете потоковые события.To work within this limit, use a service account with the ApplicationImpersonation role assigned for the target mailboxes, and impersonate the first user in each subscription ID group when getting streamed events.
Опрашивающие или Push-подключенияPull or push connections
евсмаксконкурренциEWSMaxConcurrency
2727
Максимальное количество одновременных запросов на получение или принудительной передачи (запросов, которые еще не ответили), которые учетная запись может открыть на сервере в один момент времени.The maximum number of concurrent pull or push connections (requests that have been received but not yet responded to) that an account can have open on the server at one time.
ПодпискиSubscriptions
евсмакссубскриптионсEWSMaxSubscriptions
20 для Exchange Online20 for Exchange Online
5000 для Exchange 20135000 for Exchange 2013
Максимальное число подписок с неистекшим сроком действия, которые могут одновременно находиться в учетной записи.The maximum number of nonexpired subscriptions that an account can have at one time. Это значение уменьшается при создании подписки на сервере.This value is decremented when the subscription is created on the server.

В приведенном ниже примере показано, как будут обрабатываться бюджеты между любым целевым почтовым ящиком и учетной записью службы, которой назначена роль ApplicationImpersonation для целевых почтовых ящиков.The following example shows how budgets are handled between any target mailbox and the service account that has the ApplicationImpersonation role assigned for the target mailboxes.

  • ServiceAccount1 (SA1) олицетворяет многих пользователей (M1, m2, M3 и т. д.) и создает подписки для каждого почтового ящика.ServiceAccount1 (sa1) impersonates many users (m1, m2, m3, and so on) and creates subscriptions for each mailbox. Обратите внимание на то, что при создании подписок владелец подписки — SA1, поэтому когда SA1 открывает подключение с подписками, EWS применяет к ним владельца SA1.Note that when the subscriptions are created, the subscription owner is sa1, so when sa1 opens a connection with the subscriptions, EWS enforces that the subscriptions are owned by sa1.

  • SA1 может открыть подключение следующими способами:Sa1 can open the connection in the following ways:

  1. Без олицетворения, поэтому соединение будет взиматься с SA1.Without impersonation, so the connection is charged against sa1.

  2. Выполнив олицетворение любого пользователя (например, M1), чтобы подключение было взимать копию бюджета m1's.By impersonating any of the users — m1 for example — so that the connection is charged against a copy of m1's budget. (M1 может открыть десять подключений с помощью Exchange Online, а все учетные записи служб, вызывающие M1, могут открыть десять подключений с помощью скопированного бюджета.)(M1 itself can open ten connections by using Exchange Online, and all service accounts impersonating m1 can open ten connections by using the copied budget.)

  • Если достигнуто максимальное число подключений, доступны следующие обходные пути:If the connection limit is hit, the following workarounds are available:

    • Если используется вариант 1, администратор может создать несколько учетных записей служб для олицетворения дополнительных пользователей.If option 1 is used, the administrator can create multiple service accounts to impersonate additional users.

    • Если используется вариант 2, код может олицетворять другого пользователя — m2 для примера.If option 2 is used, the code can impersonate another user — m2 for example.

Пример: поддержание сходства между группой подписок и сервером почтовых ящиковExample: Maintaining affinity between a group of subscriptions and the Mailbox server

Итак, давайте посмотрим, как это выполняется в действии.Okay, let's see it in action. В приведенном ниже примере кода показано, как группировать пользователей и использовать заголовки X AnchorMailbox и X Преферсервераффинити, а также файл cookie X – Баккендоверридекукие для поддержки сходства с сервером почтовых ящиков.The following code example shows you how to group users and use the X-AnchorMailbox and X-PreferServerAffinity headers and the X-BackendOverrideCookie cookie to maintain affinity with the Mailbox server. Так как заголовки и файлы cookie являются основным уровнем важности в цепочке сходства, в этом примере основное внимание уделяется запросам и ответам XML EWS.Because the headers and the cookie are of primary importance in the affinity story, this example focuses on the EWS XML requests and responses. Чтобы использовать управляемый API EWS для создания основного текста запросов и ответов на подписку, обратитесь к разделу Отправка уведомлений о событиях почтовых ящиков с помощью EWS в Exchange и уведомления о событиях почтовых ящиков с помощью EWS в Exchange.To use the EWS Managed API to create the body of the subscription requests and responses, see Stream notifications about mailbox events by using EWS in Exchange and Pull notifications about mailbox events by using EWS in Exchange. В этом разделе приводятся дополнительные действия для поддержки сходства и добавления заголовков в запросы.This section includes additional steps particular to maintaining affinity and adding the headers to your requests.

В этом примере имеются четыре пользователя: alfred@contoso.com, alisa@contoso.com, ronnie@contoso.com и sadie@contoso.com.This example has four users: alfred@contoso.com, alisa@contoso.com, ronnie@contoso.com, and sadie@contoso.com. На следующем рисунке показаны Параметры автообнаружения Граупингинформатион и екстерналевсурл для пользователей.The following figure shows the GroupingInformation and ExternalEwsUrl Autodiscover settings for the users.

Рис. 1. Параметры автообнаружения, используемые для групповых почтовых ящиковFigure 1. Autodiscover settings used to group mailboxes

Таблица, в которой показаны значения параметров GroupingInformation и ExternalEwsUrl для каждого из пользователей.

При использовании параметров из ответов автообнаружения почтовые ящики группируются по Объединенному значению параметров Граупингинформатион и Екстерналевсурл.Using the settings from the Autodiscover responses, the mailboxes are grouped by the concatenated value of the GroupingInformation and ExternalEwsUrl settings. В этом примере Алфред и Ольга имеют одинаковые значения, поэтому они находятся в одной группе, а Алиса и ронние имеют одни и те же значения, поэтому они находятся в другой группе.In this example, Alfred and Sadie have the same values, so they are in one group, and Alisa and Ronnie share the same values, so they are in another group.

Рис. 2. Создание групп почтовых ящиковFigure 2. Creating mailbox groups

Таблица, в которой показано, как группы почтовых ящиков создаются с помощью параметров автообнаружения.

В этом примере основное внимание уделяется группе A. Мы будем использовать одни и те же действия для группы B, но использовать другое значение X-AnchorMailbox для этой группы.For the purpose of this example, we'll focus on Group A. We would use the same steps for group B, but use a different X-AnchorMailbox value for that group.

С помощью ApplicationImpersonationсоздайте запрос на подписку для почтового ящика привязки (Alfred@contoso.com), для которого в заголовке x-AnchorMailbox задан адрес электронной почты, а для заголовка x-преферсервераффинити — значение true.Using ApplicationImpersonation, create the subscription request for the anchor mailbox (alfred@contoso.com), with the X-AnchorMailbox header set to the their email address and an X-PreferServerAffinity header value of true. Установка этих двух значений заголовков приведет к запуску сервера для создания Баккендоверридекукие X для ответа.Setting these two header values will trigger the server to create an X-BackEndOverrideCookie for the response.

Если вы используете управляемый API EWS, используйте метод хттфеадерсAdd , чтобы добавить два заголовка в запрос на подписку, как показано ниже.If you're using the EWS Managed API, use the HttpHeadersAdd method to add the two headers to your subscription request, as shown.

service.HttpHeaders.Add("X-AnchorMailbox", Mailbox.SMTPAddress);
service.HttpHeaders.Add("X-PreferServerAffinity", "true");

Поэтому запрос на подписку Алфред выглядит следующим образом.So Alfred's subscription request looks like this.

POST https://outlook.office365.com/EWS/Exchange.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
Accept: text/xml
User-Agent: ExchangeServicesClient/15.00.0516.014
X-AnchorMailbox: alfred@contoso.com
X-PreferServerAffinity: true
Host: outlook.office365.com
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2013" />
    <t:ExchangeImpersonation>
      <t:ConnectingSID>
        <t:SmtpAddress>alfred@contoso.com</t:SmtpAddress>
      </t:ConnectingSID>
    </t:ExchangeImpersonation>
  </soap:Header>
  <soap:Body>
    <m:Subscribe>
      <m:StreamingSubscriptionRequest>
        <t:FolderIds>
          <t:DistinguishedFolderId Id="inbox" />
        </t:FolderIds>
        <t:EventTypes>
          <t:EventType>NewMailEvent</t:EventType>
        </t:EventTypes>
      </m:StreamingSubscriptionRequest>
    </m:Subscribe>
  </soap:Body>
</soap:Envelope>

Следующее XML-сообщение является ответом на запрос подписки Алфред и включает X-Баккендоверридекукие.The following XML message is the response to Alfred's subscription request, and it includes the X-BackEndOverrideCookie. Повторно отправить этот файл cookie для всех последующих запросов пользователей в этой группе.Resend this cookie for all subsequent requests for users in this group. Обратите внимание, что в ответе также содержатся дополнительные файлы cookie, например файл cookie ексчанжекукие, используемый Exchange 2010.Notice that the response also contains additional cookies, such as the exchangecookie cookie used by Exchange 2010. Exchange Online, Exchange Online в составе Office 365 и версии Exchange, начиная с Exchange 2013, игнорируйте ексчанжекукие, если он включен в последующие запросы подписки.Exchange Online, Exchange Online as part of Office 365, and versions of Exchange starting with Exchange 2013, ignore exchangecookie if it is included in subsequent subscription requests.

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Set-Cookie: exchangecookie=ddb8c383aef34c7694132aa679744feb; expires=Thu, 25-Sep-2014 18:42:45 GMT; path=/;
    HttpOnly
Set-Cookie: X-BackEndOverrideCookie=CO1PR06MB222.namprd06.prod.outlook.com~1941996295; path=/; secure; HttpOnly
Set-Cookie: X-BackEndCookie=alfred@contoso.com=Ox8XKzcXLxg==; 
    expires=Wed, 25-Sep-2013 18:52:49 GMT; path=/EWS; secure; HttpOnly
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo MajorVersion="15"
                         MinorVersion="0"
                         MajorBuildNumber="775"
                         MinorBuildNumber="7"
                         Version="V2_4"
                         xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
                         xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
                         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <m:SubscribeResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
                         xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:SubscribeResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:SubscriptionId>JgBjbzFwcjA2bWIyMjIubmFtcHJkMDYucHJvZC5vdXRsb29rLmNvbRAAAAAUeGk+7JFdSaFM8/NI/gQQpVdgZX6H0Ag=</m:SubscriptionId>
        </m:SubscribeResponseMessage>
      </m:ResponseMessages>
    </m:SubscribeResponse>
  </s:Body>
</s:Envelope>

При использовании ответа X-Баккендоверридекукие из отклика Алфред и заголовка X-AnchorMailbox запрос на подписку создается для Ольга, а другой участник группы A. Ольга-запроса на подписку выглядит следующим образом.Using the X-BackEndOverrideCookie from Alfred's response and the X-AnchorMailbox header, the subscription request is created for Sadie, the other member of Group A. Sadie's subscription request looks like this.

POST https://outlook.office365.com/EWS/Exchange.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
Accept: text/xml
User-Agent: ExchangeServicesClient/15.00.0516.014
X-AnchorMailbox: alfred@contoso.com
X-PreferServerAffinity: true
Host: outlook.office365.com
Cookie: X-BackEndOverrideCookie=CO1PR06MB222.namprd06.prod.outlook.com~1941996295
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2013" />
    <t:ExchangeImpersonation>
      <t:ConnectingSID>
        <t:SmtpAddress>sadie@contoso.com </t:SmtpAddress>
      </t:ConnectingSID>
    </t:ExchangeImpersonation>
  </soap:Header>
  <soap:Body>
    <m:Subscribe>
      <m:StreamingSubscriptionRequest>
        <t:FolderIds>
          <t:DistinguishedFolderId Id="inbox" />
        </t:FolderIds>
        <t:EventTypes>
          <t:EventType>NewMailEvent</t:EventType>
        </t:EventTypes>
      </m:StreamingSubscriptionRequest>
    </m:Subscribe>
  </soap:Body>
</soap:Envelope>

Ответ на подписку Ольга выглядит следующим образом.Sadie's subscription response looks like this. Обратите внимание, что он не включает X – Баккендоверридекукие.Note that it does not include the X-BackEndOverrideCookie. Клиент отвечает за кэширование этого значения для будущих запросов.The client is responsible for caching that value for future requests.

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Set-Cookie: exchangecookie=640ea858f69d47ff8cce8b44c337f6d9; path=/
Set-Cookie: X-BackEndCookie=alfred@contoso.com=Ox8XKzcXLxg==; 
   expires= Wed, 25-Sep-2013 18:53:06 GMT; path=/EWS; secure; HttpOnly
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo MajorVersion="15"
                         MinorVersion="0"
                         MajorBuildNumber="775"
                         MinorBuildNumber="7"
                         Version="V2_4"
                         xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
                         xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
                         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <m:SubscribeResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
                         xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:SubscribeResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:SubscriptionId>JgBjbzFwcjA2bWIyMjIubmFtcHJkMDYucHJvZC5vdXRsb29rLmNvbRAAAAB4EQOy2pfrQJfM3hzs/nZJIZssan6H0Ag=</m:SubscriptionId>
        </m:SubscribeResponseMessage>
      </m:ResponseMessages>
    </m:SubscribeResponse>
  </s:Body>
</s:Envelope>

С помощью значений SubscriptionId из ответов на подписку был создан запрос GetStreamingEvents для всех подписок в группе.Using the SubscriptionId values from the subscription responses, a GetStreamingEvents operation request was created for all the subscriptions in the group. Так как в этой группе менее 200 подписок, все они отправляются в одном запросе.Because there are less than 200 subscriptions in this group, they are all sent in one request. Для заголовка X-Преферсервераффинити задано значение true, а также включен параметр X-Баккендоверридекукие.The X-PreferServerAffinity header is set to true and the X-BackEndOverrideCookie is included.

POST https://outlook.office365.com/EWS/Exchange.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
Accept: text/xml
User-Agent: ExchangeServicesClient/15.00.0516.014
X-AnchorMailbox: alfred@contoso.com
X-PreferServerAffinity: true
Host: outlook.office365.com
Cookie: X-BackEndOverrideCookie=CO1PR06MB222.namprd06.prod.outlook.com~1941996295
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2013" />
    <t:ExchangeImpersonation>
      <t:ConnectingSID>
        <t:SmtpAddress>sadie@contoso.com</t:SmtpAddress>
      </t:ConnectingSID>
    </t:ExchangeImpersonation>
  </soap:Header>
  <soap:Body>
    <m:GetStreamingEvents>
      <m:SubscriptionIds>
        <t:SubscriptionId>JgBjbzFwcjA2bWIyMjIubmFtcHJkMDYucHJvZC5vdXRsb29rLmNvbRAAAAB4EQOy2pfrQJfM3hzs/nZJIZssan6H0Ag=</t:SubscriptionId>
        <t:SubscriptionId>JgBjbzFwcjA2bWIyMjIubmFtcHJkMDYucHJvZC5vdXRsb29rLmNvbRAAAAAUeGk+7JFdSaFM8/NI/gQQpVdgZX6H0Ag=</t:SubscriptionId>
      </m:SubscriptionIds>
      <m:ConnectionTimeout>10</m:ConnectionTimeout>
    </m:GetStreamingEvents>
  </soap:Body>
</soap:Envelope>

Возвращаемые события затем передаются в отдельный поток для обработки.The returned events are then passed to a separate thread for processing.

Как изменилось сходство?How has affinity changed?

В Exchange 2010 подписки хранятся на сервере клиентского доступа, как показано на рисунке 3.In Exchange 2010, subscriptions are maintained on the Client Access server, as shown in Figure 3. В более поздних версиях Exchange, чем Exchange 2010, подписки хранятся на сервере почтовых ящиков, как показано на рисунке 4.In versions of Exchange later than Exchange 2010, subscriptions are maintained on the Mailbox server, as shown in Figure 4.

Рис. 3. Процесс поддержания сходства в Exchange 2010Figure 3. Process for maintaining affinity in Exchange 2010

Иллюстрация, показывающая принцип поддержки таблицы активных подписок на сервере клиентского доступа в Exchange 2010.

На рисунке 4. Процесс поддержания сходства в Exchange Online и Exchange 2013Figure 4. Process for maintaining affinity in Exchange Online and Exchange 2013

Иллюстрация, показывающая, как балансировщик нагрузки и сервер клиентского доступа перенаправляют запросы на сервер почтовых ящиков, на котором хранится таблица активных подписок Exchange Server и Exchange Online.

В Exchange 2010 клиент знает только адрес подсистемы балансировки нагрузки, а ексчанжекукие, возвращенный сервером, гарантирует, что запрос перенаправляется на подходящий сервер клиентского доступа.In Exchange 2010, the client only knows the address of the load balancer, and the exchangecookie that is returned by the server ensures that the request is routed to the right Client Access server. Однако в более поздних версиях подсистема балансировки нагрузки и роли сервера клиентского доступа должны правильно маршрутизировать запросы, прежде чем они будут переданы на сервер почтовых ящиков.However, in later versions, the load balancer and the Client Access server roles both have to route the requests appropriately before they get to the Mailbox server. Для этого требуются дополнительные сведения, поэтому были введены новые заголовки и файлы cookie.To do that, additional information is required, which is why the new headers and cookie were introduced. Подписки на уведомления, события почтовых ящиков и EWS в Exchange в Exchange поясняют, как поддерживаются подписки в Exchange 2013.The article Notification subscriptions, mailbox events, and EWS in Exchange explains how subscriptions are maintained in Exchange 2013.

Вы можете заметить, что ексчанжекукие, используемый Exchange 2010, по-прежнему возвращается в более поздних версиях.You might notice that the exchangecookie that Exchange 2010 uses is still returned by later versions. Включение этого файла cookie в запросы не является вредом, но последующие версии Exchange игнорируют его.There's no harm in including this cookie in requests, but later versions of Exchange ignore it.

См. такжеSee also