1. Архитектура ПО¶
Архитектура программного обеспечения (ПО) - это структурное разбиение системы на составные части, их взаимодействие и организация, направленные на достижение определенных целей программы. Архитектура ПО определяет общую форму системы, определяет ключевые компоненты, их связи и принципы организации.
Важные аспекты архитектуры ПО включают:
- Компоненты: Определение основных элементов системы, таких как модули, компоненты, классы и т.д.
- Связи: Определение взаимосвязей между компонентами. Это включает в себя способы передачи данных, вызова функций и другие формы взаимодействия.
- Стиль архитектуры: Выбор общего стиля или парадигмы архитектуры, такой как клиент-сервер, многоуровневая архитектура, микросервисы и т.д.
- Принципы проектирования: Установление основных принципов и правил для разработки программного обеспечения, таких как принципы SOLID (Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion) и другие.
- Шаблоны проектирования: Использование стандартных шаблонов проектирования для решения типичных проблем и улучшения повторного использования кода.
- Сценарии использования: Разработка сценариев использования, которые определяют, как пользователи будут взаимодействовать с системой.
- Производительность и масштабируемость: Решение вопросов производительности и способы масштабирования системы при необходимости.
- Безопасность: Включение мер безопасности в архитектуру для защиты от угроз и атак.
- Архитектура ПО играет важную роль в обеспечении эффективности, надежности, управляемости и поддерживаемости программных систем. Хорошо спроектированная архитектура облегчает разработку, тестирование и сопровождение ПО.
Простой пример архитектуры ПО
2. Архитектурный путь¶
Архитектурный путь - это организация и структурирование компонентов системы. Включает в себя логические уровни абстракции, модули, компоненты и пр. Здесь, и далее по проекту, является синонимом аббревиатуры CALMF (Contour->Application->Layer->Module->Funtion), структура проекта
Архитектурный путь представляет собой иерархию, которая помогает описать, как система организована и как компоненты взаимодействуют друг с другом.
-
Contour (КОНТУР): master Наивысший уровень архитектуры, описывающий общий контур или границы всего приложения. На этом уровне определяются общие принципы, требования и цели разрабатываемого программного продукта.
-
Application (ПРИЛОЖЕНИЕ): Desktop Этот уровень определяет основные компоненты приложения и их взаимодействие. Определяются области ответственности и основные функциональные блоки приложения.
-
Layer (СЛОЙ): Backend Уровень слоя относится к разделению приложения на логические слои, каждый из которых выполняет определенные функции. Например, это может быть слой доступа к данным, бизнес-логики, представления и т.д.
-
Module (МОДУЛЬ): library.database На этом уровне происходит декомпозиция слоев на более мелкие модули. Модуль - это логически связанный набор функций, отвечающий за определенный аспект системы. Это может включать в себя отдельные компоненты, классы или файлы.
-
Function (ФУНКЦИЯ): query Этот уровень представляет собой конечные функции или методы, реализующие конкретные задачи внутри модуля. Функции могут быть описаны в терминах входных данных, выходных данных и выполняемой логики.
Иерархия представлена следующим образом:
Contour ->Application ->Layer ->Module ->Function
Каждый уровень в этой иерархии представляет собой абстракцию, которая уточняется по мере продвижения вниз по пути. Эта структура позволяет разработчикам лучше понимать, организовывать код и локализовывать проблемы "до точки".
Данный подход обеспечивает четкое разделение ответственности и упрощает сопровождение и расширение программного продукта в виде автоматических задач, статистических сводок, уведомлений
3. Примеры организации архитектуры¶
Возьмем типовую функцию авторизации. Допустим, функционал авторизации расположен в 3 слоях: Backend, Frontend, Database, и все слои разрабатывают 3 отдельных программиста.
Каждый из них в своей функции, отвечающей за авторизацию, отправляет 2 события в мониторинг с соответствующим TYPE_ID (Тип события)
- Звёздочкой отмечено, что тип события (TYPE_ID) должен быть соответствующий ситуации
Backend¶
Для разработчика архитектурный путь: Master -> MyApp -> Backend -> Auth -> SignIN
| Контур | Приложение | Слой | Модуль | Функция | Тип события |
|---|---|---|---|---|---|
| Master | MyApp | Backend | Auth | SignIN | start |
| Master | MyApp | Backend | Auth | SignIN | finish * |
Frontend¶
Для разработчика архитектурный путь: Master -> MyApp -> Frontend -> AuthForm -> SignIN
| Контур | Приложение | Слой | Модуль | Функция | Тип события |
|---|---|---|---|---|---|
| Master | MyApp | Frontend | AuthForm | SignIN | start |
| Master | MyApp | Frontend | AuthForm | SignIN | finish * |
Database¶
Для разработчика архитектурный путь: Master -> MyApp -> Database -> Auth -> SignIN_Routine
| Контур | Приложение | Слой | Модуль | Функция | Тип события |
|---|---|---|---|---|---|
| Master | MyApp | Database | Auth | SignIN_Routine | start |
| Master | MyApp | Database | Auth | SignIN_Routine | finish * |
После того, как разработчик покроет этими метками код, любой пользователь системы выполняет сценария, и мы получаем статистику в виде 6 инцидентов (3 парных jobID с типами событий start-finish) для одного Контура и Приложения.
Эта информация дает нам понимание в цифрах: * работает ли заявленный разработчиком функционал корректно или нет * как давно он появился, сколько раз к нему обращались и какую нагрузку на него создают в любом разрезе времени * формируется структура проекта в автоматическом режиме * позволяет анализировать архитектурную схему, прогнозировать и моделировать ситуации * отправляет уведомления в чаты и создает автоматические задачи по принципу SMART
4. Транзакция¶
Транзакция - это 2 события одного jobID. Данный подход увеличивает трафик, но, мы получаем объективную исчерпывающую информацию о жизнедеятельности ПО: фактическое\среднее время выполнения функций, количество запросов функции за отчетный период (её востребованность), архитектурный путь и нагрузку на архитектурные слои.
Сформированный запрос должен пройти одну из цепочек бизнес-процесса.
4.1 Нормальная транзакция¶
Каждая функция архитектурного пути наблюдаемого кода покрывается метками c одним jobID дважды (далее, 2 состояния), тем самым, образуя нормальную транзакцию, состоящую из 2-х состояний: start и finish.
Первое состояние jobID: TYPE_ID=start
Второе состояние jobID: TYPE_ID=finish
4.2 Ошибочная транзакция (Инцидент)¶
Ошибочная транзакция или Инцидент - это транзакция из 2-х состояний, второе состояние которой не finish.
В момент запуска функции отправляем TYPE_ID=start. Если программист ведет свой учет jobID, то на старт его можно передать на старте транзакции. Все последующие операции для этого jobID будут выполняться планово. Если не введет - jobID будет сгенерирован и возвращен. Далее, его необходимо указывать для второго состояния.
В момент финиша или исключительной ситуации отправляем второе состояние TYPE_ID=finish, TYPE_ID=error, TYPE_ID=token, etc.
Второе состояние этого же jobID не равно finish. Т.е., второе состояние - это TYPE_ID=error [token, connect, etc.]
4.3 Аномальная транзакция¶
Если у транзакции меньше или больше 2-х состояний - она считается аномальной транзакцией
Количество инцидентов с одним jobID не равно 2!
Например, если норма = пара jobID: start->finish, то, аномалией считается следующее:
- только одна запись jobID
- более 2-х разных TYPE_ID для одного jobID
- 2 одинаковых TYPE_ID для одного jobID
4.4 Генерация ключей¶
Принцип алгоритма формирования ключей на примере jobID в LC.Мониторинг
5. Ключ операции (SERVER_KEY)¶
Данный ключ выдается администрацией LC.Мониторинг по запросу. Им "пдописывается" каждый запрос к серверу
Подробнее о SERVER_KEY
6. Тип события (TYPE_ID)¶
TYPE_ID или тип события - это одно из предусмотренных базовых значений:
events_dictionary = {
"start": {"title": "Успешный старт", "url": "[ICONS_FOLDER]/start.png"},
"finish": {"title": "Успешный финиш", "url": "[ICONS_FOLDER]/finish.png"},
"error": {"title": "Ошибка", "url": "[ICONS_FOLDER]/error.png"},
"security": {"title": "Ошибка безопасности", "url": "[ICONS_FOLDER]/security.png"},
"warning": {"title": "Предупреждение", "url": "[ICONS_FOLDER]/warning.png"},
"alert": {"title": "Уведомление", "url": "[ICONS_FOLDER]/alert.png"},
"process": {"title": "В процессе", "url": "[ICONS_FOLDER]/process.png"},
"longtime": {"title": "Долгое время работы", "url": "[ICONS_FOLDER]/longtime.png"},
"html": {"title": "Ошибка HTML или JS", "url": "[ICONS_FOLDER]/html.png"},
"connect": {"title": "Ошибка интеграционной шины", "url": "[ICONS_FOLDER]/connect.png"},
"zabbix": {"title": "Ошибка инфраструктуры", "url": "[ICONS_FOLDER]/zabbix.png"},
"token": {"title": "Ошибка просроченного\несуществующего токена", "url": "[ICONS_FOLDER]/token.png"},
}
При необходимости, список может быть расширен для конкретного клиента
7. Получатель сообщения (HOOK_ID)¶
HOOK_ID - это идентификатор чата в Битрикс24 (возможна урезанная версия оповещений в Telegram-бот).
В случае, если у Вас еще нет Битрикс24, то как партнёр 1С-Битрикс, рекомендуем зарегистрировать бесплатную версию и начать
Нам не потребуется никаких специфических знаний в программировании, чтобы выполнить подключение к групповому чату портала.
Ниже видеоскрин с последовательностью действий для создания и получения WEBHOOK в Битрикс24
Теперь нам нужно получить идентификатор группового чата, который будет принимать сообщения:
После того, как мы подготовили webhook и создали нужный нам чат на стороне Битрикс24, можем отправить в него тестовое сообщение
Приведен пример кода на Python
import json
from bitrix24 import Bitrix24
# URL для вашего Bitrix24 REST API инициализируется
url = '[BITRIX_WEBHOOK_URL]]'
# Настройки для отправки сообщения
settings = {
'method': 'im.message.add',
'hook_id': '[HOOK_ID]',
'message': 'Какое-то тестовое сообщение'
}
# Инициализация объекта Bitrix24 с использованием предоставленного URL
bx24 = Bitrix24(url)
# Функция для отправки сообщения
def send_message(settings):
# Используем метод callMethod из экземпляра Bitrix24
result = bx24.callMethod(settings["method"],
DIALOG_ID=settings["hook_id"],
MESSAGE=settings["message"])
# Раскомментируйте строку ниже, если хотите видеть результат в выводе
# print(f'result: {result}')
if not result:
result = False
return result
# Вызов функции для отправки сообщения при запуске скрипта
if __name__ == '__main__':
# Преобразование результата в строку перед использованием json.loads
result_str = json.dumps(send_message(settings))
print(json.loads(result_str))
8. Задание (jobID)¶
Уникальный идентификатор задания (jobID), представляет собой уникальное значение или метку, присвоенное определенному заданию внутри транзакции (job) или операции в системе.
Этот идентификатор обычно используется для однозначного определения конкретной задачи или операции среди других.
В контексте заданий (jobs) в программировании или информационных системах, jobID может использоваться для отслеживания выполнения определенного задания, присвоения статусов, управления зависимостями между заданиями и т. д.
В применении к информационным системам, базам данных или другим системам учета и мониторинга, jobID может быть уникальным идентификатором для конкретного процесса, операции или записи в системе.
Основная идея заключается в том, что jobID предоставляет средство однозначной идентификации и отслеживания конкретного элемента в системе, облегчая управление и мониторинг задач или операций.
Например:
Транзакция ID: XYZ
- jobID для События 1: TYPE_ID=start
- jobID для События 2: TYPE_ID=finish // или иное состояние TYPE_ID
Рекомендуемый алгоритм генерации jobID для контроля на стороне разработчиков клиента
import time
import random
import string
def generate_random_string():
current_microtime = str(int(time.time() * 1e6))
random_suffix = ''.join(random.choices(string.ascii_letters + string.digits, k=32 - len(current_microtime)))
random_string = current_microtime + random_suffix
return random_string
# Пример использования
random_string = generate_random_string()
print(random_string)
9. Автозадачи¶
Адтозадача или автоматическая задача - это задача, которая создается сервисом LC.Мониторинг по результатам анализа ситуации, в нужную группу, с нужным количеством участников; назначается ответственный и сроки выполнения.
Мы придерживаемся структурированных задач, поэтому, используем подход SMART при создании всех автоматических задач.
Автозадачи делятся на 3 типа: прямые (или просто автозадачи), реверс-задачи, автопоручения.
План "прямой" автозадачи выглядит следующим образом: Название: Исправить функцию "get" :: Тип события: "vista3". Событий: (3) на 2023-12-19 19:21:02 Описание (тело) задачи: Уникальный идентификатор группы задач: 9F89A6C0AEE734F4400F10D7E6AF732D Specific (Конкретная): - Количество однотипных инцидентов - Архитектурный путь Measurable (Измеримая): ToDo - лист с конкретным сценарием исполнения - Провести анализ списка jobID идентификаторов (список jobID) - Установить пользователя, связаться, уточнить детали (список пользователей) и т.п.
Achievable (Достижимая): Технический план действий для 2+ линии СТП, согласно SLA
Relevant (Актуальная): Краткая сводка по инциденту в подобном виде:
Количество событий: 3
Пользователей МИС: 1
Пользователей ПК: 1
Появление инцидента: 2023-12-19 22:20:52
Последний инцидент: 2023-12-19 22:20:53
Общая длительность: 00:00:01
Time-Framed (Определенная во времени):
Технический план действий для 1, 2 линии СТП, тимлида и руководителя проекта, согласно SLA
План реверс-задачи аналогичен, т.к. стандартизирован по SMART и не требует изменений
Автозадачи создаются автоматически, по результатам анализа базы за последнюю минуту, если инцидентов > 2, contour > master. Если автозадача уже есть и она в стадии "Требует проверки" или "Завершена", а количество инцидентов изменилось, задача будет возобновлена.
Реверс-задачи создаются автоматически, по результатам анализа базы за последнюю минуту, если инцидентов > 0, contour = master. Возобновление реверс-задачи аналогично автозадаче
Автопоручения загружаются вручную в виде предзаполненного шаблона XLSX
9.1 taskCode¶
taskCode - это производная от архитектурного пути и TYPE_ID. Пример, 9F89A6C0AEE734F4400F10D7E6AF732D. Состоит из CALMF + тип события. Данный код вычисляется средствами СУБД. Данный код уникален. Он необходим для создания и контроля задачи по этому коду в Битрикс24.
Данные задачи следует считать техническим долгом разработчиков перед клиентом. Для подобных задач создается отдельная группа (проект\скрам) "Технический долг"
Алгоритм создания автозадачи:
- если TYPE_ID не равно start или finish, и количество событий больше 2-х (настраивается), то берем код автозадачи (taskCode)
- проверяем taskCode в задачах Битрикс24
9.2 taskID¶
Уникальный цифровой идентификатор с номером задачи из Битрикс24
9.3 reverse taskCode¶
То же самое, что и автозадача, только из другого хранилища, в котором собираются данные о неудачных запросах из отдельного чата "Работа Мониторинга", в который отправляем запрос напрямую, если LC.Мониторинг недоступен
Данные задачи следует считать ошибками, которые допустили разработчики при покрытии своего кода мониторингом. Для подобных задач создается отдельная группа (проект\скрам), например: "Реверс-события Мониторинга"
9.4 reverse_taskID¶
То же самое, что и taskID, но для реверс-задачи