Сохраняемость и сериализация данных в Устойчивые функции для Функции Azure

Среда выполнения Устойчивые функции автоматически сохраняет параметры функции, возвращаемые значения и другие данные о состоянии в концентратор задач task для обеспечения надежного выполнения. Однако объем и частота данных, сохраняемых в долговременном хранилище, может повлиять на производительность приложений и затраты на транзакции хранилища. В зависимости от типа данных, которые хранятся в вашем приложении, также может потребоваться учитывать политики хранения данных и конфиденциальности.

В этой статье объясняется, какие данные сохраняются, как обрабатывать большие полезные данные и конфиденциальные данные, а также как настроить сериализацию для каждого поддерживаемого языка.

Содержание этой статьи

Содержимое концентратора задач

Центры задач хранят текущее состояние экземпляров и все ожидающие сообщения:

  • Состояния экземпляров хранят текущее состояние и историю экземпляра. Для экземпляров оркестрации это состояние включает состояние среды выполнения, журнал оркестрации, входные данные, выходные данные и настраиваемое состояние. Для экземпляров сущностей указывается состояние сущности.
  • Сообщения хранят входные или выходные данные функции, полезные данные событий и метаданные, которые используются для внутренних целей, таких как маршрутизация и сквозная корреляция.

Сообщения удаляются после обработки, но состояния экземпляра сохраняются, если их не удалит явно приложение или оператор. В частности, журнал оркестрации остается в хранилище даже после завершения оркестрации.

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

Место и способ представления состояний и сообщений в хранилище зависит от поставщика хранилища. Поставщик по умолчанию для Устойчивые функции — это служба хранилища Azure, который сохраняет данные в очередях, таблицах и блобах в указанной вами учетной записи служба хранилища Azure.

Типы данных, сериализованные и сохраненные

В следующем списке показаны различные типы данных, которые будут сериализованы и сохранены при использовании функций Устойчивые функции:

  • все входящие и выходящие данные функций оркестратора, активности и сущности, включая любые идентификаторы и необработанные исключения;
  • имена функций оркестратора, активности и сущности;
  • Имена внешних событий и полезная нагрузка
  • настраиваемые полезные нагрузки статуса оркестрации
  • Сообщения о завершении оркестрации
  • устойчивые полезные данные таймера;
  • надёжные URL-адреса запросов и ответов HTTP, заголовки и нагрузка.
  • Вызов функции сущности и полезная нагрузка сигнала
  • полезная нагрузка состояния сущности

Руководство по управлению размером полезной нагрузки и защите конфиденциальных элементов в этом списке смотрите в следующих разделах.

Держите входные и выходные данные Устойчивые функции минимальными.

Вы можете столкнуться с проблемами с памятью, если вы предоставляете большие входные и выходные данные в Устойчивые функции API. Входные и выходные данные сериализуются в журнал оркестрации, что означает, что большие полезные данные могут со временем значительно способствовать неограниченному росту истории. Существует риск, что этот рост приведет к исключениям памяти во время воспроизведения.

Чтобы снизить влияние больших входных и выходных данных, можно:

  • Делегируйте работу подоркестраторам, чтобы сбалансировать нагрузку на память истории в нескольких оркестраторах, сохраняя объем памяти отдельных историй небольшим.
  • Храните большие данные во внешнем хранилище (например, Хранилище BLOB-объектов Azure) и передайте упрощенные идентификаторы, которые позволяют получать эти данные внутри функций действий при необходимости.

Если вы используете планировщик устойчивых задач, вы также можете использовать поддержку больших полезных данных для разгрузки больших полезных данных в хранилище BLOB-объектов Azure.

Tip

Рекомендуется сохранять большие данные во внешнем хранилище и материализовать их только в рамках операций, если это необходимо.

Работа с конфиденциальными данными

Входные и выходные данные (включая исключения) для API-интерфейсов Устойчивые функции устойчиво сохраняются и извлекаются в выбранном вами поставщике хранилища. Если эти входные данные, выходные данные или исключения содержат конфиденциальные данные (например, секреты, строки подключения или личную информацию), любой пользователь с доступом на чтение к ресурсам поставщика хранилища может получить их.

