278 lines
12 KiB
Markdown
278 lines
12 KiB
Markdown
|
|
# 🏗️ Архитектура системы мониторинга файлов
|
|||
|
|
|
|||
|
|
## 🎯 Общая схема
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ ИСТОЧНИКИ ФАЙЛОВ │
|
|||
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
|
|||
|
|
│ │ CRM PHP │ │ Nextcloud │ │ S3 Browser │ │ Внешние │ │
|
|||
|
|
│ │ │ │ WebUI │ │ Cyberduck │ │ скрипты │ │
|
|||
|
|
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └─────┬──────┘ │
|
|||
|
|
│ │ │ │ │ │
|
|||
|
|
│ └─────────────────┼─────────────────┼─────────────────┘ │
|
|||
|
|
│ │ │ │
|
|||
|
|
└───────────────────────────┼─────────────────┼───────────────────────────┘
|
|||
|
|
▼ ▼
|
|||
|
|
┌──────────────────────────────────────┐
|
|||
|
|
│ │
|
|||
|
|
│ TWC S3 Storage (Cloud) │
|
|||
|
|
│ f9825c87-18698658-c378-... │
|
|||
|
|
│ │
|
|||
|
|
└────┬─────────────────────────────┬───┘
|
|||
|
|
│ │
|
|||
|
|
│ (mounted via │ (polling)
|
|||
|
|
│ external │
|
|||
|
|
│ storage) │
|
|||
|
|
▼ ▼
|
|||
|
|
┌──────────────────────┐ ┌──────────────────────────┐
|
|||
|
|
│ Nextcloud │ │ n8n S3 Monitor │
|
|||
|
|
│ Docker Container │ │ Workflow │
|
|||
|
|
│ │ │ │
|
|||
|
|
│ Files change → │ │ Every 30s: │
|
|||
|
|
│ notify_storage_ │ │ 1. List S3 files │
|
|||
|
|
│ update (Redis) │ │ 2. Compare with prev │
|
|||
|
|
└──────────┬───────────┘ │ 3. Detect changes │
|
|||
|
|
│ └─────────┬────────────────┘
|
|||
|
|
│ │
|
|||
|
|
▼ ▼
|
|||
|
|
┌──────────────────────┐ ┌─────────────────────────┐
|
|||
|
|
│ redis_bridge.js │ │ │
|
|||
|
|
│ (Node.js) │ │ (n8n internal) │
|
|||
|
|
│ │ │ │
|
|||
|
|
│ 1. Subscribe NC │ │ │
|
|||
|
|
│ Redis │ │ │
|
|||
|
|
│ 2. Parse events │ │ │
|
|||
|
|
│ 3. Enrich data │ │ │
|
|||
|
|
└──────────┬───────────┘ └─────────┬───────────────┘
|
|||
|
|
│ │
|
|||
|
|
│ │
|
|||
|
|
└────────────┬───────────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌──────────────────────────────┐
|
|||
|
|
│ CRM Redis │
|
|||
|
|
│ 147.45.146.17:6379 │
|
|||
|
|
│ │
|
|||
|
|
│ Channel: │
|
|||
|
|
│ crm:file:events │
|
|||
|
|
└───────────┬──────────────────┘
|
|||
|
|
│
|
|||
|
|
│ (subscribe)
|
|||
|
|
│
|
|||
|
|
┌─────────────────┼─────────────────┐
|
|||
|
|
│ │ │
|
|||
|
|
▼ ▼ ▼
|
|||
|
|
┌────────────┐ ┌────────────┐ ┌────────────┐
|
|||
|
|
│ n8n │ │ CRM PHP │ │ Другие │
|
|||
|
|
│ Workflows │ │ Listeners │ │ сервисы │
|
|||
|
|
└────────────┘ └────────────┘ └────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 Потоки событий
|
|||
|
|
|
|||
|
|
### Поток 1: Файлы через Nextcloud WebUI
|
|||
|
|
```
|
|||
|
|
User uploads file → Nextcloud → S3 Storage →
|
|||
|
|
→ Nextcloud detects change → notify_storage_update (NC Redis) →
|
|||
|
|
→ redis_bridge.js → crm:file:events (CRM Redis) → Обработчики
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
⏱️ **Задержка:** ~1-2 секунды (реал-тайм)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Поток 2: Файлы напрямую в S3
|
|||
|
|
```
|
|||
|
|
External tool → S3 Storage →
|
|||
|
|
→ n8n S3 Monitor (polling every 30s) → Detects change →
|
|||
|
|
→ crm:file:events (CRM Redis) → Обработчики
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
⏱️ **Задержка:** 0-30 секунд (зависит от интервала polling)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔄 Компоненты системы
|
|||
|
|
|
|||
|
|
### 1. **redis_bridge.js** (Node.js, работает на хосте)
|
|||
|
|
- **Задача:** Мост между Nextcloud Redis и CRM Redis
|
|||
|
|
- **Вход:** `notify_storage_update` (Nextcloud Redis, port 6380)
|
|||
|
|
- **Выход:** `crm:file:events` (CRM Redis, port 6379)
|
|||
|
|
- **Статус:** ✅ Работает
|
|||
|
|
- **Запуск:**
|
|||
|
|
```bash
|
|||
|
|
cd /var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage
|
|||
|
|
/usr/bin/nodejs redis_bridge.js &
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. **n8n S3 Monitor Workflow** (в n8n)
|
|||
|
|
- **Задача:** Мониторинг прямых изменений в S3
|
|||
|
|
- **Метод:** Polling (каждые 30 секунд)
|
|||
|
|
- **Вход:** TWC S3 API (ListObjectsV2)
|
|||
|
|
- **Выход:** `crm:file:events` (CRM Redis)
|
|||
|
|
- **Статус:** ⚙️ Нужно настроить
|
|||
|
|
- **Файл:** `n8n_s3_monitor_workflow.json`
|
|||
|
|
|
|||
|
|
### 3. **CRM Redis** (центральная шина событий)
|
|||
|
|
- **Адрес:** `147.45.146.17:6379`
|
|||
|
|
- **Канал:** `crm:file:events`
|
|||
|
|
- **Формат события:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"type": "file_created|file_modified|file_deleted",
|
|||
|
|
"source": "nextcloud|s3_monitor|crm",
|
|||
|
|
"timestamp": "2025-10-30T12:34:56Z",
|
|||
|
|
"path": "full/path/to/file.txt",
|
|||
|
|
"filename": "file.txt",
|
|||
|
|
"size": 12345,
|
|||
|
|
"file_id": 73460,
|
|||
|
|
"etag": "abc123...",
|
|||
|
|
"operation": "create|update|delete"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 Сценарии использования
|
|||
|
|
|
|||
|
|
### Сценарий 1: Обработка ERV файлов
|
|||
|
|
```
|
|||
|
|
1. Загружаешь ERV файл в S3 через S3 Browser
|
|||
|
|
2. n8n S3 Monitor обнаруживает файл (через 0-30с)
|
|||
|
|
3. Событие публикуется в Redis → crm:file:events
|
|||
|
|
4. n8n ERV Processor подхватывает событие
|
|||
|
|
5. Скачивает файл из S3
|
|||
|
|
6. Обрабатывает ERV
|
|||
|
|
7. Загружает в CRM
|
|||
|
|
8. Отправляет уведомление
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Сценарий 2: Автоматическая обработка PDF счетов
|
|||
|
|
```
|
|||
|
|
1. Клиент загружает PDF в Nextcloud
|
|||
|
|
2. Nextcloud → notify_storage_update → redis_bridge.js
|
|||
|
|
3. Событие в Redis (реал-тайм, ~1с)
|
|||
|
|
4. n8n Invoice Processor:
|
|||
|
|
- Распознаёт текст (OCR)
|
|||
|
|
- Извлекает данные
|
|||
|
|
- Создаёт счёт в CRM
|
|||
|
|
- Уведомляет бухгалтера
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Сценарий 3: Синхронизация с внешней системой
|
|||
|
|
```
|
|||
|
|
1. Внешний скрипт пишет в S3
|
|||
|
|
2. n8n S3 Monitor (через 30с)
|
|||
|
|
3. Redis событие
|
|||
|
|
4. n8n External Sync:
|
|||
|
|
- Проверяет формат файла
|
|||
|
|
- Отправляет в external API
|
|||
|
|
- Логирует в CRM
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ⚙️ Настройки производительности
|
|||
|
|
|
|||
|
|
### Интервал polling S3 Monitor
|
|||
|
|
|
|||
|
|
| Интервал | Задержка | Нагрузка на API | Рекомендация |
|
|||
|
|
|----------|----------|-----------------|--------------|
|
|||
|
|
| 10 сек | 0-10с | Высокая | Только для критичных файлов |
|
|||
|
|
| 30 сек | 0-30с | Средняя | ✅ **Оптимально** |
|
|||
|
|
| 60 сек | 0-60с | Низкая | Для некритичных файлов |
|
|||
|
|
| 300 сек | 0-5мин | Минимальная | Для архивов |
|
|||
|
|
|
|||
|
|
### Количество файлов
|
|||
|
|
|
|||
|
|
- **< 1000 файлов:** Мониторь весь bucket
|
|||
|
|
- **1000-10000:** Используй `Prefix` для фильтрации папок
|
|||
|
|
- **> 10000:** Создай отдельные workflows для разных папок
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔧 Мониторинг и логи
|
|||
|
|
|
|||
|
|
### Проверка работы redis_bridge.js
|
|||
|
|
```bash
|
|||
|
|
ps aux | grep redis_bridge.js
|
|||
|
|
tail -f /var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/redis_bridge.log
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Проверка событий в Redis
|
|||
|
|
```bash
|
|||
|
|
redis-cli -h 147.45.146.17 -p 6379 -a 'CRM_Redis_Pass_2025_Secure!' \
|
|||
|
|
SUBSCRIBE crm:file:events
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Проверка n8n workflow
|
|||
|
|
- n8n UI → Workflows → S3 File Monitor → Executions
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚀 Расширение системы
|
|||
|
|
|
|||
|
|
### Добавление новых источников событий
|
|||
|
|
|
|||
|
|
Любой компонент может публиковать в `crm:file:events`:
|
|||
|
|
|
|||
|
|
**Пример из PHP (CRM):**
|
|||
|
|
```php
|
|||
|
|
$redis = new Redis();
|
|||
|
|
$redis->connect('147.45.146.17', 6379);
|
|||
|
|
$redis->auth('CRM_Redis_Pass_2025_Secure!');
|
|||
|
|
|
|||
|
|
$event = [
|
|||
|
|
'type' => 'file_created',
|
|||
|
|
'source' => 'crm_api',
|
|||
|
|
'timestamp' => date('c'),
|
|||
|
|
'path' => $filePath,
|
|||
|
|
'filename' => basename($filePath),
|
|||
|
|
'size' => filesize($localPath),
|
|||
|
|
'user_id' => $userId
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
$redis->publish('crm:file:events', json_encode($event));
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Пример из Python:**
|
|||
|
|
```python
|
|||
|
|
import redis
|
|||
|
|
import json
|
|||
|
|
from datetime import datetime
|
|||
|
|
|
|||
|
|
r = redis.Redis(
|
|||
|
|
host='147.45.146.17',
|
|||
|
|
port=6379,
|
|||
|
|
password='CRM_Redis_Pass_2025_Secure!'
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
event = {
|
|||
|
|
'type': 'file_created',
|
|||
|
|
'source': 'python_script',
|
|||
|
|
'timestamp': datetime.utcnow().isoformat() + 'Z',
|
|||
|
|
'path': file_path,
|
|||
|
|
'filename': os.path.basename(file_path)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
r.publish('crm:file:events', json.dumps(event))
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 Итого
|
|||
|
|
|
|||
|
|
✅ **Nextcloud файлы** → реал-тайм через `redis_bridge.js`
|
|||
|
|
✅ **S3 прямые загрузки** → polling через n8n (0-30с задержка)
|
|||
|
|
✅ **CRM файлы** → прямая публикация в Redis
|
|||
|
|
✅ **Единая точка обработки** → Redis канал `crm:file:events`
|
|||
|
|
✅ **Гибкость** → любой сервис может подписаться и обработать
|
|||
|
|
|
|||
|
|
**Всё работает через один канал Redis! 🎉**
|
|||
|
|
|