livrare lot 2
This commit is contained in:
commit
8ecc78e729
763 changed files with 164593 additions and 0 deletions
|
|
@ -0,0 +1,168 @@
|
|||
# Migrare RabbitMQ: `staging-dataLayer-rabbitmq` local → cluster HA `10.11.50.100`
|
||||
|
||||
**Autor**: refactor 2026-04-22 (după Redis migration)
|
||||
**Scop**: mutarea cozilor async (cele 31 de cozi analysis.*) de pe containerul RabbitMQ local pe clusterul HA managed cu vhost dedicat `/didi`.
|
||||
|
||||
---
|
||||
|
||||
## Stare actuală (post-cutover)
|
||||
|
||||
- Codul RabbitMQ era **deja centralizat** în 3 fișiere:
|
||||
- `src/queue/connection.ts` — manager singleton conexiune + channels
|
||||
- `src/shared/queue/constants.ts` — `getRabbitMQConfig()` + `getRabbitMQUrl()`
|
||||
- `src/scripts/init-priority-queues.ts` — script standalone
|
||||
- Zero refactor pe cod aplicație. Un singur punct de schimbat.
|
||||
- URL-encoding corect pentru vhost `/didi` adăugat în `getRabbitMQUrl()` (folosește `encodeURIComponent` pentru user/pass/vhost).
|
||||
- `CONNECTION_RETRY_DELAY` tuned de la 5s la 2s pentru failover HA mai rapid.
|
||||
- Logging îmbunătățit: arată host+vhost+user la conectare/eroare/close.
|
||||
|
||||
---
|
||||
|
||||
## Target
|
||||
|
||||
| Parametru | Valoare |
|
||||
|---|---|
|
||||
| AMQP | `10.11.50.100:16672` |
|
||||
| Management UI | `http://10.11.50.100:16673` |
|
||||
| Username | `didi` |
|
||||
| Password | `$CLUSTER_PASSWORD` |
|
||||
| Vhost dedicat | `/didi` (izolat de alte proiecte) |
|
||||
| URI encoded | `amqp://didi:...@10.11.50.100:16672/%2Fdidi` |
|
||||
| Cluster HA | 3 noduri rag01/02/03 + HAProxy VIP |
|
||||
|
||||
---
|
||||
|
||||
## Diferență critică față de Redis
|
||||
|
||||
**Nu a fost nevoie de migrare de date**. Cozile RabbitMQ sunt efemere — topologia (exchange + 31 queues) se creează automat de workeri la `assertExchange()` / `assertQueue()` pe prima conectare. Mesajele în zbor la cutover se pierd (erau 0 la momentul migrării).
|
||||
|
||||
---
|
||||
|
||||
## Pași executați la cutover
|
||||
|
||||
### 1. Refactor cod (minim)
|
||||
|
||||
- `src/queue/connection.ts`:
|
||||
- Retry: 5s → 2s
|
||||
- Logging: `[RabbitMQ] Connecting to HOST:PORT/VHOST (user: USER)...`
|
||||
- Error messages: includ host+vhost pentru debug
|
||||
- Add `blocked/unblocked` handlers (broker flow control)
|
||||
- `src/shared/queue/constants.ts`:
|
||||
- `getRabbitMQUrl()` folosește `encodeURIComponent()` pentru user/pass/vhost
|
||||
- Fix critical: vhost `/didi` acum devine `%2Fdidi` în URL (fără asta, amqplib parsa ca vhost `didi` fără slash)
|
||||
|
||||
### 2. docker-compose (agent-v3)
|
||||
|
||||
`x-worker-env` schimbate din hardcoded la fallbacks:
|
||||
```yaml
|
||||
RABBITMQ_HOST: ${RABBITMQ_HOST:-staging-dataLayer-rabbitmq}
|
||||
RABBITMQ_PORT: ${RABBITMQ_PORT:-5672}
|
||||
RABBITMQ_USER: ${RABBITMQ_USER:-admin}
|
||||
RABBITMQ_PASS: ${RABBITMQ_PASS:-rabbitmq123}
|
||||
RABBITMQ_VHOST: ${RABBITMQ_VHOST:-/}
|
||||
```
|
||||
|
||||
### 3. `.env` agent-v3
|
||||
|
||||
Adăugat bloc:
|
||||
```
|
||||
RABBITMQ_HOST=10.11.50.100
|
||||
RABBITMQ_PORT=16672
|
||||
RABBITMQ_USER=didi
|
||||
RABBITMQ_PASS=$CLUSTER_PASSWORD
|
||||
RABBITMQ_VHOST=/didi
|
||||
```
|
||||
|
||||
### 4. Rebuild + restart
|
||||
|
||||
- `docker compose build` (toate 8 imagini, cache fast)
|
||||
- `docker compose up -d --force-recreate` pe agent-v3 stack
|
||||
- Workerii s-au conectat în < 1s și au creat automat toate 31 cozile
|
||||
|
||||
### 5. Verificare
|
||||
|
||||
- 31/31 cozi prezente pe `/didi` cu consumerii corespunzători (claims×3, rest×2)
|
||||
- 14 conexiuni active de la workeri prin HAProxy VIP
|
||||
- Smoke test: analiză async plan 4 = pro, status `completed` în 3.9s, risk MOSTLY_RELIABLE (22)
|
||||
|
||||
---
|
||||
|
||||
## Script de verificare: `scripts/verify-rabbitmq-cluster.ts`
|
||||
|
||||
Mirror al `verify-redis-cluster.ts`. Rulează cu:
|
||||
|
||||
```bash
|
||||
RABBITMQ_HOST=10.11.50.100 RABBITMQ_PORT=16672 \
|
||||
RABBITMQ_USER=didi RABBITMQ_PASS='...' RABBITMQ_VHOST=/didi \
|
||||
node_modules/.bin/ts-node --transpile-only scripts/verify-rabbitmq-cluster.ts
|
||||
```
|
||||
|
||||
Verifică:
|
||||
1. Conectivitate + auth pe vhost
|
||||
2. Channel creation
|
||||
3. Assert exchange `analysis` (topic, durable)
|
||||
4. Write privilege (creează + șterge coadă temporară)
|
||||
5. Topologie expected (31 cozi) — WARN dacă workerii nu au rulat încă
|
||||
|
||||
Exit codes: `0` = OK sau WARN (topology lipsă pre-cutover), `1` = FATAL.
|
||||
|
||||
---
|
||||
|
||||
## Fallback LOCAL păstrat
|
||||
|
||||
Containerul `staging-dataLayer-rabbitmq` e **oprit** dar **nu șters** — rollback rapid prin script.
|
||||
|
||||
### Switch rapid: `services/orchestration-layer/scripts/redis-switch.sh`
|
||||
|
||||
Scriptul acoperă ACUM ambele servicii (Redis + RabbitMQ):
|
||||
|
||||
```bash
|
||||
# Arată status curent
|
||||
./redis-switch.sh status
|
||||
|
||||
# Switch ambele (Redis + Rabbit) la cluster
|
||||
./redis-switch.sh cluster
|
||||
|
||||
# Switch ambele la local
|
||||
./redis-switch.sh local
|
||||
|
||||
# Doar unul:
|
||||
./redis-switch.sh cluster redis # Redis → cluster, Rabbit neschimbat
|
||||
./redis-switch.sh local rabbit # Rabbit → local, Redis neschimbat
|
||||
```
|
||||
|
||||
Script-ul:
|
||||
- Pornește containerul local dacă e oprit (`docker start` sau `docker compose up -d`)
|
||||
- Rescrie blocul corespunzător în `.env` (fără să atingă celelalte)
|
||||
- Restart `didi-framework` + `agent-v3` stack
|
||||
|
||||
### Rollback în 30s
|
||||
|
||||
```bash
|
||||
./redis-switch.sh local rabbit # doar RabbitMQ înapoi la local
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cleanup DEFINITIV (după 30+ zile stabil)
|
||||
|
||||
1. Stop + remove container local:
|
||||
```bash
|
||||
docker stop staging-dataLayer-rabbitmq # deja oprit
|
||||
docker rm staging-dataLayer-rabbitmq
|
||||
docker volume rm didi-staging-rabbitmq-data
|
||||
```
|
||||
|
||||
2. Șterge secțiunea din `data-layer/docker-compose.yml`
|
||||
|
||||
3. Update `didiQueue/INDEX.md` marcat ca deprecated
|
||||
|
||||
4. Admin dashboard nginx — șterge `/health-check/rabbitmq` (pointa la container local)
|
||||
|
||||
---
|
||||
|
||||
## Riscuri cunoscute / TODO
|
||||
|
||||
1. **amqplib nu are Sentinel/discovery nativ** — la failover cluster, ioredis-style "învață" singur noul master. amqplib doar se deconectează și se reconectează la VIP (care rutează la noul master). Downtime client: 5-15s acceptabil.
|
||||
2. **init-priority-queues.ts** — neinvestigat în detaliu dacă mai e rulat. Cozile se creează oricum prin workeri.
|
||||
3. **Monitoring**: management UI-ul e pe `10.11.50.100:16673` — accesibil doar din LAN. Admin dashboard nu-l embedă direct; user poate deschide browser separat.
|
||||
Loading…
Add table
Add a link
Reference in a new issue