Чтобы безопасно обрабатывать конфиденциальные данные, извлекайте данные в функциях действий из Azure Key Vault или переменных среды и никогда не сообщайте эти данные напрямую или из оркестраторов или сущностей. Этот подход помогает предотвратить утечку конфиденциальных данных в ресурсы хранилища.

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

Tip

Это руководство также относится к CallHttp API оркестратора, который сохраняет полезные данные запроса и ответа в хранилище. Если целевые конечные точки HTTP требуют проверки подлинности, реализуйте http-вызов внутри действия или используйте встроенную поддержку управляемого удостоверения, предлагаемую CallHttp, которая не сохраняет учетные данные в хранилище.

Note

Избегайте регистрации данных, содержащих секреты, так как любой пользователь с доступом на чтение к журналам (например, в Application Insights) может получить эти секреты.

Шифрование при хранении

При использовании поставщика хранилищ Azure все данные автоматически шифруются в состоянии покоя. Однако любой пользователь, имеющий доступ к учетной записи хранения, может считывать данные в их незашифрованном виде. Если вам нужна более надежная защита конфиденциальных данных, сначала рассмотрите возможность шифрования данных с помощью собственных ключей шифрования, чтобы данные сохранялись в предварительно зашифрованной форме.

Кроме того, пользователи .NET имеют возможность реализовать пользовательские поставщики сериализации, обеспечивающие автоматическое шифрование. Пример пользовательской сериализации с шифрованием можно найти в этом примере на GitHub .

Note

Если вы решили реализовать шифрование на уровне приложения, имейте в виду, что оркестрации и сущности могут существовать в течение неопределенного количества времени. Важность этого вопроса возникает, когда настает момент для обновления ключей шифрования, поскольку процессы или сущности могут работать дольше, чем ваша политика смены ключей. Если происходит смена ключа, то ключ, используемый для шифрования ваших данных, может оказаться недоступным для их расшифровки при следующем запуске оркестрации или объекта. Поэтому пользовательское шифрование рекомендуется использовать только в том случае, если оркестрации и сущности должны выполняться в течение относительно короткого времени.

Защита хранилища концентратора задач

Серверная часть хранилища, в которую размещается центр задач, является критической границей доверия. Платформа устойчивых задач доверяет данным, считываемым из хранилища во время воспроизведения оркестрации и обработки сообщений. Любой пользователь, имеющий доступ на запись к хранилищу центра задач, может вмешиваться в состояние оркестрации, сообщения в очереди или сохраненные данные полезной нагрузки. Это может изменить поведение приложения, активировать непреднамеренные действия или выполнить удаленное выполнение кода в контексте приложения-функции.

Important

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

Общая ответственность

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

Если вы используете Durable Task Scheduler, служба полностью управляет механизмом хранения и защищает его с помощью аутентификации через управляемое удостоверение и ролевого управления доступом (RBAC). В случае собственных серверных хранилищ типа BYO, таких как служба хранилища Azure, MSSQL или Netherite, необходимо самостоятельно защитить базовые ресурсы хранения.

Note

Не используйте один Task Hub для нескольких недоверенных арендаторов. Концентратор задач не разграничивает права доступа между своими пользователями, поэтому любой арендатор, который может читать данные в концентраторе задач или записывать их туда, может влиять на все оркестрации и сущности в нём. Аналогичным образом не следует полагаться на отдельные концентраторы задач в одном и том же бэкенде как на границу безопасности. Хотя планировщик устойчивых задач поддерживает RBAC в пределах отдельных центров задач, сетевые элементы управления, такие как списки разрешений IP и частные конечные точки, применяются только на уровне планировщика, поэтому центры задач в планировщике не являются границей изоляции безопасности. То же самое верно для поставщиков хранилища BYO— любой клиент с доступом к учетной записи хранения или базе данных может получить доступ ко всем центрам задач в этой серверной части. При необходимости изоляции безопасности между клиентами подготовьте отдельную инфраструктуру для каждого клиента: отдельные учетные записи хранения или базы данных для поставщиков BYO или отдельные экземпляры планировщика устойчивых задач.

