Обновление
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Struchkov Mark
2025-02-25 21:32:31 +03:00
parent 58127ccecd
commit ee66c043b8
23 changed files with 931 additions and 10 deletions

View File

@@ -17,7 +17,7 @@ steps:
- name: build site
# https://hub.docker.com/r/library/docker
pull: always
image: docker.struchkov.dev/quartz:develop
image: docker.struchkov.dev/quartz:v.4.4.7
environment:
GITHUB_SSH:
from_secret: GITHUB_SSH
@@ -66,6 +66,6 @@ steps:
# drone sign --save upagge/digital-garden
---
kind: signature
hmac: 136d4effa27f318fb6ff0cf16bc1bf7b20b428610832f7bdd8224c164a804e69
hmac: fd5326b43706588aa4b35e24e551954df3dba6fc88e94c462ab91b9384ba0d6d
...

View File

@@ -0,0 +1,39 @@
---
aliases:
- MDC
tags:
- maturity/🌱
date: 2025-02-24
---
MDC — это структура данных, основанная на концепции ThreadLocal, которая позволяет привязать набор ключ-значение к текущему [[fundamental/Поток процесса ОС|потоку]] выполнения. Это значит, что для каждого потока можно задать свой уникальный контекст, который автоматически будет включаться в записи лога.
Например, с помощью MDC можно добавить в лог идентификатор запроса, информацию о пользователе или данные сессии. Эти данные впоследствии помогают отследить цепочку событий, относящихся к одному запросу или сессии, что значительно упрощает диагностику и анализ работы приложения.
**Зачем нужен MDC**
- **Улучшение отладки и мониторинга:** Благодаря MDC в каждом сообщении лога оказывается дополнительная информация (например, request ID, user ID). Это помогает быстро сопоставить связанные события и понять, как обрабатывается конкретный запрос.
- **Анализ в распределённых системах:** В [[../../../wiki/zero/00 Микросервисная архитектура|микросервисных архитектурах]] запрос может проходить через несколько сервисов. Использование MDC позволяет передавать и сохранять идентификаторы на протяжении всей цепочки вызовов, что существенно упрощает трассировку.
- **Фильтрация и поиск логов:** С дополнительными метаданными логи становятся более структурированными. Это позволяет фильтровать и искать конкретные записи по значимым атрибутам, ускоряя процесс анализа инцидентов.
**Основные возможности MDC**
- **Добавление контекста:** С помощью методов вроде `MDC.put(key, value)` можно установить необходимые данные, которые автоматически добавляются в каждую запись лога, если логгер настроен на их отображение.
- **Получение и удаление контекста:** Методы `MDC.get(key)` и `MDC.remove(key)` позволяют получить или удалить конкретное значение, что важно для избежания утечек данных при повторном использовании потоков.
- **Автоматическая интеграция с логгерами:** Многие современные логирующие библиотеки, такие как Logback, Log4j или SLF4J, имеют встроенную поддержку MDC. Это позволяет легко настраивать формат логов так, чтобы он автоматически включал информацию из MDC.
**Ограничения и нюансы использования**
- **Привязка к потоку:** Поскольку MDC реализован через ThreadLocal, его данные по умолчанию привязаны к конкретному потоку. В асинхронных и реактивных системах, где управление потоками осуществляется динамически, может возникать необходимость вручную переносить данные MDC между потоками.
- [[java/quarkus/Обеспечение корректного асинхронного выполнения в Quarkus|Обеспечение корректного асинхронного выполнения в Quarkus]]
- **Ручное управление:** Чтобы избежать ошибок и утечек информации, рекомендуется всегда очищать MDC после завершения обработки запроса, например, с помощью конструкции `try-finally`.
***
## Мета информация
**Область**:: [[../meta/zero/00 Разработка|00 Разработка]]
**Родитель**::
**Источник**::
**Создана**:: [[2025-02-24]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

32
dev/NanoId.md Normal file
View File

@@ -0,0 +1,32 @@
---
aliases:
tags:
- maturity/🌱
date: 2024-10-30
---
NanoID — это генератор уникальных [[Идентификатор сущности|идентификаторов]], разработанный как альтернатива [[Universal Unique IDentifier|UUID]]. Он отличается компактностью, высокой скоростью генерации и повышенной криптографической стойкостью. Идентификаторы, созданные с помощью NanoID, используют алфавит из безопасных символов и могут быть настроены по длине.
**Основные характеристики NanoID**
- Компактность. По умолчанию NanoID генерирует идентификаторы длиной 21 символ, что делает их короче UUID (36 символов) при схожем уровне уникальности.
- Высокая скорость. Генерация NanoID происходит быстрее, чем UUID, поскольку использует оптимизированные алгоритмы и не требует сложных вычислений.
- Криптографическая стойкость. В отличие от некоторых других генераторов идентификаторов, NanoID использует криптографически безопасный генератор случайных чисел, что делает его подходящим для задач, где важна защита от предсказуемости.
- Настраиваемость. Можно изменить алфавит и длину идентификаторов в зависимости от требований системы.
NanoID идеально подходит для:
- Генерации идентификаторов в веб-приложениях и API.
- Создания ссылок с короткими, но уникальными значениями.
- Использования в системах, где важна производительность и компактность.
- Обеспечения защиты от предсказуемости идентификаторов.
***
## Мета информация
**Область**:: [[../meta/zero/00 Разработка|00 Разработка]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-10-30]]
**Автор**::
### Дополнительные материалы
- Порт для Java [GitHub - aventrix/jnanoid: A unique string ID generator for Java.](https://github.com/aventrix/jnanoid)
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -0,0 +1,31 @@
---
aliases:
- TSID
tags:
- maturity/🌱
date: 2024-10-30
---
TSID (Time-Sorted Identifier) — это тип уникального [[Идентификатор сущности|идентификатора]], который генерируется так, чтобы его можно было сортировать по времени создания. Он сочетает временную метку с дополнительными компонентами, обеспечивающими уникальность, что делает его особенно полезным для распределённых систем и [[../meta/zero/00 HighLoad|высоконагруженных приложений]].
**Основные характеристики TSID:**
- Уникальность. Гарантирует отсутствие коллизий, даже при высокой скорости генерации и в распределённых средах.
- Сортируемость по времени. Временная компонента в структуре TSID позволяет автоматически упорядочивать идентификаторы в хронологическом порядке, упрощая работу с базами данных и логами.
- Компактность. В отличие от [[Universal Unique IDentifier|UUID]], TSID занимает меньше места, что снижает нагрузку на хранилище и каналы передачи данных.
- Высокая производительность. Генерация TSID происходит быстро и не требует централизованного сервера, что делает этот тип идентификаторов эффективным для масштабируемых систем.
**Альтернативы TSID:**
- [[Universal Unique IDentifier|Universal Unique IDentifier]] — широко используемый уникальный идентификатор, но не гарантирует временную сортируемость.
- [[NanoId]] — компактный идентификатор, генерируемый случайным образом, но без встроенной поддержки сортировки по времени.
***
## Мета информация
**Область**:: [[../meta/zero/00 Разработка|00 Разработка]]
**Родитель**:: [[Идентификатор сущности]]
**Источник**::
**Создана**:: [[2024-10-30]]
**Автор**::
### Дополнительные материалы
- [The best UUID type for a database Primary Key - Vlad Mihalcea](https://vladmihalcea.com/uuid-database-primary-key/)
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -4,9 +4,6 @@ aliases:
tags:
- maturity/🌱
date: 2023-11-12
zero-link:
parents:
linked:
---
**UUID (Universal Unique IDentifier)** — это 128-битный идентификатор, представленный в виде строки. Однако для пользовательских данных доступно только 122 бита, так как 6 бит зарезервировано:
- 4 бита используются для указания версии UUID;
@@ -135,13 +132,13 @@ UUID V7 может иметь несколько типов генерации,
***
## Мета информация
**Область**:: [[../meta/zero/00 Разработка|00 Разработка]]
**Родитель**::
**Родитель**:: [[Идентификатор сущности|Идентификатор сущности]]
**Источник**::
**Автор**::
**Создана**:: [[2023-11-12]]
### Дополнительные материалы
- [ID-баттл: UUID vs автоинкремент / Валентин Удальцов - YouTube](https://www.youtube.com/watch?v=Xr_SNd9LIng&t=1762s)
- [Библиотека для генерации UUID в Java. Все версии](https://github.com/f4b6a3/uuid-creator)
- [[../../../_inbox/Автоинкремент|Автоинкремент]]
- [[database/other/Автоинкремент в БД|Автоинкремент в БД]]
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -0,0 +1,51 @@
---
aliases:
- автоинкремент
- sequence
tags:
- maturity/🌱
date: 2025-02-18
---
Автоинкремент — это механизм [[../../../meta/zero/00 Реляционная база данных|баз данных]], который автоматически увеличивает значение числового идентификатора при добавлении новой записи. Обычно он используется для генерации уникальных первичных ключей.
Для работы автоинкремента ==требуется место, где хранится последнее сгенерированное значение.== В разных СУБД это может быть реализовано через:
- **Sequences** (например, `CREATE SEQUENCE` в PostgreSQL, Oracle);
- **Auto-increment fields** (например, `AUTO_INCREMENT` в MySQL, `IDENTITY` в SQL Server);
- **Таблицы-счетчики** (редко используемый способ, если СУБД не поддерживает автоинкремент напрямую).
При добавлении новой строки в таблицу БД получает следующее доступное значение из последовательности или автоинкрементного счетчика и использует его как идентификатор.
**Плюсы автоинкремента**
- **Сортируемость**. Поскольку значения увеличиваются последовательно, записи автоматически упорядочиваются по времени вставки.
- **Легко читаемый и запоминаемый**. Числовые идентификаторы проще воспринимать, чем длинные [[../../Universal Unique IDentifier|UUID]].
- **Оптимизация индексов**. Последовательные ключи могут работать быстрее в [[../Индекс базы данных|индексах]], поскольку новые данные добавляются в конец индекса, а не в случайные позиции (актуально для [[../../fundamental/structure/B-tree|B-деревьев]]).
- **Проще отлаживать**. В логах легче сопоставлять записи с их идентификаторами.
**Минусы автоинкремента**
- **Можно предсказать количество записей**. Последовательные идентификаторы позволяют злоумышленникам оценить активность системы, например, количество заказов в интернет-магазине.
- **Легкость перебора записей**. Зная один идентификатор, можно предполагать другие и пытаться получать не авторизованные данные.
- **Конечный диапазон значений**. У каждого типа данных есть границы (например, `BIGINT` в PostgreSQL поддерживает максимум `9,223,372,036,854,775,807` записей).
- **Не хранит дополнительную информацию**. В отличие от UUID, автоинкрементные идентификаторы не содержат метаданных, например, о времени создания или сервере, который их сгенерировал.
Если необходимо скрыть количество записей или усложнить перебор ID, можно использовать:
- [[../../Universal Unique IDentifier|UUID]]. Позволяет избежать предсказуемости, но увеличивает размер индексов.
- **Случайные ID**. Вместо автоинкремента можно генерировать случайные числа.
- **Маскирование ID**. Например, через хеширование (`SHA-256`) или кодирование (`Base62`).
- **Salted-ключи**. Добавление уникального префикса к числам (например, `ORD-1001`).
### Преобразование автоинкремента в UUID
![](../../../meta/files/images/Pasted%20image%2020231112135724.png)
***
## Мета информация
**Область**:: [[../../../meta/zero/00 Разработка|00 Разработка]]
**Родитель**:: [[../../Идентификатор сущности|Идентификатор сущности]]
**Источник**::
**Создана**:: [[2025-02-18]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -0,0 +1,108 @@
---
aliases:
tags:
- maturity/🌱
date: 2025-02-18
---
В этой заметке описывается процесс миграции с [[../../Universal Unique IDentifier|UUID]] на [[Автоинкремент в БД]]
Подготовка и анализ зависимостей
- Нет ли в других таблицах внешних ключей (FK), ссылающихся на старую колонку UUID.
- Проверьте код приложения, API, скрипты: не используют ли они явным образом старый тип ключа или его формат.
Создание нового столбца
- Создайте новую колонку с типом `BIGINT` (или `BIGSERIAL`, если используете PostgreSQL).
- Если требуется, создайте последовательность:
```sql
CREATE SEQUENCE your_table_id_seq;
```
Назначьте этой колонке `DEFAULT`, чтобы при вставке новых данных значение генерировалось автоматически:
```sql
ALTER TABLE your_table
ALTER COLUMN temp_id SET DEFAULT nextval('your_table_id_seq');
```
Сделайте колонку `NOT NULL` (если уверены, что в ней не должно быть пропусков):
```sql
ALTER TABLE your_table
ALTER COLUMN temp_id SET NOT NULL;
```
Заполнение новой колонки (бэкфил). Обновите существующие записи, чтобы у каждой строки появилось уникальное значение:
```sql
UPDATE your_table
SET temp_id = nextval('your_table_id_seq');
```
> [!WARNING]
> Если важен порядок (например, по дате создания), можно использовать более сложный запрос с сортировкой.
Переключение на новый ключ
- Удалите внешние ключи, если они указывали на старую колонку-ключ.
- Удалите или переименуйте старую колонку:
```sql
ALTER TABLE your_table DROP COLUMN old_uuid_column;
```
или:
```sql
ALTER TABLE your_table RENAME COLUMN old_uuid_column TO uuid_backup;
```
Переименуйте `temp_id` в `id`:
```sql
ALTER TABLE your_table
RENAME COLUMN temp_id TO id;
```
Добавьте первичный ключ:
```sql
ALTER TABLE your_table
ADD CONSTRAINT your_table_pkey PRIMARY KEY (id);
```
- Если были внешние ключи, которые ссылаются на старый UUID, обновите их или добавьте новые, ссылающиеся на новую колонку.
- Проверьте код приложения: там, где раньше ожидался UUID, теперь будет число. При необходимости скорректируйте схемы, DTO, сервисы и т. п.
### Пример миграции с Liquibase
Добавление нового столбца с автоинкрементом
```xml
<changeSet id="1" author="dev">
<addColumn tableName="your_table">
<column name="temp_id" type="BIGINT" autoIncrement="true"/>
</addColumn>
</changeSet>
```
Заполнение нового столбца значениями
```xml
<changeSet id="2" author="dev">
<sql>UPDATE your_table SET temp_id = nextval('your_table_id_seq');</sql>
</changeSet>
```
Удаление старого UUID и установка нового первичного ключа
```xml
<changeSet id="3" author="dev">
<dropPrimaryKey tableName="your_table" constraintName="your_table_pkey"/>
<dropColumn tableName="your_table" columnName="old_uuid_column"/>
<renameColumn tableName="your_table" oldColumnName="temp_id" newColumnName="id"/>
<addPrimaryKey tableName="your_table" columnNames="id" constraintName="your_table_pkey"/>
</changeSet>
```
***
## Мета информация
**Область**:: [[../../../meta/zero/00 Реляционная база данных|00 Реляционная база данных]]
**Родитель**::
**Источник**::
**Создана**:: [[2025-02-18]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -5,6 +5,7 @@ aliases:
- индексы
- индексирования
- индекса
- индексах
tags:
- maturity/🌱
date: 2024-10-11

View File

@@ -0,0 +1,27 @@
---
aliases:
- самодиагностику Gitea
tags:
- maturity/🌱
date: 2025-02-05
---
```shell
gitea doctor check
```
```shell
docker exec -it gitea su git -c "gitea doctor check"
```
***
## Мета информация
**Область**:: [[../../../meta/zero/00 Gitea|00 Gitea]]
**Родитель**::
**Источник**::
**Создана**:: [[2025-02-05]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -0,0 +1,80 @@
---
aliases:
tags:
- maturity/🌱
- content/problem
date: 2025-02-04
---
В какой-то момент я обнаружил, что мой сервер (Процессор: 2 core  Память: 4 Gb  Хранилище: 60 Gb) на котором запущена Gitea стал потреблять много ресурсов.
```
top -o %CPU -b -n 1 | head -20
```
Cудя по top, основным потребителем CPU является Gitea, которая занимает 22,7% CPU и использует 61,6% оперативной памяти. Также увидел несколько активных процессов git, которые могут быть вызваны Gitea для обработки репозиториев, и они тоже нагружают CPU.
Следующим шагом я проверил логи контейнера
```
docker logs --tail 50 gitea
```
По логам увидел, что у меня много **медленных запросов (slow GET)**, связанных с:
1. Обработкой коммитов и blame (история изменений файлов)
2. Доступом к файлам в репозиториях
3. Работой с RSS и raw-файлами
4. Запросами на поиск и скачивание контента
Кроме того, встречались 404-ошибки, которые могут указывать на частые обращения к несуществующим ресурсам.
Далее я проверил активные процессы Gitea
```
docker exec -it gitea top -b -n 1
```
Gitea активно выполняла много процессов Git, связанных с read-tree, rev-list, cat-file, check-attr и batch-check. Это говорило о том, что Gitea либо индексирует файлы, либо выполняет операции, связанные с доступом к репозиториям:
- read-tree → Чтение структуры репозитория.
- log -1 → Получение последнего коммита для файла.
- cat-file --batch → Доступ к содержимому файлов.
Это может быть вызвано:
1. [[Фоновые задачи Gitea|Фоновыми задачи Gitea]].
2. **Запросами от пользователей** — если кто-то активно использует Gitea через UI. Но у меня персональный Git хостинг, никто кроме меня им не пользуется.
3. **Запросы от ботов** - какие-нибудь парсеры, особенно если пользователей в Gitea не много.
4. **Webhooks или интеграциями** — если какие-то сервисы взаимодействуют с Gitea. Интеграция у меня была только с Drone CI, которая вряд ли может создавать такую нагрузку.
Перед дальнейшими действиям, я решил провести [[Автоматическая диагностика в Gitea|самодиагностику Gitea]]. Но все проверки были успешно пройдены.
## Отключение переодических задач
Я решил, что проблема в [[Фоновые задачи Gitea|фоновых задачах Gitea]]. Тем более, что у меня было много репозиториев зеркал, которые стягивались с GitHub. Так что мой следующий шаг: Проверить фоновые задачи в Gitea. Это можно сделать или запросом, или через панель управления в UI.
```
curl -X GET "http://localhost:3000/api/v1/admin/cron" -H "Authorization: token YOUR_ACCESS_TOKEN"
```
Далее я отключил сначала все фоновые задачи и оставил только важные. И на первый взгляд показалось, что это помогло.
Однако спустя час Gitea снова потребляла CPU (41,2%) и память (13,7%). Кроме того, снова был запущен процесс git (17,6% CPU), что говорило о том, что Gitea выполняет какие-то операции с репозиториями. Хотя пользователей в это время не было.
## Запросы от ботов
Как я уже говорил это мой персональный публичный Git хостинг, так что им пользуюсь только я. Но он публичный, и я предположил, что возможно какие-то парсеры могут постоянно сканировать репозитории, например в надежде получить какие-нибудь случайно опубликованные ключи доступа.
Я решил проверить эту гипотезу.
***
## Мета информация
**Область**:: [[../../../meta/zero/00 Gitea|00 Gitea]]
**Родитель**::
**Источник**::
**Создана**:: [[2025-02-04]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -0,0 +1,68 @@
---
aliases:
tags:
- maturity/🌱
date: 2025-02-05
---
Это команда покажет, какие операции в Gitea происходят чаще всего за последние 8 часов.
```shell
docker logs gitea --since "8h" | grep "router: completed GET" | awk '{print $NF}' | sort | uniq -c | sort -nr | head -20
```
Пример вывода:
```
grep: (стандартный ввод): двоичный файл совпадает
6933 repo/view_home.go:314(repo.Home)
1332 repo/commit.go:44(repo.RefCommits)
860 <autogenerated>:1(WebNotFound)
824 repo/download.go:111(repo.SingleDownload)
805 repo/blame.go:42(repo.RefBlame)
531 context/repo.go:401(context.RepoAssignment)
88 repo/issue_list.go:750(repo.Issues)
56 repo/commit.go:279(repo.Diff)
23 repo/commit.go:410(repo.RawDiff)
21 auth/auth.go:179(auth.SignIn)
9 repo/download.go:123(repo.SingleDownloadOrLFS)
9 feed/render.go:11(feed.RenderBranchFeed)
7 repo/milestone.go:244(repo.MilestoneIssuesAndPulls)
6 misc/misc.go:36(misc.RobotsTxt)
5 repo/find.go:19(repo.FindFiles)
4 repo/compare.go:708(repo.CompareDiff)
3 repo/milestone.go:34(repo.Milestones)
1 web/goget.go:20(web.goGet)
1 repo/treelist.go:17(repo.TreeList)
1 repo/repo.go:469(repo.Download)
```
- **repo/view_home.go:314(repo.Home) → 6933 запросов**
- Главная страница репозитория (обзор файлов, README).
- Может быть вызвано частым обновлением страниц пользователями или ботами.
- **repo/commit.go:44(repo.RefCommits) → 1332 запросов**
- Просмотр списка коммитов в репозитории.
- Может быть вызвано активной работой разработчиков или парсерами.
- **\<autogenerated\>:1(WebNotFound) → 860 ошибок 404**
- Кто-то (или что-то) запрашивает несуществующие страницы.
- Возможные причины:
- Боты, сканирующие сайт (поиск уязвимостей).
- Пользователи, переходящие по несуществующим ссылкам.
- Неправильные ссылки в коде (например, старые или сломанные URL).
- **repo/download.go:111(repo.SingleDownload) → 824 запросов**
- Загрузка файлов из репозитория.
- Если это **LFS-файлы**, то они могут быть **очень большими**, что увеличивает нагрузку на CPU и сеть.
- **repo/blame.go:42(repo.RefBlame) → 805 запросов**
- Просмотр истории изменений в файле (git blame).
- Очень тяжёлая операция, особенно для больших файлов.
***
## Мета информация
**Область**::
**Родитель**::
**Источник**::
**Создана**:: [[2025-02-05]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -0,0 +1,90 @@
---
aliases:
tags:
- maturity/🌱
date: 2025-02-04
---
Вот список основных задач (cron-задач), которые Gitea выполняет по расписанию:
### Задача `start_schedule_tasks`
Задача `start_schedule_tasks` в Gitea отвечает за **запуск всех запланированных фоновых задач**, которые должны выполняться через определенные интервалы времени. Она запускается **каждую минуту**.
### Задача `update_mirrors`
- Проверяет обновления в зеркалах (mirror repositories) и синхронизирует их.
- Если у тебя есть зеркала репозиториев, теперь они не будут автоматически обновляться.
### Задача `repo_health_check`
- Проверяет репозитории на повреждения (например, отсутствующие файлы или некорректные коммиты).
- Если репозитории работают стабильно, проблем не будет, но в долгосрочной перспективе могут появиться “битые” репозитории, если что-то сломается.
### Задача `check_repo_stats`
- Пересчитывает количество коммитов, изменений, контрибьюторов.
### Задача `archive_cleanup`
- Удаляет временные архивы (.zip, .tar.gz), созданные при скачивании репозиториев.
- Без этой задачи дисковое пространство может постепенно заполняться ненужными файлами.
### Задача `deleted_branches_cleanup`
- Удаляет метаданные о ветках, которые были удалены.
- Без этой задачи дисковое пространство может постепенно заполняться ненужными файлами.
### Задача `cleanup_packages`
- Очищает устаревшие пакеты из Gitea Package Registry.
- Если ты используешь Gitea для хранения артефактов (например, Docker-образов, Maven-пакетов), они могут оставаться в системе навсегда.
### Задачи `stop_zombie_tasks` и `stop_endless_tasks`
- Останавливает фоновые задачи, которые зависли или выполняются бесконечно.
- Если в Gitea зависнет процесс (например, Git-команда или индексация), он может остаться активным навсегда и жрать ресурсы.
### Задача `cleanup_hook_task_table`
- Удаляет старые уведомления о системных событиях.
- Если у тебя много пользователей, база данных может расти из-за ненужных логов.
### Задача `git_gc_repos`
- Запускает git gc (сборщик мусора) для репозиториев, чтобы оптимизировать их размер.
- Если ты часто пушишь большие файлы, размер репозиториев может расти быстрее, чем обычно.
### Задача `gc_lfs`
- Удаляет устаревшие файлы из Git LFS (если используется).
- Если у тебя включен Git LFS, репозитории могут занимать больше места, чем нужно.
## Включаем только важные задачи
Для экономии ресурсов процессора можно включить только важные задачи
```shell
nano /data/gitea/conf/app.ini
```
```toml
[cron]
ENABLED = false
[cron.cleanup_packages]
ENABLED = true
SCHEDULE = @midnight
[cron.archive_cleanup]
ENABLED = true
SCHEDULE = @midnight
[cron.deleted_branches_cleanup]
ENABLED = true
SCHEDULE = @midnight
[cron.cleanup_hook_task_table]
ENABLED = true
SCHEDULE = @midnight
[cron.git_gc_repos]
ENABLED = true
SCHEDULE = @midnight
```
```
docker restart gitea
```
***
## Мета информация
**Область**:: [[../../../meta/zero/00 Gitea|00 Gitea]]
**Родитель**::
**Источник**::
**Создана**:: [[2025-02-04]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -1,5 +1,8 @@
---
aliases:
aliases:
- сениор
- мидл
- джун
tags:
- maturity/🌱
date: 2024-10-22
@@ -29,7 +32,7 @@ date: 2024-10-22
Самостоятельность на уровне синьора максимальна. Он может работать как над конкретной задачей, так и принимать участие в стратегическом планировании проекта. В отличие от мидла, синьор способен не только реализовывать технические решения, но и формировать их на уровне концепций, выбирая наилучшие пути реализации. Для него важен результат, и он умеет находить пути его достижения с минимальными затратами времени и ресурсов.
***
## Мета информация
**Область**:: [[../meta/zero/00 Разработка|00 Разработка]]
**Область**:: [[../../meta/zero/00 Эффективная разработка|00 Эффективная разработка]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-10-22]]

View File

@@ -0,0 +1,58 @@
---
aliases:
tags:
- maturity/🌱
date: 2025-02-13
---
В каждом сервисе есть два ответственных: это обеспечивает баланс нагрузки, взаимный контроль, а также непрерывность работы в случае отсутствия одного из них. ==У каждого сервиса должны быть ответственные разработчики. В противном случае сервис превращается в "ничей" и становится легаси.==
- **Старший ответственный** — обладает правами maintainer-а, но при этом также проходит код-ревью. Обычно это [[Грейды разработчиков|сениор]] или крепкий [[Грейды разработчиков|мидл]].
- **Младший ответственный** — поддерживает основного ответственного и заменяет его в случае отсутствия. Обычно это [[Грейды разработчиков|джун]] или [[Грейды разработчиков|мидл]], который забирает на себя рутинные задачи и учится у своего старшего коллеги.
**Общие обязанности ответственных:**
- Заполнять [[Сhangelog изменений сервисов|changelog]] для всех изменений в сервисе.
- Проводить и участвовать в технических встречах для обсуждения текущего состояния, проблем и планов по развитию сервиса.
- Разрабатывать и поддерживать документацию сервиса.
**Обязанности старшего ответственного:**
- Обеспечивать техническую реализацию сервиса, включая разработку и исправление ошибок.
- Осуществлять основной технический контроль качества и проводить код-ревью.
- Консультировать другие команды по вопросам работы сервиса.
**Полномочия старшего ответственного:**
- В случае необходимости передавать код-ревью младшему ответственному.
- Мержить доработки в сервис после прохождения ревью
**Обязанности младшего ответственного:**
- Выполнять обязанности основного ответственного в его отсутствие.
- Помогать в проведении код-ревью.
- Участвовать в разработке и исправлении ошибок.
- Консультировать другие команды по вопросам работы сервиса.
**Контроль изменений в сервисе**
- Младший ответственный назначает на ревью старшего, старший — младшего.
- Если разработку выполняет не ответственный за сервис, то ревью проводит старший ответственный. Он может передать ревью младшему ответственному.
- Все изменения должны проходить код-ревью ответственных за сервис, чтобы избежать хаотичных доработок.
- В случае разногласий между старшим и младшим ответственными изменения обсуждаются с архитектором и/или техлидом.
**Процесс передачи ответственности**
- Если старший ответственный уходит из компании или переводится на другой проект, архитектор модуля определяет нового старшего ответственного. Это может быть назначение младшего на эту роль или поиск нового кандидата.
- До официального назначения нового старшего младший временно выполняет его обязанности.
- В системе должен быть актуальный список сервисов с указанием ответственных разработчиков.
**Принятие значительных изменений в архитектуре сервиса**
- Решения о значительных изменениях принимаются на технических обсуждениях с архитектором модуля.
- В качестве утверждающего органа выступает техлид и/или архитектор.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Эффективная разработка|00 Эффективная разработка]]
**Родитель**::
**Источник**::
**Создана**:: [[2025-02-13]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -0,0 +1,113 @@
---
aliases:
- changelog
tags:
- maturity/🌱
date: 2025-02-13
---
Changelog (журнал изменений) — это больше, чем просто список исправлений и новых фич. Это коммуникационный мост между разными участниками продуктовой команды и будущими версиями системы. Это способ зафиксировать эволюцию продукта, сделать его предсказуемым и понятным, а также избежать хаоса, который неизбежно наступает, когда изменения теряются в глубинах репозиториев или устных обсуждений.
Changelog — это структурированный журнал изменений в сервисе или продукте. Хороший сhangelog отвечает на три ключевых вопроса:
1. **Что изменилось?** (новые возможности, исправления, улучшения, депрекейшены)
2. **Почему это изменилось?** (какие проблемы решены, какие задачи стояли)
3. **Как это влияет на систему и пользователей?** (что нужно учесть при обновлении, есть ли [[../other/Backward compatibility|backward compatibility]])
**Зачем это нужно?**
- **Прозрачность**. Разработчики, DevOps-инженеры и даже пользователи должны понимать, что происходит с системой и как это влияет на их работу.
- **История развития**. Changelog фиксирует техническую эволюцию проекта и помогает анализировать причины изменений.
- Обратная совместимость. Понимание изменений помогает избежать неожиданных проблем при обновлении версий.
- **Взаимодействие с пользователями и заказчиками**. Хорошо написанный changelog упрощает адаптацию пользователей к новым версиям, а также служит маркетинговым инструментом, демонстрируя активное развитие продукта.
**Ограничения и возможные проблемы**
- **Слабая структура и хаос**. Если changelog ведется нерегулярно или его формат непоследователен, он теряет свою пользу.
- **Избыточность**. Если changelog превращается в поток технических подробностей, понятных только разработчикам, он перестает быть полезным.
- **Недостаточная детализация**. Формулировка «Исправлены баги» или «Улучшена производительность» не дает читателям никакой полезной информации.
**Типовая структура**
- **Изменения API**. Включает все изменения, влияющие на взаимодействие с внешними системами и пользователями API:
- Добавлено: новые эндпоинты, новые параметры запросов/ответов.
- Изменено: изменения контрактов API, изменения кодов ответов, обновление документации API.
- Удалено: устаревшие эндпоинты или версии API, удаленные параметры запросов/ответов.
- Введение новых ограничений (rate-limiting, авторизация и т. д.).
- **Изменения межсервисных взаимодействий**. Фиксируются изменения в том, какие сервисы вызывают друг друга и зачем. Сюда не включаются изменения API.
- Начали вызывать новый сервис.
- Перестали вызывать сервис
- Изменена схема вызова между сервисами
- billing теперь вызывается асинхронно через очередь вместо синхронного REST-запроса.
- **Изменения конфигураций**. Фиксирует изменения, влияющие на настройки системы:
- Новые переменные окружения.
- Изменение значений конфигурационных параметров.
- Введение новых фич-флагов.
- Изменения в форматах конфигурационных файлов.
- **Исправления багов**. Список устраненных проблем, влияющих на работу системы:
- Критические фиксы, вызывавшие падения или утечки памяти.
- Исправления в логике расчетов, валидации данных, обработке ошибок.
- Баги, связанные с интеграциями и совместимостью.
- Обновления зависимостей, исправляющие известные уязвимости.
- **Новый функционал**. В этом разделе фиксируются все новые возможности, которые появляются в системе:
- **Добавленные фичи**. Новые возможности, модули, крупные изменения в логике работы сервиса.
- **Новые сценарии использования**, появившиеся после обновления.
- **Поддержка новых технологий и интеграций**.
- **Технические изменения**. Изменения, которые не влияют напрямую на API, но важны для работы системы:
- Оптимизация алгоритмов и производительности.
- Рефакторинг кода и переработка архитектуры.
- Улучшение логирования (новые уровни логов, новые метрики).
- Обновления зависимостей.
- Изменения в CI/CD, механизме деплоя, мониторинге.
- **Устаревшие функции**. Функциональность, которая будет удалена в будущем, с указанием сроков и альтернатив:
- Устаревшие API и их замены.
- Удаляемые конфигурационные параметры.
- Фичи, которые больше не поддерживаются.
- **Действия при обновлении**. Что необходимо сделать перед или после обновления:
- Запуск миграций базы данных.
- Очистка кэша или пересборка индексов.
- Обновление конфигурации окружения.
- Ручной запуск скриптов или дополнительных процессов.
**Как писать полезный changelog?**
1. **Соблюдайте структуру**
2. **Changelog не должен быть черновиком разработки**
1. Если что-то добавили и потом убрали до релиза, этого никогда не существовало для пользователя.
2. Не нужно записывать историю разработки — changelog фиксирует только итоговые изменения.
3. **Пишите понятно**. Ваша целевая аудитория это люди, которые не погружены в ваш сервис.
1. Избегайте технического жаргона, если это не критично.
2. Описывайте изменения так, чтобы их мог понять человек, не знакомый с внутренним устройством системы.
3. Указывайте контекст: что исправлено и почему.
4. Фиксируйте причину изменений
4. Не просто «обновлен API», а «обновлен API для поддержки новых параметров, влияющих на X».
5. Добавляйте ссылки на тикеты, если это возможно.
5. **Обновляйте changelog перед релизом, а не после.** Changelog должен быть частью процесса разработки, а не постфактум-документом.
6. **Синхронизируйте с версиями.**
1. Используйте версионирование (например, [[../other/Семантическое версионирование|Semantic Versioning]]).
2. Если выпускается патч, changelog должен отражать только исправления ошибок, а не все изменения за последние месяцы.
**Процесс ведения changelog**
Чтобы changelog был полезным и актуальным, он должен вестись в рамках строгого процесса:
5. **Changelog фиксирует только выпущенные изменения**
1. В changelog должны попадать только те изменения, которые вошли в релиз
2. Если во время разработки что-то добавили, а затем удалили до выпуска версии, то это **не должно оставлять следов в changelog**. Например, если в SNAPSHOT-версии добавили API, а потом удалили его до релиза, то запись о нем просто удаляется, а не заменяется на «удалили API».
6. **Разработчик, выполняющий доработку, отвечает за корректное добавление записей в changelog**. Изменения не должны теряться — каждая доработка должна быть зафиксирована в changelog, а не оставаться только в коде или коммитах.
7. **Ревьювер обязан проверить наличие и корректность записей в changelog**.
- Проверка changelog становится такой же важной частью code review, как и сам код.
- Запись должна быть понятной, отражать суть изменений и быть написана простым языком.
- Ревьювер должен убедиться, что не попали временные изменения, не вошедшие в релиз.
**Дополнительные советы**
- Можно настроить сбор changelog на основе PR-описаний, но важно, чтобы в итоговый changelog попадали только финальные изменения. Генерация changelog из commit history (например, Conventional Commits) может помочь, но требует жесткой дисциплины.
- Если пользователи или команда часто задают вопросы по changelog, это сигнал, что его стоит делать понятнее.
- Можно тестировать понятность changelog, давая его прочитать коллегам, не участвовавшим в разработке изменения.
- Changelog старых версий не должен меняться после их выпуска.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Эффективная разработка|00 Эффективная разработка]]
**Родитель**::
**Источник**::
**Создана**:: [[2025-02-13]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -1,5 +1,6 @@
---
aliases:
aliases:
- B-деревьев
tags:
- maturity/🌱
date: 2024-01-29

View File

@@ -0,0 +1,64 @@
---
aliases:
tags:
- maturity/🌱
date: 2025-02-24
---
Допустим, мы разрабатываем веб-сервис, который обрабатывает входящие HTTP-запросы. Каждому запросу назначается уникальный идентификатор, который должен сохраняться на протяжении всей обработки запроса, включая асинхронные операции, такие как:
- обращение к базе данных,
- вызовы внешних API,
- запись логов,
- отправка событий в Kafka или RabbitMQ.
В синхронных приложениях все просто: данные привязываются к [[../../fundamental/Поток процесса ОС|потоку]], который обслуживает запрос, и остаются неизменными на протяжении всего выполнения.
Но в асинхронных системах задача усложняется. В отличие от синхронных программ, где каждый запрос выполняется в одном потоке от начала до конца, в асинхронных системах выполнение может передаваться между разными потоками, а один поток может обслуживать множество операций. В итоге:
- **Потоки могут переключаться** — одна часть кода выполняется в одном потоке, а затем продолжение запроса передается другому. Данные, связанные с первым потоком, могут потеряться.
- **Логирование может работать некорректно** — если идентификатор запроса не передается автоматически, логи окажутся несвязанными, и отладка системы станет сложной.
- **Настройки или переменные запроса могут сбрасываться** — например, если определенные переменные нужны для аутентификации, они могут «потеряться» между вызовами.
В таких условиях возникает важный вопрос: ==как сохранить состояние данных при переключении между потоками?== Например, если у нас есть уникальный идентификатор запроса для логирования, как убедиться, что он не потеряется при передаче управления между разными частями кода?
Для решения этой проблемы в [[../../../meta/zero/00 Quarkus|Quarkus]] и Vert.x используются контексты. Они позволяют хранить локальные данные и передавать их между асинхронными вызовами. Однако существует несколько видов контекстов, каждый из которых решает свои задачи. Разберем их подробнее.
==В большинстве случаев Quarkus и Vert.x автоматически управляют контекстами==, но если ваш код выполняется в разных потоках, стоит использовать дублированный контекст. Это поможет избежать [[Обеспечение корректного асинхронного выполнения в Quarkus|неожиданных ошибок]] и сделать вашу систему более стабильной и предсказуемой.
В Quarkus и Vert.x есть несколько видов контекстов, каждый из которых выполняет свою роль.
## Корневой контекст
Корневой контекст — это самый базовый контекст, который используется для работы с глобальными процессами, выходящими за пределы одного запроса.
Особенности корневого контекста:
- Он общий для всех процессов, что делает его небезопасным для хранения локальных данных.
- Если попытаться сохранить в нем данные, они могут быть случайно переданы в другие запросы.
- Любая попытка модифицировать его может привести к исключению `UnsupportedOperationException`.
> [!DANGER] Не используйте
> Не используйте корневой контекст для хранения уникальных данных запроса. Вместо этого лучше работать с **обычным или дублированным контекстом**.
## Обычный (основной) контекст
Это контекст, который автоматически создается системой при обработке запроса. Он содержит:
- информацию о текущем [[../../architecture/Event Loop|event loop]],
- локальные данные, такие как настройки, переменные и данные для логирования (например, MDC),
- механизм автоматической передачи данных между асинхронными вызовами в пределах одного event loop.
Когда вы обрабатываете HTTP-запрос или сообщение из Kafka, Quarkus автоматически создает основной контекст и использует его для выполнения всей операции.
Однако проблема в том, что если выполнение запроса переключается между потоками, этот контекст может потеряться.
## Дублированный контекст
Обычный контекст автоматически передается между асинхронными вызовами, но только в пределах одного event loop. Если выполнение задачи выходит за его пределы (например, передается другому потоку), контекст может не сохраниться.
Решение — создать дублированный контекст. Это копия текущего контекста, которая остается доступной даже при переключении потоков.
***
## Мета информация
**Область**:: [[../../../meta/zero/00 Quarkus|00 Quarkus]]
**Родитель**::
**Источник**::
**Создана**:: [[2025-02-24]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -0,0 +1,56 @@
---
aliases:
tags:
- maturity/🌱
- content/problem
date: 2025-02-24
---
В процессе разработки одного из сервисов я обнаружил, что при асинхронной обработке данных с почтового сервера терялась диагностическая информация, передаваемая через [[../../Mapped Diagnostic Context|MDC]].
Первоначально код выглядел как-то так:
```java
Unis.voidItem()
.chain(() -> mailService.process(msg));
```
**Возникающие проблемы:**
- **Потеря MDC:** MDC хранится в ThreadLocal, а асинхронные операции могут переключаться между потоками. Из-за этого данные, установленные в MDC, терялись или оказывались перепутанными, что усложняло диагностику.
- **Отсутствие изоляции:** Поскольку вызов выполнялся в общем контексте, отсутствовало явное управление окружением выполнения. Это могло привести к состояниям гонки или другим непредсказуемым ошибкам.
- Блокировка [[../../architecture/Event Loop|event loop]]: Если метод `mailService.process` выполнял блокирующий код, это могло негативно сказаться на производительности.
Стоит подчеркнуть, что если бы запрос поступал через стандартные механизмы [[../../../meta/zero/00 Quarkus|Quarkus]] (gRPC, GraphQL, Kafka), то управление контекстом осуществлялось бы системой, и подобных проблем бы не возникало. Однако в нашем случае вызов инициировался через `org.apache.camel.Processor`, что требовало дополнительных усилий по сохранению контекстной информации.
Анализ показал, что основная проблема кроется в потере MDC при переключении между потоками. В условиях асинхронного выполнения вызовы, инициированные через Camel, не гарантируют автоматическую передачу контекста, что приводит к потере данных, необходимых для корректного логирования и диагностики.
==Чтобы решить эту проблему, было решено явно создать дублированный контекст и переключить выполнение на него.== Код был изменён следующим образом:
```java
final Context duplicateContext = Context.newInstance(
VertxContext.getOrCreateDuplicatedContext(vertx.getDelegate())
);
Unis.voidItem()
.emitOn(duplicateContext::runOnContext)
.chain(() -> mailService.process(msg));
```
**Преимущества данного подхода:**
- **Сохранение MDC:** Дублированный контекст позволяет перенести все данные, связанные с текущим окружением (включая MDC), что обеспечивает корректное логирование даже при асинхронном выполнении.
- **Изоляция выполнения:** Переключение на новый контекст гарантирует, что все последующие операции выполняются в заданном окружении, исключая неожиданные переключения потоков.
- Устранение блокировки [[../../architecture/Event Loop|event loop]]: Если метод `mailService.process` содержит блокирующие или ресурсоёмкие операции, их выполнение в изолированном контексте помогает снизить негативное влияние на основной event loop.
Таким образом, если ваши асинхронные операции инициируются через нестандартные компоненты, такие как Apache Camel, и Quarkus не управляет контекстом напрямую, создание дублированного контекста становится необходимым для корректной работы.
***
## Мета информация
**Область**:: [[../../../meta/zero/00 Quarkus|00 Quarkus]]
**Родитель**::
**Источник**::
**Создана**:: [[2025-02-24]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -0,0 +1,44 @@
---
aliases:
tags:
- maturity/🌱
- content/problem
date: 2025-02-11
---
У меня есть жесткий диск, который я переодически бэкапирую на MacOS. Под бэкапом я понимаю копирование точной структуры и файлов. Нужно удалить те файлы, что были удалены и добавить те, которые появились.
Для этого я использую команду `rsync` :
```shell
rsync -av --delete /путь/к/первой_папке/ /путь/ко/второй_папке/
```
> [!WARNING]
> В конце пути первой папки (/путь/к/первой_папке/) есть **слэш /**. Это важно: rsync в этом случае копирует **содержимое** папки, а не саму папку.
**Разбор флагов:**
- -a — архивный режим (сохраняет права, даты, символические ссылки и пр.)
- -v — режим вывода информации (можно убрать, если не нужен список файлов)
- --delete — удаляет файлы во второй папке, если их больше нет в первой
Если хочешь проверить, какие файлы будут удалены или добавлены, перед выполнением можешь сделать сухой прогон:
```shell
rsync -av --delete --dry-run ~/Documents/source/ ~/Documents/backup/
```
Он покажет, что будет сделано, но не изменит файлы.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]]
**Родитель**::
**Источник**::
**Создана**:: [[2025-02-11]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@@ -0,0 +1,39 @@
---
aliases:
- идентификатор
- идентификатора
- идентификаторов
tags:
- maturity/🌱
date: 2025-02-18
---
Идентификатор (ID) — это уникальное значение, используемое для однозначного определения объектов в системе. Он играет ключевую роль в [[architecture/Бизнес-логика|бизнес-логике]], связывая сущности и обеспечивая их однозначное различение.
**Типы идентификаторов**
- [[database/other/Автоинкремент в БД|Автоинкремент в БД]]
- [[Universal Unique IDentifier|UUID]]
- [[Time-Sorted Identifier]]
- [[NanoId|NanoId]]
- Хешированные идентификаторы
- Комбинированные идентификаторы. Иногда идентификаторы комбинируются для удобства и повышения уникальности:
- UUID + порядковый номер (для удобства пользователей).
- Осмысленные ID (например, ORD-20240218-1234 для заказов).
- Хеш-идентификаторы ([[cryptography/SHA-256|SHA-256]], Base62), чтобы скрыть предсказуемые ID.
***
## Мета информация
**Область**::
**Родитель**::
**Источник**::
**Создана**:: [[2025-02-18]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Universal Unique IDentifier]]
- [[Автоинкремент в БД]]
- [[Time-Sorted Identifier]]
<!-- SerializedQuery END -->

17
meta/zero/00 Gitea.md Normal file
View File

@@ -0,0 +1,17 @@
---
aliases:
- Gitea
tags:
- type/zero-link
date: 2025-02-04
title: Gitea
---
- [[../../dev/devops/other/Фоновые задачи Gitea|Фоновые задачи Gitea]]
Диагностика:
- [[../../dev/devops/other/Автоматическая диагностика в Gitea|Автоматическая диагностика в Gitea]]
- [[../../dev/devops/other/Проверка get запросов к Gitea|Проверка get запросов к Gitea]]
Решение проблем:
- [[../../dev/devops/other/Высокое потребление ресурсов контейнером Gitea|Высокое потребление ресурсов контейнером Gitea]]

View File

@@ -11,6 +11,7 @@ aliases:
- высоконагруженных систем
- систем с высокой нагрузкой
- высокой нагрузкой
- высоконагруженных приложений
---
## Что такое HighLoad?
Например, один запрос в секунду это нагрузка явно не highload, любой сервер, вроде бы, справится. Но, например, если он перекодирует видеоролики, то тут может наступить highload.

View File

@@ -10,6 +10,7 @@ aliases:
- Реляционная база данных
- базами данных
- базы данных
- баз данных
linked:
- "[[../../../../_inbox/00 In-memory СуБД|00 In-memory СуБД]]"
---