Od tématu magazínu k projektové praxi
Vhodné stránky služeb a technické stránky k příspěvku
Video-Botschaft
Linuxové služby s Delphi v produkčním provozu
Kurze Einordnung, warum Delphi-basierte Linux-Services im Betrieb nicht an der Fachlogik scheitern, sondern an Logging, systemd-Integration, Updates und definiertem Fehlerverhalten – und welche Perspektive für robuste Nacht-3-Uhr-Setups zählt.
Video mit KI erstellt
Transkript anzeigen
Guten Tag. Die meisten Service-Probleme sind keine Programmfehler.
Es sind Betriebsfehler. Im Beitrag „Linux-Services mit Delphi im produktiven Betrieb“ geht es genau darum: Hintergrunddienste sind nur dann hilfreich, wenn man sie wie einen Produktbestandteil betreibt.
In der Praxis scheitert es oft an Basics: Wie startet und stoppt der Dienst sauber? Unter Linux übernimmt das meist systemd, also die Service-Steuerung fürs System.
Wie sieht Logging aus, sodass man nachts um drei Ursache statt Vermutung hat? Und was passiert bei Neustarts, Netzproblemen oder doppelten Jobs?
Die Kernaussage ist nüchtern: Fachlogik reicht nicht. Zustände, Updates, Rechte und Wiederanlauf müssen geplant sein.
Wenn Sie dazu Fragen haben, klären wir sie gern entlang Ihres Betriebsmodells.
Služby na pozadí jsou v mnoha podnikových aplikacích tichým hybatelem produktivity: importy dat, exporty, zpracování souborů a EDI, synchronizace s ERP/DMS/CRM, časově řízené workflow, notifikace nebo poskytování technických rozhraní. V praxi však o úspěchu nerozhoduje čistě funkce, ale otázka: Lze službu spolehlivě provozovat, aktualizovat, monitorovat a v případě chyby kontrolovaně obnovit?
Právě zde se vyplatí střízlivý pohled na Linux-Services s Delphi. Delphi je v mnoha organizacích již nosnou částí fachlogiky. Pokud lze tuto logiku smysluplně znovu použít na straně serveru, vznikne konzistentní celková architektura: obchodní pravidla se neimplementují duplicitně, rozhraní zůstávají stabilní a týmy pracují v osvědčeném toolingu. Současně přináší Linux ve světě serverů prověřené stavební bloky pro provoz, automatizaci a bezpečnost.
Klíčový bod: Windows- und Linux-Services není „malý pomocný program“, který se spustí vedle. Je to součást produktu s provozní odpovědností. Tento článek ukazuje konkrétně, jak mít Delphi-založené Linux-services v produkci robustně zajištěné: od procesního a stavového modelu přes integraci do systemd, logging, nasazení a aktualizace až po monitoring, přístup k datům, bezpečnost a typické chybové scénáře. Cílem je nastavení, které funguje v každodenním provozu – i ve 3 ráno.
Kdy mají Delphi-services pod Linux smysl
Delphi-Linux-service je nasnadě vždy, když platí jedno nebo více z následujících vzorů:
- Existující Delphi-fachlogik má být využita na serveru (např. validace, výpočty, pravidla, import/export parsery).
- Zpracování na pozadí je integrální součástí aplikace (např. PDF-/reportingové pipeline, job-queue, dávkové zpracování).
- Narůstá integrační zátěž: mnoho systémů, mnoho rozhraní, mnoho formátů, spolehlivá opakovatelná provedení (idempotence) jsou důležité.
- Modernizace bez kompletního restartu: části logiky se vyčlení do services, zatímco desktopový klient se postupně zjednodušuje.
- REST-Server & Services mají být navrženy společně: stejný coding standard, stejné logging/monitoring, stejné rollout procesy.
Méně vhodné je nasazení Delphi-service pod Linux, pokud tým vůbec nemá Delphi-kompetenci a zároveň je předepsána standardizovaná platforma (např. existující Java/.NET ekosystém). V tom případě není problém v Delphi jako takovém, ale v organizačním začlenění. V mnoha firmách je Delphi však dostupná hodnota, kterou lze ve vrstvě services stabilně znovu použít – za předpokladu, že architektura a provoz jsou řádně naplánovány.
Architektonické základy: procesní model, stavy, odpovědnosti
Produktivní service málokdy ztroskotá na „hlavní funkci“. Častěji to jsou nejasné stavy: co se stane při výpadku sítě? Jak se služba chová při failoveru DB? Bude job zpracován dvakrát? Je definované chování při SIGTERM? Právě proto potřebuje každý service jasný procesní a stavový model.
Typy služeb: Always-on vs. Worker vs. Job-Runner
V B2B prostředí se ustálily tři základní typy:
- Always-on Daemon: trvale běžící proces, např. listener, queue-consumer, event-dispatcher, websocket-/push-komponenta.
- Worker-Pool: více instancí zpracovává paralelně joby z fronty. Škálování se provádí počtem procesů.
- Job-Runner (Timer): spouští se periodicky, vykoná úlohy a ukončí se. Pod Linux často vhodnější použít systemd timer/cron než vlastní plánovače v threadu.
Delphi dokáže pokrýt všechna tři vzory. Pro provoz je nicméně rozhodující, aby byl vzor vědomě zvolen. „Always-on“ proces, který ve skutečnosti dělá něco jen každých 15 minut, přináší zbytečnou komplexitu (memory-leaky se projeví později, idle-stavy nejsou řádně ošetřeny). Naopak čistý job-runner může být nevhodný, pokud je požadována nízká latence.
Idempotence a restartovatelnost: jádro produktivní odolnosti
Produktivní provoz znamená: služby jsou restartovány, probíhá deployment, sítě jsou dočasně nestabilní, databáze mají okna údržby a joby se mohou objevit dvakrát. Proto je idempotence (opakované provedení bez vedlejších efektů) u importů, exportů a integrací zásadní princip.
Prakticky to znamená:
- Každý job má jednoznačné job-ID a status (queued, running, succeeded, failed, dead-letter).
- Vedlejší efekty (např. „faktura odeslána“) se ukládají s dedikovaným důkazem, nikoli implicitně odvozené z logů.
- Retry-strategie jsou řízené: backoff, maximální počet pokusů, jasná kritéria pro ukončení, dead-letter-queue.
Kdo idempotenci důsledně zavede, získá v provozu výraznou výhodu: restart pak není krize, ale standardní stav.
systemd jako provozní základ: start, stop, restart, limity
Pod Linux je systemd v většině distribucí centrálním nástrojem pro řízení služeb v provozu. Pro Delphi-services není systemd „pouze“ startovacím skriptem, ale součástí stability architektury. Dobře definovaný unit-file často dělí rozdíl mezi „nějak to běží“ a „lze to profesionálně provozovat“.
Důležité parametry v unit-file
Pro typické Delphi-daemon jsou relevantní následující aspekty:
- Restart-Policy: např. Restart=on-failure nebo always, v kombinaci s RestartSec, aby se zabránilo crash-loopům.
- TimeoutStopSec a KillSignal: umožňují řízené vypnutí (flush front, čisté uzavření DB transakcí).
- User/Group: služby by neměly běžet jako root; principle of least privilege.
- WorkingDirectory a Environment: reprodukovatelné cesty a prostředí namísto implicitních předpokladů.
- LimitNOFILE a limity zdrojů: důležité při mnoha současných spojení/souborech.
- Propojení logování: StandardOutput/StandardError do journald, případně přesměrování do centrálních log-systémů.
Přesně zvolené Restart-Policy jsou kritické. Proces, který se kvůli konfigurační chybě okamžitě ukončí, by neměl být v nekonečné restartovací smyčce a zahlcovat systém. V takových případech má smysl fail-fast s jasnou chybovou hláškou a odpovídajícím exit-code.
Graceful Shutdown v Delphi: SIGTERM není detail
V provozu pod Linux je service obvykle ukončen signálem SIGTERM. Delphi-service by měl tento případ považovat za normální stav: žádné náhlé přerušení, ale řádné ukončení.
To v praxi zahrnuje:
- nastavení stop-flagu, nepřijímat nové joby.
- dokončit běžící joby nebo je kontrolovaně přerušit (dle semantiky).
- transakce čistě commit/rollback, uzavření spojení.
- perzistence důležitých stavových informací (např. „Job X přerušen, retry možný“).
Service, který při SIGTERM „tvrdě umře“, vytváří nekonzistence a ztěžuje údržbu.
Konfigurace: reprodukovatelná, verzovatelná, bezpečná
Mnoho produkčních problémů má v jádru problém s konfigurací: špatný DB-host, nesprávné credentials, chybějící cesty, rozdílné timeouty mezi prostředími. Proto konfigurace není jen „jedna INI-soubor“, ale koncept.
Zdroj konfigurace a priority
Osvědčil se vícestupňový model:
- Default konfigurace v kódu (bezpečná baseline, rozumné timeouty).
- Konfigurační soubory (např. INI/JSON/YAML), které lze verzovat a nasazovat.
- Environment proměnné pro secrets a prostředí-specifické hodnoty (v kontejnerech/CI, žádné secrets v repozitáři).
Důležitá je jasná priorita (např. Env přepíše soubor přepíše Default) a start-check, který validuje konfiguraci: povinná pole, dostupnost, práva k souborům, minimální rozsahy hodnot.
Secrets: ne v plaintextu, ne v logu
V B2B prostředích patří databázová hesla, API tokeny, certifikáty a privátní klíče mezi nejcennější provozní assety. Minimální standardy:
- Secrets ne v Gitu a ne v nasazených konfiguračních souborech v plaintextu, pokud je to možné vyhnout se.
- Čtecí práva k configu/secrets jen pro service-user.
- Výstupy do logů důsledně maskují secrets (i v případě výjimek).
Ať už se používá vault systém nebo klasické nasazení s restriktivními právy: rozhodující je, že nakládání se secrets je systematické.
Logging: od „chybového textu“ k provozní diagnostice
Produktivní Linux-service je jen tak dobrý, jak dobrá je jeho diagnostika. „Došlo k chybě“ nepomůže. V poruše musí provoz i vývoj umět zpětně zjistit: jaký byl input? Která verze běžela? V jakém kroku nastala chyba? Šlo o transientní chybu nebo problém s daty?
Strukturované logování a korelační ID
Pro služby s rozhraními (REST, MQ, importy souborů) jsou dvě věci klíčové:
- Strukturované logování (key-value, JSON-like): service, version, env, job_id, customer_id (pokud je to dovoleno), duration_ms, result.
- Korelační-ID: ID, které se nese mezi komponentami (např. z REST-requestu do worker-jobu).
Tím se produkční chyby nejen naleznou, ale i zúží: týká se to všech zákazníků? Pouze jednoho zdroje dat? Jen jedné verze? Jen jedné instance?
Úrovně logů, šum a operační signály
Častým anti-vzorem je příliš mnoho logů bez signifikantního signálu: megabyty „Processing…“ při každém pollu. Místo toho:
- INFO: relevantní změny stavu (start, stop, konfigurace načtena, job spuštěn/dokončen).
- WARNING: očekávané odchylky (retry, transientní síťová chyba, timeouts).
- ERROR: neočekávané, vyžaduje manuální zásah.
- DEBUG: aktivovatelné cíleně, časově omezené.
V prostředích systemd/journald má smysl plánovat rotaci logů a dobu uchování. Bez retention konceptu budou logy buď příliš krátce dostupné (žádná diagnostika) nebo zaplní úložiště (provozní problém).
Monitoring a health: ne jen „běží“ – ale „dodává“
Proces může běžet a přitom být odborně mrtvý (visí v deadlocku, čeká na IO nebo už nepracuje s joby). Produkční zralost znamená: monitoring nekontroluje jen stav procesu, ale zdraví služby.
Health checks: Liveness, Readiness, Business-Checks
Pro Delphi-services jsou smysluplné tři úrovně:
- Liveness: proces žije (systemd status, watchdog, jednoduchý ping endpoint).
- Readiness: služba je připravena (DB spojení dostupné, konfigurace validní, závislé systémy dostupné).
- Business-Check: služba skutečně zpracovává; např. „poslední úspěšný job < 10 minut“ nebo „délka fronty < prahová hodnota“.
Business úroveň je v B2B provozu často nejdůležitější, protože měří skutečnou hodnotu.
Metriky: časy běhu, chybovost, backlog
Jak služby rostou, logy samy nestačí. Metriky pomáhají odhalit trendy:
- Propustnost (jobs/min), průměrná doba jobu, p95/p99 doba běhu.
- Retry-rate, chybovost podle kategorie (síť, data, autentizace).
- Fronty backlog, čekací doby, čítač dead-letterů.
I bez komplexního observability stacku lze s pomocí jednoduchých exportů (např. interní HTTP endpoint nebo parsování logů) dosáhnout mnoho. Důležité je důsledné definování metrik a prahů.
Přístup k datům a transakce: FireDAC, správa připojení, pooling
Mnoho Delphi-services je databázově centrálních. Pod Linux je přístup v Delphi typicky organizován přes BDE-Ablösung s nativním napojením a nativní klientské knihovny. Pro produkční zralost nejsou klíčové „správné ovladače“ tolik jako model životního cyklu připojení a transakcí.
Životní cyklus připojení: krátkodobé vs. dlouhodobé
Pro background joby je osvědčená praxe:
- Pro job nebo dávku jobů otevřít connection, zpracovat, zavřít (odolné vůči výpadkům sítě).
- U vysoce frekventovaných jobů případně použití connection-poolu, ale pouze s čistým resetem mezi joby.
Dlouhotrvající spojení mohou fungovat, ale při přerušení sítě nebo DB failoveru rychle přejdou do těžko diagnostikovatelných stavů. Krátkodobé connection jsou často robustnější výchozí strategií – s adekvátními timeouts a retry.
Transakční hranice a chování zámků
Produkční problémy často vznikají z příliš velkých transakcí: dlouhé zámky, blokované tabulky, „všechno visí“. Lepší je:
- Transakce vymezit podle fachových jednotek (např. „jeden importní záznam“ nebo „jeden dokument“).
- Perzistence mezivýsledků, aby byl možný opětovný běh.
- Chyby klasifikovat: data-error (ne retry), síťová chyba (retry), vedlejší efekt již proveden (řešit idempotentně).
Obzvlášť u paralelních workerů je chování zámků a deadlocků návrhovým faktorem – ne pouze DBA tématem.
Nasazení a aktualizace: reprodukovatelné, rollbackovatelné, s minimálním rizikem
Service nikdy není „hotový“; bude aktualizován. Proto není deployment dodatečná práce, ale součást řešení. V produkci platí tři vlastnosti: reprodukovatelnost, rollbackovatelnost a nízké výpadky.
Verzování a artefakty
Osvedčené postupy jsou:
- Každý build nese jednoznačné číslo verze (SemVer nebo build-ID) a zapíše je do logů při startu.
- Artefakty jsou immutable: stejná verze se znovu „nepřestaví“ a nepřepíše.
- Závislosti (např. nativní knihovny) jsou součástí nasazení nebo jasně dokumentované.
Tím se předejde běžnému produkčnímu problému, že „verze X“ na různých serverech ve skutečnosti drobně liší.
Strategie aktualizací: Rolling, Blue/Green, Stop/Start
Volba strategie závisí na vzoru:
- Stop/Start: pro job-runner nebo nekritické služby; jednoduché, ale s krátkým down-timem.
- Rolling Update: více instancí se postupně restartuje; frontově orientované systémy se pro to hodí.
- Blue/Green: dvě oddělené prostředí, přepnutí přes load-balancer; vyšší náklady, minimální riziko.
Důležité: update je bezpečný jen tehdy, když služba při startu očekává kompatibilní verzi DB/schematu nebo když migrace běží kontrolovaně. Změny schémat jsou samostatný rollout krok s plánem (dopředu/dozadu kompatibilní, nebo s oknem údržby).
Bezpečnost a provozní hardening: malé kroky, velký efekt
Linux-services často pracují blízko dat, rozhraní a credentials. Proto není hardening luxus. Několik základních standardů výrazně sníží rizika.
Princip nejmenších práv a práva k souborům
- Vlastní service-user bez shell-loginu, minimální skupinová práva.
- Konfigurační a secret soubory čitelné pouze tímto userem.
- Zapisovací práva pouze tam, kde jsou nezbytná (např. Working-Directory, spool, temp).
Síťové hranice a správa portů
Pokud Delphi-service otevírá porty (např. jako REST-Server), patří k tomu:
- Bind na interní rozhraní, pokud není požadována externí dostupnost.
- Pravidla firewallu a segmentovaná síť namísto „otevřeno v LAN“.
- Plánování TLS-terminace (reverse proxy, rotace certifikátů) dle prostředí.
I interně platí: služby by neměly předpokládat, že volají pouze „důvěryhodní klienti“. Autentizace a autorizace jsou součástí návrhu.
Typické chybové vzory v praxi – a jak se jim vyhnout
V produkčním provozu se často opakují vzory, které týmům zabírají čas. Několik častých případů a opatření:
„Service běží, ale nic neprobíhá“
- Příčina: deadlock, blokující IO, tiché reconnect-problémy.
- Opatření: timeouts všude; watchdog/health-business-check; worker-architektura místo single-thread; fail-fast při poškozené závislosti.
„Po updatu jsou joby duplicitní“
- Příčina: chybějící idempotence, žádná dedikovaná job-tabule, vedlejší efekty nejsou atomické.
- Opatření: job-status v DB, jednoznačné constraints, outbox-/inbox-vzor, deduplikovatelné eventy.
„Logy nepomáhají – jen stacktracy bez kontextu“
- Příčina: nestrukturované logování, žádné korelační ID, bez kontextu jobu.
- Opatření: strukturovaná logová pole, job-ID, zdroj inputu, doba trvání, výsledek, třída chyby.
„Service padá při zátěži“
- Příčina: nekontrolovaná paralelita, chybějící backpressure, příliš mnoho DB spojení, příliš velké transakce.
- Opatření: limity workerů, délky front, limity spojení, malé transakce, buffery a retry.
Souhra s REST-servery a existujícím podnikovým software
V mnoha architekturách není jeden jediný service, ale balík REST-server, background-worker a klienti. V Delphi-projektech je často rozumné držet společnou fachlogiku v jasných modulech, zatímco transportně a provozně specifické části oddělit.
Oddělení vrstev (fachově i technicky)
Pragmatická struktura:
- Domain/Fachlogik: pravidla, validace, výpočty, use-casy.
- Infrastruktura: DB přístup, souborový systém, HTTP klienti, messaging.
- Adaptery: REST-endpointy, service-loop, CLI-runner, systemd-blízká startovací logika.
Toto oddělení není akademické. Umožňuje, aby stejná fachlogika byla využita v REST-serveru i ve workeru, zatímco provozní aspekty (timeouts, retries, logging, health) mohou být implementovány konzistentně.
Multiplatformní myšlení: Delphi jako jednotná kódová báze
Pokud firmy používají Delphi pro Windows-klienty, může být Linux-service logickým dalším krokem: stejný jazyk, podobné knihovny, jednotné build-pipeline. Zisk však vzniká jen tehdy, když se vědomě respektují hranice platforem (cesty k souborům, case-sensitivity, locale/encoding, práva service-usera, conventions nasazení). Multiplatformní provoz je v praxi vždy „detailní práce“ – proto by se měl plánovat včas.
Praktický checklist: co produktivní Delphi-Linux-service minimálně potřebuje
- systemd unit se smysluplnými restart-/timeout pravidly, vlastní service-user, definované cesty.
- Graceful shutdown (SIGTERM), žádné datové nekonzistence při stopu.
- Konfigurační model s validací, bezpečné secrets, žádné secrets v logu.
- Strukturované logování s verzí, job-ID, korelační-ID, dobou trvání, třídou chyby.
- Health checks (alespoň readiness + business-check) a definované metriky.
- Idempotentní zpracování jobů, retry/backoff, koncept dead-letteru.
- Deployment s jasným verzováním, rollback strategií, plánovatelnými migracemi schémat.
- Koncepce zdrojů a zátěže: paralelita, limity, timeouts, správa spojení.
Závěr: Delphi pod Linux není výjimka – pokud se počítá s provozem
Linux-services s Delphi jsou v produkčním provozu velmi solidní volbou, pokud jsou považovány za plnohodnotnou součást systému: s jasnou architekturou, řádnou integrací do systemd, robustním modelem chyb a stavů, srozumitelným loggingem, monitoringem a reprodukovatelným nasazením. Technická implementace zřídkakdy představuje hlavní riziko; riziko je v „provozních detailech“, které se řeší příliš pozdě.
Kdo tyto detaily plánuje od začátku, získá udržovatelnou servisní krajinu, která konzistentně využívá fachlogiku, spolehlivě realizuje integrace a je v každodenním provozu ovladatelná – včetně aktualizací, restartů a poruch.
Pokud chcete prověřit, jak lze vaši existující Delphi-fachlogik převést do Linux-services, workerů a REST-serverů (včetně provozního a deployment konceptu), vyjasníme okrajové podmínky rádi strukturovaně v technickém úvodním rozhovoru: Kontakt.
další krok
Když se z tématu stane reálný projekt, měly by být architektura, stávající systém a provoz posuzovány společně již v rané fázi.
Podporujeme nejen při jednotlivých otázkách, ale i v případě, že se z útržků zdrojového kódu, legacy témat nebo nápadů na portál má vyvinout robustní podnikový projekt.
- Současný stav, cílový stav a technická rizika jsou hodnoceny společně.
- REST, přístup k datům, portály a rollout nebudou přesunuty do pozdějších fází.
- Včas zjistíte, která varianta je ekonomicky i provozně životaschopná.