Контрольный список по усилению безопасности хранилища

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

  • Используйте подключения на основе идентификации вместо строк подключения, содержащих ключи хранилища. Управляемые удостоверения обеспечивают точное управление доступом и устраняют риск утечки учетных данных. См. Настройка управляемого удостоверения для Устойчивые функции.
  • Применяйте роли RBAC с наименьшими привилегиями. Предоставьте только минимальные необходимые разрешения. Избегайте предоставления доступа к широкой учетной записи хранения пользователям или службам, которым он не нужен.
  • Ограничить сетевой доступ к учетной записи хранения с помощью частных конечных точек или конечных точек службы. Это предотвращает несанкционированный доступ на уровне сети к данным концентратора задач.
  • Отслеживайте доступ к хранилищу, включив журналы ресурсов Azure Monitor для вашей учетной записи хранения, в частности категорию журналов StorageWrite. Перенаправите эти журналы в место назначения за пределами отслеживаемой учетной записи хранения, например Log Analytics, чтобы они не могли быть изменены. См. журналы хранилища.
  • Регулярно поворачивайте учетные данные при использовании строк подключения. Обращайтесь с ключами учетной записи хранилища с той же осторожностью, как и к любым другим учетным данным с высоким уровнем привилегий.
  • Рассмотрим серверную часть управляемого хранилища. Планировщик устойчивых задач автоматически обрабатывает безопасность хранилища, включая шифрование, проверку подлинности и сетевую изоляцию.

Настройка сериализации и десериализации

Параметры настройки сериализации зависят от языка. Выберите вкладку языка, чтобы просмотреть доступные параметры.

Логика сериализации по умолчанию

Устойчивые функции для .NET внутри процессов используют JSON.NET для сериализации данных оркестрации и сущностей в JSON. Используются параметры Json.NET по умолчанию:

Входы, выходы и состояние:

JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.None,
    DateParseHandling = DateParseHandling.None,
}

Исключения:

JsonSerializerSettings
{
    ContractResolver = new ExceptionResolver(),
    TypeNameHandling = TypeNameHandling.Objects,
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
}

Дополнительные сведения о JsonSerializerSettings см. здесь.

Настройка сериализации с помощью атрибутов .NET

Во время сериализации Json.NET ищет различные атрибуты классов и свойств, которые управляют сериализацией и десериализацией данных из JSON. Если вы владеете исходным кодом для типа данных, переданного в API Устойчивые функции, попробуйте добавить эти атрибуты в тип для настройки сериализации и десериализации.

Настройка сериализации с помощью внедрения зависимостей

Приложения-функции, предназначенные для .NET и запускаемых в среде выполнения Функций версии 3, могут использовать Dependency Injection (DI) для настройки сериализации данных и исключений. В следующем примере кода показано, как использовать DI для переопределения параметров сериализации Json.NET по умолчанию с помощью пользовательских реализаций интерфейсов служб IMessageSerializerSettingsFactory и IErrorSerializerSettingsFactory.

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System.Collections.Generic;

[assembly: FunctionsStartup(typeof(MyApplication.Startup))]
namespace MyApplication
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddSingleton<IMessageSerializerSettingsFactory, CustomMessageSerializerSettingsFactory>();
            builder.Services.AddSingleton<IErrorSerializerSettingsFactory, CustomErrorSerializerSettingsFactory>();
        }

        /// <summary>
        /// A factory that provides the serialization for all inputs and outputs for activities and
        /// orchestrations, as well as entity state.
        /// </summary>
        internal class CustomMessageSerializerSettingsFactory : IMessageSerializerSettingsFactory
        {
            public JsonSerializerSettings CreateJsonSerializerSettings()
            {
                // Return your custom JsonSerializerSettings here
            }
        }

        /// <summary>
        /// A factory that provides the serialization for all exceptions thrown by activities
        /// and orchestrations
        /// </summary>
        internal class CustomErrorSerializerSettingsFactory : IErrorSerializerSettingsFactory
        {
            public JsonSerializerSettings CreateJsonSerializerSettings()
            {
                // Return your custom JsonSerializerSettings here
            }
        }
    }
}

Дальнейшие действия