[Документация Yandex Cloud](../../index.md) > [Yandex Managed Service for Valkey™](../index.md) > [Практические руководства](index.md) > Распределенные блокировки для «1С:Предприятия» в кластере Yandex Managed Service for Valkey™

# Распределенные блокировки для 1С:Предприятия в кластере Yandex Managed Service for Valkey™

Кластер Yandex Managed Service for Valkey™ можно использовать как хранилище распределенных блокировок для 1С:Предприятия — например, чтобы несколько пользователей не могли одновременно редактировать один и тот же элемент справочника.

Интеграция выполняется через промежуточный HTTP-сервер, развернутый на виртуальной машине Yandex Compute Cloud. Сервер предоставляет HTTP API для управления блокировками и использует кластер Valkey™ в качестве бэкенда. Модуль в 1С:Предприятии взаимодействует с API через внешнее соединение.

{% note info %}

Для работы модуля требуется 1С:Предприятие версии не ниже 8.3.

{% endnote %}

Чтобы настроить блокировки:

1. [Подготовьте инфраструктуру](#deploy-infrastructure).
2. [Разверните HTTP-сервер блокировок](#deploy-lock-server).
3. [Настройте модуль в 1С:Предприятии](#configure-1c).
4. [Проверьте работу блокировок](#test).
5. [Удалите созданные ресурсы](#clear-out)


## Перед началом работы {#before-you-begin}

Зарегистрируйтесь в Yandex Cloud и создайте [платежный аккаунт](../../billing/concepts/billing-account.md):
1. Перейдите в [консоль управления](https://kz.console.yandex.cloud), затем войдите в Yandex Cloud или зарегистрируйтесь.
1. На странице **[Yandex Cloud Billing](https://kz.console.yandex.cloud/billing)** убедитесь, что у вас подключен платежный аккаунт, и он находится в [статусе](../../billing/concepts/billing-account-statuses.md) `ACTIVE` или `TRIAL_ACTIVE`. Если платежного аккаунта нет, [создайте его](../../billing/quickstart/index.md) и [привяжите](../../billing/operations/pin-cloud.md) к нему облако.

Если у вас есть активный платежный аккаунт, вы можете создать или выбрать [каталог](../../resource-manager/concepts/resources-hierarchy.md#folder), в котором будет работать ваша инфраструктура, на [странице облака](https://kz.console.yandex.cloud/cloud).

[Подробнее об облаках и каталогах](../../resource-manager/concepts/resources-hierarchy.md).

### Необходимые платные ресурсы {#paid-resources}

* Кластер Yandex Managed Service for Valkey™: вычислительные ресурсы хостов и объем хранилища ([тарифы Yandex Managed Service for Valkey™](../pricing.md)).
* Виртуальная машина: использование вычислительных ресурсов, хранилища, публичного IP-адреса и операционной системы ([тарифы Compute Cloud](../../compute/pricing.md)).


## Подготовьте инфраструктуру {#deploy-infrastructure}

{% list tabs group=instructions %}

- Вручную {#manual}

  1. [Создайте кластер Yandex Managed Service for Valkey™](../operations/cluster-create.md) со следующими характеристиками:

     * **Версия Valkey** — `9.1`.

     * **Имя** — `1c-locks`.

     * Включите опцию **Использовать FQDN вместо IP-адресов**.

     * Выберите режим [персистентности данных](../concepts/replication.md#persistence) **На репликах**.

       {% note warning %}

       Блокировки имеют ограниченный TTL. Чтобы избежать потери данных, используйте [высокодоступную конфигурацию кластера](../concepts/high-availability.md).

       {% endnote %}

     * Включите настройку **Доступ из WebSQL**.

  1. [Создайте виртуальную машину](../../compute/operations/vm-create/create-linux-vm.md) для HTTP-сервера блокировок в той же сети, что и кластер.

  1. [Настройте группы безопасности](../operations/connect/index.md#configuring-security-groups) так, чтобы:

     * HTTP-сервер мог подключаться к кластеру.
     * Сервер 1С:Предприятия мог обращаться к HTTP-серверу по выбранному порту.

- Terraform {#tf}

  1. Если у вас еще нет Terraform, [установите его](../../tutorials/infrastructure-management/terraform-quickstart.md#install-terraform).
  1. [Получите данные для аутентификации](../../tutorials/infrastructure-management/terraform-quickstart.md#get-credentials). Вы можете добавить их в переменные окружения или указать далее в файле с настройками провайдера.
  1. [Настройте и инициализируйте провайдер](../../tutorials/infrastructure-management/terraform-quickstart.md#configure-provider). Чтобы не создавать конфигурационный файл с настройками провайдера вручную, [скачайте его](https://github.com/yandex-cloud-examples/yc-terraform-provider-settings/blob/main/provider.tf).
  1. Поместите конфигурационный файл в отдельную рабочую директорию и [укажите значения параметров](../../tutorials/infrastructure-management/terraform-quickstart.md#configure-provider). Если данные для аутентификации не были добавлены в переменные окружения, укажите их в конфигурационном файле.
  1. Скачайте в ту же рабочую директорию файл конфигурации [valkey-1c-http.tf](https://github.com/yandex-cloud-examples/yc-valkey-1c-locks/blob/main/valkey-1c-http.tf).

      В этом файле описаны:

      * сеть;
      * подсеть;
      * группы безопасности;
      * кластер Yandex Managed Service for Valkey™;
      * виртуальная машина с публичным доступом из интернета и предустановленным HTTP-сервером вместе со всеми зависимостями.

  1. Укажите в файле `valkey-1c-http.tf`:

      * пароль для доступа к кластеру Yandex Managed Service for Valkey™;
      * порт для обращения к HTTP-серверу блокировок;
      * префикс ключей блокировки в Valkey™.

  1. Проверьте корректность файлов конфигурации Terraform с помощью команды:

      ```bash
      terraform validate
      ```

      Если в файлах конфигурации есть ошибки, Terraform на них укажет.

  1. Создайте необходимую инфраструктуру:

      1. Выполните команду для просмотра планируемых изменений:
      
         ```bash
         terraform plan
         ```
      
         Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
      
      1. Если вас устраивают планируемые изменения, внесите их:
      
         1. Выполните команду:
      
            ```bash
            terraform apply
            ```
      
         1. Подтвердите изменение ресурсов.
         1. Дождитесь завершения операции.

      В указанном каталоге будут созданы все требуемые ресурсы. Проверить появление ресурсов и их настройки можно в [консоли управления](https://kz.console.yandex.cloud).

  После завершения операции создания ресурсов в терминале будут выведены параметры HTTP-сервера блокировок:

  * `vm_public_ip` — публичный IP-адрес сервера.
  * `http_url` — эндпоинт для подключения к серверу.

{% endlist %}

## Разверните HTTP-сервер блокировок {#deploy-lock-server}

HTTP-сервер блокировок — это тонкая прослойка между сервером 1С:Предприятия и кластером Yandex Managed Service for Valkey™. Он предоставляет эндпоинты с префиксом `lock`:

|Эндпоинт|Метод|Назначение|
|:---|:---|:---|
|`lock/acquire`|POST|Захватить блокировку|
|`lock/release`|POST|Освободить блокировку|
|`lock/renew`|POST|Продлить блокировку|
|`lock/status`|POST|Получить статус блокировки|
|`lock/list`|GET|Получить список блокировок|

Логика работы с кластером:

* Захват блокировки (`lock/acquire`) выполняется командой `SET` с аргументом `NX` и установкой времени жизни ключа (`PX`). Аргумент `NX` гарантирует, что блокировка захватывается, только если ключа еще нет, а TTL не дает удерживать блокировку бесконечно:

  ```text
  SET <ключ> <токен> NX PX <ttl_в_миллисекундах>
  ```

* Освобождение (`lock/release`) и продление (`lock/renew`) блокировки выполняются командой `EVAL` с вызовом Lua-скриптов. В рамках скриптов выполняются несколько последовательных операций в Valkey™:

   1. Получение данных блокировки по ключу.
   1. Сравнение токена блокировки и токена из запроса.
   1. Удаление ключа или продление срока блокировки.

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

   ```lua
   -- release: удалить ключ, только если токен совпадает
   local value = server.call('GET', KEYS[1])
   if not value then
     return 0
   end
   local ok, lock = pcall(cjson.decode, value)
   if not ok or lock['token'] ~= ARGV[1] then
     return 0
   end
   return server.call('DEL', KEYS[1])
   ```

* Сервер возвращает HTTP-коды состояния и сообщения об ошибках (удалось ли захватить, освободить или продлить блокировку).

Чтобы развернуть сервер:

{% list tabs group=instructions %}

- Вручную {#manual}

    1. [Подключитесь к виртуальной машине по SSH](../../compute/operations/vm-connect/ssh.md).
    1. Установите [Go версии 1.26.2](https://go.dev/dl/) или выше.
    1. Клонируйте репозиторий:

       ```bash
       git clone https://git@git.sourcecraft.dev/valkey/webinar-260624-1c-example.git && \
       cd webinar-260624-1c-example/http-lock-valkey
       ```

    1. Создайте переменные окружения с конфигурацией сервера:

       ```bash
       export HTTP_ADDR=:<открытый_порт_сервера_для_запросов>
       export VALKEY_ADDR=<FQDN_хоста_Valkey™>:6379
       export VALKEY_USER=default
       export VALKEY_PASSWORD=<пароль_Valkey™>
       export DEFAULT_LOCK_TTL=<интервал_продления_блокировки_в_секундах>
       export LOCK_KEY_PREFIX=<префикс_ключа_блокировки>
       ```

    1. Запустите HTTP-сервер командой:

       ```bash
       go run .
       ```

- Terraform {#tf}

    В файле конфигурации Terraform указаны все необходимые команды для развертывания HTTP-сервера. После создания инфраструктуры сервер полностью готов к работе.

    1. При необходимости измените параметры сервера в файле конфигурации:

       * Интервал продления блокировки в параметре `DEFAULT_LOCK_TTL` локальной переменной `cloud_init`.
       * Префикс ключа блокировки в локальной переменной `lock_key_prefix`.
       * Порт сервера для запросов от кластера Valkey™ в локальной переменной `http_port`.

    1. Проверьте корректность настроек.

        1. В командной строке перейдите в каталог, в котором расположены актуальные конфигурационные файлы Terraform с планом инфраструктуры.
        1. Выполните команду:
        
           ```bash
           terraform validate
           ```
        
           Если в файлах конфигурации есть ошибки, Terraform на них укажет.

    1. Подтвердите изменение ресурсов.

        1. Выполните команду для просмотра планируемых изменений:
        
           ```bash
           terraform plan
           ```
        
           Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
        
        1. Если вас устраивают планируемые изменения, внесите их:
        
           1. Выполните команду:
        
              ```bash
              terraform apply
              ```
        
           1. Подтвердите изменение ресурсов.
           1. Дождитесь завершения операции.

    После завершения операции изменения ресурсов в терминале будут выведены обновленные параметры HTTP-сервера блокировок:

    * `vm_public_ip` — публичный IP-адрес сервера.
    * `http_url` — эндпоинт для подключения к серверу.

{% endlist %}

## Настройте модуль в 1С:Предприятии {#configure-1c}

В 1С:Предприятии используется модуль **Блокировка каталога**, который обращается к HTTP-серверу по внешнему соединению. Готовый код модуля содержится в контейнере с тестовой базой данных 1С:Предприятия в репозитории [valkey/webinar-260624-1c-example](https://sourcecraft.dev/valkey/webinar-260624-1c-example/browse/1CExample).

Модуль выполняет следующие функции:

* Отправка HTTP-запросов к эндпоинтам сервера (`lock/acquire`, `lock/release`, `lock/status`, `lock/renew`, `lock/list`) в зависимости от действия.
* Формирование ключа блокировки из полного пути каталога (метаданных коллекции) и идентификатора элемента. Это гарантирует уникальность блокировки для конкретного элемента справочника.
* В форме модуля настраиваются обработчики событий для справочников:
   * при открытии — попытка захватить блокировку;
   * при изменении и закрытии — продлить или освободить блокировку.
* Чтобы не истек срок действия блокировки во время работы пользователя с формой, настраивается периодическое продление блокировки.
* Для наглядности на форму выводится информация о блокировке: состояние (захвачена или свободна), оставшийся TTL и токен, по которому проверяется владение блокировкой.

Чтобы настроить модуль:

1. Подключите базу данных из папки `1CExample` репозитория и скопируйте общий модуль `БлокировкиКаталогов` в вашу конфигурацию 1С:Предприятия.
1. Если методы вызываются из серверного кода форм, проверьте, что у модуля включен серверный вызов.
1. В функции `HTTPЗапрос()` укажите адрес HTTP-сервера блокировок:

   ```text
   Соединение = Новый HTTPСоединение("<публичный_IP_адрес_созданной_ВМ>", <порт_из_переменной_HTTP_ADDR>);
   ```

1. Добавьте блокировку в нужную форму. Для этого:

   * Добавьте реквизиты формы для токена и статуса.
   * При открытии формы вызывайте `ЗаблокироватьКаталог()`.
   * При закрытии формы вызывайте `РазблокироватьКаталог()`.
   * Подключите периодическую отправку `renew`.

1. Подключите обработчики событий формы к нужным справочникам. Пример для минимальной функциональности:

   ```text
   ПриСозданииНаСервере:
       acquire

   ПриОткрытии:
       renew

   ПриЗакрытии:
       release
   ```

1. Настройте ключ блокировки. По умолчанию ключ формируется как:

   ```text
   "Справочник." + Ссылка.Метаданные().Имя + ":" + Ссылка.УникальныйИдентификатор()
   ```

   Для документов можно сделать аналогично:

   ```text
   Документ.ЗаказКлиента:УникальныйИдентификатор()
   ```

   Если нужно использовать один модуль для разных типов объектов, обобщите функцию `КлючБлокировки()`.

{% note warning %}

Настройки подключения модуля могут отличаться в зависимости от пользовательской реализации 1С-Предприятия.

{% endnote %}

## Проверьте работу блокировок {#test}

1. Откройте 1С:Предприятие и перейдите в справочник, например `Клиенты`.
1. Откройте на редактирование элемент, например `Роман`. На форме отобразится состояние блокировки — захвачена, а также TTL блокировки и токен.
1. Понаблюдайте за TTL: он должен уменьшаться со временем (например, `41` → `31` секунда). По истечении интервала продления (по умолчанию 30 секунд) 1С:Предприятие автоматически продлевает блокировку.

1. Убедитесь, что блокировка отражается в кластере:

   {% list tabs group=instructions %}

   - Консоль управления {#console}

       1. Откройте [**Подключения**](https://websql.yandex.cloud) Yandex WebSQL.
       1. [Добавьте подключение к БД](../../websql/operations/add-connection-to-db-in-cluster.md) для созданного ранее сервера Valkey™. Укажите имя БД `0`.
       1. Подключитесь к базе данных `0` и найдите строку с ключом блокировки.

       {% note info %}

       Из-за особенностей кодировки имя ключа в WebSQL может отображаться некорректно. Для проверки владения блокировкой ориентируйтесь на его наличие и значение (токен), а не на читаемость имени.

       {% endnote %}

   - SQL {#sql}

       [Подключитесь к кластеру Yandex Managed Service for Valkey™](../operations/connect/clients.md#valkey-cli) и выполните запрос:

       ```bash
       KEYS <префикс_ключа_блокировки>:*
       ```

       Valkey™ вернет строку с ключом блокировки.

   {% endlist %}

## Удалите созданные ресурсы {#clear-out}

Чтобы снизить потребление ресурсов, которые вам не нужны, удалите их:

{% list tabs group=instructions %}

- Вручную {#manual}

  1. [Удалите кластер Yandex Managed Service for Valkey™](../operations/cluster-delete.md).
  1. [Удалите ВМ](../../compute/operations/vm-control/vm-delete.md).

- С помощью Terraform {#tf}

  1. В терминале перейдите в директорию с планом инфраструктуры.
  
      {% note warning %}
  
      Убедитесь, что в директории нет Terraform-манифестов с ресурсами, которые вы хотите сохранить. Terraform удаляет все ресурсы, которые были созданы с помощью манифестов в текущей директории.
  
      {% endnote %}
  
  1. Удалите ресурсы:
  
      1. Выполните команду:
  
          ```bash
          terraform destroy
          ```
  
      1. Подтвердите удаление ресурсов и дождитесь завершения операции.
  
      Все ресурсы, которые были описаны в Terraform-манифестах, будут удалены.

{% endlist %}