Dateien nach "/" hochladen
This commit is contained in:
@@ -1,66 +1,133 @@
|
||||
# SMTPGraphRelay V1.2 – Queue & Retry
|
||||
# SMTPGraphRelay V1.3 – parallele SMTP-Verbindungen
|
||||
|
||||
Diese Version ersetzt nur `SMTPGraphRelay.ps1`. Die bestehende `config.json`, Entra-App,
|
||||
das Zertifikat und Exchange Application RBAC bleiben unverändert.
|
||||
V1.3 baut auf V1.2 auf. Entra-App, Zertifikat, Exchange Application RBAC und
|
||||
`config.json` können unverändert weiterverwendet werden.
|
||||
|
||||
## Neue Queue-Struktur
|
||||
## Neu
|
||||
|
||||
```text
|
||||
queue\
|
||||
├── incoming\
|
||||
├── pending\
|
||||
└── processing\
|
||||
- bis zu 20 parallele SMTP-Verbindungen standardmäßig
|
||||
- konfigurierbares Parallel-Limit über `Smtp.MaxConcurrentClients`
|
||||
- SMTP-Clients laufen in einem .NET Runspace Pool
|
||||
- Queue-/Graph-Versand läuft in einem eigenen Runspace
|
||||
- ein langsamer Graph-Aufruf blockiert die SMTP-Annahme nicht mehr
|
||||
- ein langsamer/hängender SMTP-Client blockiert andere Clients nicht mehr
|
||||
- bei erreichtem Parallel-Limit erhält ein neuer Client:
|
||||
`421 4.3.2 SMTPGraphRelay busy, try again later`
|
||||
- Logging ist mit einem benannten Mutex gegen parallele Schreibzugriffe geschützt
|
||||
- Queue-/Retry-Logik aus V1.2 bleibt erhalten
|
||||
|
||||
failed\
|
||||
## Optional: Parallel-Limit konfigurieren
|
||||
|
||||
Bestehende `config.json` muss nicht geändert werden. Ohne Eintrag gilt `20`.
|
||||
|
||||
Optional:
|
||||
|
||||
```json
|
||||
"Smtp": {
|
||||
"ListenAddress": "0.0.0.0",
|
||||
"Port": 2525,
|
||||
"Hostname": "SMTPRELAY01",
|
||||
"AllowedNetworks": [
|
||||
"127.0.0.1/32",
|
||||
"10.0.0.0/8",
|
||||
"172.16.0.0/12",
|
||||
"192.168.0.0/16"
|
||||
],
|
||||
"MaxMessageSizeMB": 25,
|
||||
"ClientTimeoutSeconds": 120,
|
||||
"MaxConcurrentClients": 20
|
||||
}
|
||||
```
|
||||
|
||||
- `incoming`: Mail wird gerade atomar geschrieben.
|
||||
- `pending`: vollständig angenommene und sendbare Mail.
|
||||
- `processing`: aktuell durch den Worker bearbeitet.
|
||||
- `failed`: permanent fehlgeschlagene oder nach MaxRetries aufgegebene Mail.
|
||||
Erlaubter Bereich: 1 bis 200. Ungültige Werte fallen auf 20 zurück.
|
||||
|
||||
Beim Start werden alte V1-Mails direkt aus `queue\` nach `pending\` migriert.
|
||||
Mails, die nach einem Absturz noch in `processing\` liegen, werden nach `pending\`
|
||||
zurückgestellt.
|
||||
|
||||
## Retry
|
||||
|
||||
- HTTP 429: `Retry-After` wird verwendet; fehlt es, exponentielles Backoff.
|
||||
- HTTP 408 und 5xx: Retry nach `RetryMinutes` aus `config.json`.
|
||||
- Netzwerk-/Transportfehler ohne HTTP-Code: Retry.
|
||||
- typische permanente 4xx wie 400/401/403/404/413/415/422: direkt nach `failed`.
|
||||
- nach `MaxRetries`: nach `failed`.
|
||||
|
||||
## Installation über bestehende Version
|
||||
|
||||
1. Scheduled Task stoppen:
|
||||
## Update
|
||||
|
||||
```powershell
|
||||
Stop-ScheduledTask -TaskName "SMTPGraphRelay"
|
||||
|
||||
Copy-Item `
|
||||
"C:\Program Files\SMTPGraphRelay\SMTPGraphRelay.ps1" `
|
||||
"C:\Program Files\SMTPGraphRelay\SMTPGraphRelay-V1.2-backup.ps1"
|
||||
```
|
||||
|
||||
2. Bestehendes `SMTPGraphRelay.ps1` sichern.
|
||||
3. `SMTPGraphRelay-V1.2.ps1` als `SMTPGraphRelay.ps1` in den Programmordner kopieren.
|
||||
4. Task starten:
|
||||
Dann `SMTPGraphRelay-V1.3.ps1` als
|
||||
|
||||
```text
|
||||
C:\Program Files\SMTPGraphRelay\SMTPGraphRelay.ps1
|
||||
```
|
||||
|
||||
ablegen und starten:
|
||||
|
||||
```powershell
|
||||
Start-ScheduledTask -TaskName "SMTPGraphRelay"
|
||||
```
|
||||
|
||||
5. Log prüfen:
|
||||
Log:
|
||||
|
||||
```powershell
|
||||
Get-Content "C:\Program Files\SMTPGraphRelay\logs\SMTPGraphRelay.log" -Tail 100
|
||||
Get-Content `
|
||||
"C:\Program Files\SMTPGraphRelay\logs\SMTPGraphRelay.log" `
|
||||
-Tail 100
|
||||
```
|
||||
|
||||
## Hinweis zu 202 Accepted
|
||||
Beim Start sollten u. a. erscheinen:
|
||||
|
||||
Microsoft Graph `sendMail` liefert bei erfolgreicher Annahme `202 Accepted`. Das bedeutet,
|
||||
dass Graph die Nachricht angenommen hat, aber nicht, dass die endgültige Zustellung bereits
|
||||
abgeschlossen ist.
|
||||
```text
|
||||
SMTPGraphRelay V1.3 gestartet ...
|
||||
Maximale parallele SMTP-Verbindungen: 20
|
||||
Queue-/Graph-Worker läuft separat vom SMTP-Listener.
|
||||
```
|
||||
|
||||
Eine absolut garantierte Exactly-Once-Zustellung kann ein SMTP→Graph-Gateway nicht
|
||||
sicherstellen: Falls Graph die Mail bereits angenommen hat und der lokale Prozess exakt
|
||||
vor dem Löschen der Queue-Datei abstürzt, kann ein erneuter Versuch theoretisch ein Duplikat
|
||||
erzeugen. V1.2 reduziert dieses Risiko durch die Processing-Queue, kann es aber nicht
|
||||
vollständig eliminieren.
|
||||
## Test für Parallelität
|
||||
|
||||
In mehreren PowerShell-Fenstern gleichzeitig:
|
||||
|
||||
```powershell
|
||||
Send-MailMessage `
|
||||
-SmtpServer 127.0.0.1 `
|
||||
-Port 2525 `
|
||||
-From "info@maieredv.de" `
|
||||
-To "manuel.maier@maieredv.de" `
|
||||
-Subject "Parallel-Test" `
|
||||
-Body "SMTPGraphRelay V1.3"
|
||||
```
|
||||
|
||||
Für einen härteren Test können mehrere Jobs gleichzeitig gestartet werden:
|
||||
|
||||
```powershell
|
||||
1..10 | ForEach-Object {
|
||||
Start-Job -ArgumentList $_ -ScriptBlock {
|
||||
param($n)
|
||||
Send-MailMessage `
|
||||
-SmtpServer 127.0.0.1 `
|
||||
-Port 2525 `
|
||||
-From "info@maieredv.de" `
|
||||
-To "manuel.maier@maieredv.de" `
|
||||
-Subject "Parallel-Test $n" `
|
||||
-Body "Nachricht $n"
|
||||
}
|
||||
}
|
||||
|
||||
Get-Job | Wait-Job | Receive-Job
|
||||
Get-Job | Remove-Job
|
||||
```
|
||||
|
||||
## Architektur
|
||||
|
||||
```text
|
||||
+--> SMTP Worker 1 --+
|
||||
SMTP Listener -----------+--> SMTP Worker 2 --+--> pending\
|
||||
+--> SMTP Worker N --+
|
||||
Runspace Pool
|
||||
|
|
||||
| unabhängig
|
||||
v
|
||||
Queue / Graph Worker
|
||||
|
|
||||
v
|
||||
Microsoft Graph
|
||||
```
|
||||
|
||||
Der SMTP-Listener nimmt dadurch weiter neue Verbindungen an, während andere Clients
|
||||
noch `DATA` übertragen oder Microsoft Graph gerade langsam antwortet.
|
||||
|
||||
Reference in New Issue
Block a user