Del tema de la revista a la pràctica del projecte
Pàgines de serveis i tècniques pertinents per a l'article
Video-Botschaft
Serveis Linux amb Delphi en funcionament productiu
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.
Els serveis en segon pla són en moltes aplicacions empresarials la palanca silenciosa de productivitat: imports de dades, exports, processament de fitxers i EDI, sincronització amb ERP/DMS/CRM, fluxos de treball programats, notificacions o l’exposició d’interfícies tècniques. A la pràctica, però, no és la mera funció de negoci la que determina l’èxit, sinó la pregunta: es pot operar el servei de manera fiable, actualitzar-lo, monitoritzar-lo i restaurar-lo controladament en cas d’error?
Aquí és on convé una mirada pragmàtica als Linux-Services amb Delphi. Delphi ja sustenta la lògica de negoci en moltes organitzacions. Si aquesta lògica es pot reutilitzar de manera sensata al costat del servidor, es genera una arquitectura global coherent: les regles de negoci no s’implementen per duplicat, les interfícies es mantenen estables i els equips treballen amb un tooling establert. Alhora, Linux porta al món servidor components provats per a l’operació, l’automatització i la seguretat.
El punt decisiu: un servei Linux no és un «petit utilitari» que s’executa de tant en tant. És una peça del producte amb responsabilitat d’operació. Aquest article mostra de manera concreta com muntar serveis Linux basats en Delphi per a producció robusta: des del model de procés i d’estats fins a la integració amb systemd, logging, deployment i updates, així com monitoratge, accés a dades, seguretat i patrons d’error típics. L’objectiu és un setup que funcioni en el dia a dia —fins i tot a les 3 de la nit.
Quan té sentit fer serveis Delphi sota Linux
Un servei Delphi-Linux és una opció òbvia quan es compleix un o diversos dels patrons següents:
- Hi ha lògica de negoci Delphi existent que cal reutilitzar al servidor (p. ex. validacions, càlculs, regles, parsers d’import/export).
- Processament en segon pla és part integral de l’aplicació (p. ex. pipelines PDF/reporting, cues de feina, processament batch).
- La càrrega d’integració augmenta: molts sistemes, moltes interfícies, molts formats; la repetibilitat fiable (idempotència) esdevé important.
- Modernització sense començar de zero: parts de la lògica es desplacen a serveis mentre el client d’escriptori s’alleugereix pas a pas.
- REST-Server & Services s’han de pensar conjuntament: mateix estàndard de codi, mateix logging/monitoring, mateixos processos de rollout.
Menys adient és un servei Delphi sota Linux quan un equip no té cap competència en Delphi i l’organització imposa estrictament una plataforma estandarditzada (p. ex. un ecosistema Java/.NET ja existent). En aquest cas, el problema no és Delphi sinó la integració organitzativa. En moltes empreses, però, Delphi és un actiu existent que es pot reutilitzar de manera estable en la capa de serveis, sempre que l’arquitectura i l’operació estiguin ben planificades.
Fonaments d’arquitectura: model de procés, estats, responsabilitats
Un servei productiu rarament fracassa per la «funció principal». Sovint ho fa per estats poc clars: què passa davant d’una fallada de xarxa? Com es comporta el servei durant un failover de base de dades? S’executa una feina dues vegades? S’ha definit el comportament davant SIGTERM? Per això cada servei necessita un model clar de procés i d’estats.
Tipus de servei: Always-on, Worker, Job-Runner
En l’entorn B2B s’han consolidat tres tipus bàsics:
- Daemon sempre actiu: procés en execució permanent, p. ex. listener, consumer de cues, event-dispatcher, component websocket/push.
- Pool de workers: diverses instàncies que processen en paral·lel jobs d’una cua. L’escalat es fa augmentant el nombre de processos.
- Executors de jobs periòdics (Job-Runner/Timer): s’inicien periòdicament, completen tasques i s’aturen. Sota Linux sovint és millor usar timers systemd/cron en lloc d’schedulers propis en threads.
Delphi pot cobrir els tres patrons. Per a l’operació, però, és crític triar el patró de manera conscient. Un procés «sempre actiu» que, en realitat, només fa alguna cosa cada 15 minuts introdueix complexitat innecessària (p. ex. fugues de memòria apareixen més tard, estats d’inactivitat no es gestionen bé). De la mateixa manera, un job-runner pur pot ser inadequat si es requereix baixa latència.
Idempotència i reexecució: el nucli de la robustesa productiva
Operar en producció vol dir: serveis es tornen a iniciar, hi ha deployments, xarxes inestables temporalment, finestres de manteniment a BD i jobs que arriben duplicats. Per això la idempotència (executar diverses vegades sense efectes col·laterals) és un principi rector en imports, exports i integracions.
A la pràctica això vol dir:
- Cada job té una ID de job única i un estat (queued, running, succeeded, failed, dead-letter).
- Els efectes secundaris (p. ex. «factura enviada») es registren amb una evidència dedicada, no s’inferexen implícitament dels logs.
- Les estratègies de reintents són controlades: backoff, intents màxims, criteris clars d’aturada, dead-letter-queue.
Qui implementa idempotència amb cura guanya molt en operació: un reinici deixa de ser una crisi i passa a ser un cas estàndard.
systemd com a fonament d’operació: Start, Stop, Restart, Limits
Sota Linux systemd és, en la majoria de distribucions, l’eina central per gestionar serveis en producció. Per als serveis Delphi systemd no és «només» un script d’arrencada, sinó part de l’arquitectura d’estabilitat. Un Unit-File ben definit sovint és la diferència entre «funciona d’alguna manera» i «es pot operar de forma professional».
Paràmetres importants en l’Unit-File
Per a daemons típics Delphi són rellevants els aspectes següents:
- Restart-Policy: p. ex. Restart=on-failure o always, combinat amb RestartSec per evitar crash-loops.
- TimeoutStopSec i KillSignal: permeten un shutdown ordenat (esborrar cues, tancar transaccions de BD correctament).
- User/Group: els serveis no haurien d’executar-se com a root; principle of least privilege.
- WorkingDirectory i Environment: rutes i entorns reproducibles en lloc d’assumpcions implícites.
- LimitNOFILE i límits de recursos: importants amb moltes connexions/fitxers simultanis.
- Integració de logging: StandardOutput/StandardError cap a journald, i si cal reenviament a sistemes centrals de logs.
Precisament les Restart-Policies han de triar-se amb cura. Un procés que falli immediatament per un error de configuració no hauria d’entrar en un bucle infinit de reinicis que sobrecarregui el sistema. En aquests casos, codis d’exit i un «fail fast» amb un missatge d’error clar són desitjables.
Graceful Shutdown en Delphi: SIGTERM no és un detall
En l’operació sota Linux un servei normalment es termina amb SIGTERM. Un servei Delphi hauria de tractar aquest cas com un estat normal: no talls abruptes sinó una finalització ordenada.
Això inclou a la pràctica:
- Posar un flag d’aturada, no acceptar jobs nous.
- Deixar que els jobs en curs acabin o abortar-los de manera controlada (segons la semàntica).
- Commit/rollback net de transaccions, tancament de connexions.
- Persistir informació d’estat rellevant (p. ex. «Job X aturat, reintentar possible»).
Un servei que «mor» bruscament en rebre SIGTERM genera incoherències i complica qualsevol manteniment.
Configuració: reproducible, versionable, segura
Molts problemes en producció són, al capdavall, problemes de configuració: host de BD equivocat, credencials incorrectes, rutes inexistents, valors de timeout divergents entre entorns. Per això la configuració no és només «un fitxer INI», sinó un concepte.
Fonts de configuració i prioritats
Un model multinivell ha demostrat ser eficaç:
- Configuració per defecte en el codi (baseline segur, timeouts raonables).
- Configuració basada en fitxers (p. ex. INI/JSON/YAML), que es pot desplegar amb control de versions.
- Variables d’entorn per a secrets i especificitats d’entorn (adequat per contenedors/CI, sense secrets al repo).
És important una prioritat clara (p. ex. Env sobreescriu fitxer sobreescriu Default) i un check d’arrencada que validi la configuració: camps obligatoris, accessibilitat, permisos de fitxer, rangs mínims de valors.
Secrets: no en text pla, no en logs
En entorns B2B, contrasenyes de BD, tokens d’API, certificats i claus privades són actius operacionals crítics. Estàndards mínims:
- No posar secrets a Git ni a fitxers de configuració desplegats en text pla, si es pot evitar.
- Permisos de lectura dels fitxers de config/secrets només per l’usuari del servei.
- La sortida de logs ha d’ocultar secrets de manera sistemàtica (també en excepcions).
Si s’usa un sistema de Vault o desplegaments clàssics amb permisos restrictius: el que importa és que el tractament dels secrets sigui sistemàtic.
Logging: del «text d’error» a la capacitat de diagnosi operativa
Un servei Linux productiu és tan bo com la seva capacitat de diagnosi. «Hi ha hagut un error» no ajuda. En cas d’incidència, operació i desenvolupament han de poder reconstruir: quin va ser l’input? Quina versió s’executava? En quin pas va ocórrer l’error? Va ser un error transitori o un problema de dades?
Logging estructurat i IDs de correlació
Per a serveis amb interfícies (REST, MQ, imports de fitxers) són centrals dues coses:
- Logging estructurat (clau-valor, tipus JSON): service, version, env, job_id, customer_id (si està permès), duration_ms, result.
- ID de correlació: una ID que es porta entre components (p. ex. des de la petició REST al job del worker).
Això permet localitzar errors de producció i aïllar-los: afecta tots els clients? Només una font de dades? Només una versió? Només una instància?
Nivell de logs, soroll i senyals operatius
Un anti-patró comú són massa logs sense senyal: megabytes de «Processing…» a cada poll. En lloc d’això:
- INFO: canvis d’estat rellevants (Start, Stop, config carregada, Job iniciat/completat).
- WARNING: desviacions esperables (Retry, error de xarxa transitori, timeouts).
- ERROR: inesperat, requereix acció manual.
- DEBUG: activable de manera selectiva i amb límit de temps.
En entorns systemd/journald convé planificar la rotació i la retenció de logs. Sense una política de retenció, els logs o bé s’emmagatzemen massa poc temps (sense possibilitat de diagnosi) o bé ocupen massa espai (problema operatiu).
Monitoratge i Health: no només «s’executa» sinó «entrega»
Un procés pot estar en execució però està mort des del punt de vista funcional (bloquejat en un deadlock, esperant IO o sense processar jobs). La maduresa de producció significa: el monitoratge comprova no només l’estat del procés, sinó la salut del servei.
Health Checks: Liveness, Readiness, Business-Checks
Per als serveis Delphi són útils tres nivells:
- Liveness: el procés viu (estat systemd, watchdog, endpoint ping senzill).
- Readiness: el servei està llest (connexió a BD possible, configuració vàlida, sistemes dependents accessibles).
- Business-Check: el servei processa realment? p. ex. «últim job amb èxit < 10 minuts» o «longitud de la cua < llindar».
El nivell Business sovint és el més important en l’operació B2B, perquè mesura la creació real de valor.
Mètriques: temps d’execució, taxes d’error, backlog
A mesura que els serveis creixen, els logs ja no són suficients. Les mètriques ajuden a veure tendències:
- Throughput (jobs/min), durada mitjana d’un job, p95/p99 de latència.
- Taxa de reintents, taxa d’errors per tipus (xarxa, dades, autenticació).
- Backlog de cues, temps d’espera, comptadors de dead-letter.
Fins i tot sense un stack d’observabilitat complex, es pot fer molt amb exportacions simples (p. ex. un endpoint HTTP intern o parsing basat en logs). El que importa és la definició constant de les mètriques i els llindars.
Accés a dades i transaccions: FireDAC, maneig de connexions, pooling
Molts serveis Delphi estan centrats en base de dades. Sota Linux l’accés amb Delphi acostuma a passar per la BDE-Ablösung amb connexió nativa i biblioteques natives de client. Per a la maduresa en producció, més que els «drivers correctes», el que compta és el model de connexió i de transacció.
Cicle de vida de la connexió: efímera vs perllongada
Per a jobs en segon pla és una pràctica recomanada:
- Obrir una connexió per cada job o batch de jobs, treballar i tancar-la (robust davant fallades de xarxa).
- En jobs d’alta freqüència, considerar pooling de connexions, però només amb un reset net entre jobs.
Les connexions llargues poden funcionar però fallen més ràpidament en interrupcions de xarxa o failovers de BD i deixen estats difícils de diagnosticar. Les connexions curtes solen ser la estratègia per defecte més robusta, amb timeouts i reintents adequats.
Fronteres de transacció i comportament de bloqueig
Els problemes en producció sovint venen de transaccions massa grans: locks llargs, taules bloquejades, «tot penja». Millor:
- Alinear transaccions amb unitats de negoci (p. ex. «un registre d’import» o «un document»).
- Persistir resultats intermedis per permetre la reexecució.
- Classificar errors netament: error de dades (no reintentar), error de xarxa (reintentar), efecte secundari ja aplicat (tractar com a idempotent).
En especial amb workers paral·lels, el comportament de bloqueig i deadlock és un factor de disseny, no només una qüestió de DBA.
Deployment i actualitzacions: reproducible, reversable, amb risc mínim
Un servei mai està «acabat»; s’actualitza. Per això el deployment no és feina posterior sinó part de la solució. En producció compten tres característiques: reproducibilitat, capacitat de rollback i baixes interrupcions.
Versionat i artefactes
Són pràctiques recomanades:
- Cada build té un número de versió únic (SemVer o Build-ID) i l’escriu als logs a l’arrencada.
- Els artefactes són immutables: la mateixa versió no es reconstrueix i es sobreescriu.
- Les dependències (p. ex. llibreries natives) formen part del desplegament o estan documentades clarament.
Això evita el problema habitual en producció que la «versió X» sigui lleugerament diferent segons el servidor.
Estratègies d’actualització: Rolling, Blue/Green, Stop/Start
Quina estratègia cal depèn del patró:
- Stop/Start: per job-runners o serveis no crítics; senzill, però amb una curta indisponibilitat.
- Rolling Update: diverses instàncies es reinicien una a una; adequat per sistemes basats en cues.
- Blue/Green: dues entorns separats i commutació via load-balancer; més cost, mínim risc.
Important: una actualització és segura només si el servei espera una versió de BD/esquema compatible a l’inici o si les migracions s’executen de manera controlada. Els canvis d’esquema són un pas de rollout propi amb pla (compatibilitat endavant/enrere o finestra de manteniment).
Seguretat i enduriment operatiu: mesures petites, gran impacte
Els serveis Linux sovint toquen dades, interfícies i credencials. Per això l’enduriment no és un luxe. Pocs estàndards redueixen el risc de manera significativa.
Least Privilege i permisos de fitxer
- Usuari de servei propi sense accés a shell, permisos de grup mínims.
- Fitxers de configuració i secrets només llegibles per aquest usuari.
- Permisos d’escriptura només allà on cal (p. ex. Working-Directory, spool, temp).
Límits de xarxa i gestió de ports
Si un servei Delphi obre ports (p. ex. com a REST-Server), cal:
- Enllaçar a interfície internes si no cal exposició externa.
- Regles de tallafocs i xarxes segmentades en lloc d’estar «obert a la LAN».
- Planificar la terminació TLS (reverse proxy, rotació de certificats) segons l’entorn.
Fins i tot en xarxes internes, els serveis no han de confiar en què només clients «bons» faran peticions. Autenticació i autorització formen part del disseny.
Patrons d’error típics a la pràctica — i com evitar-los
En operació productiva sovint es repeteixen patrons que fan perdre temps als equips. Alguns casos típics i contramesures:
«El servei està en execució però no processa res»
- Causes: deadlock, IO bloquejant, problema de reconnect silenciós.
- Contramesures: timeouts arreu; watchdog/health-business-check; arquitectura de workers en lloc de single-thread; fail-fast davant dependències trencades.
«Després d’una actualització els jobs es dupliquen»
- Causes: falta d’idempotència, no tenir una taula de jobs dedicada, efectes secundaris no atòmics.
- Contramesures: estat de job a la BD, constraints úniques, patrons Outbox/Inbox, events deduplicables.
«Els logs no ajuden — només stacktraces sense context»
- Causes: logging no estructurat, manca d’ID de correlació, sense context de job.
- Contramesures: camps de log estructurats, Job-ID, font d’input, durada, resultat, classe d’error.
«El servei cau sota càrrega»
- Causes: paral·lelisme descontrolat, falta de backpressure, connexions BD en excés, transaccions massa grans.
- Contramesures: límits de workers, longituds de cua, límits de connexió, transaccions petites, buffers i reintents.
Interacció amb REST-Servers i software empresarial existent
En moltes arquitectures no hi ha «un sol servei», sinó un paquet format per REST-Server, background-workers i clients. En projectes Delphi sovint és aconsellable mantenir la lògica de negoci comuna en mòduls clars i separar les parts específiques de transport i operació.
Separar capes netament (funcional i tècnica)
Una estructura pragmàtica:
- Domini/Lògica de negoci: regles, validació, càlculs, casos d’ús.
- Infraestructura: accés BD, sistema de fitxers, clients HTTP, messaging.
- Adaptadors: endpoints REST, bucle de servei, CLI-runner, lògica d’arrencada propera a systemd.
Aquesta separació no és acadèmica. Permet reutilitzar la mateixa lògica de negoci en el REST-Server i en el worker, mentre que els aspectes operatius (timeouts, reintents, logging, health) es poden implementar de manera coherent.
Enfocament multiplataforma: Delphi com a base de codi unificada
Si les empreses ja utilitzen Delphi per a clients Windows, un servei Linux pot ser el pas lògic següent: mateix llenguatge, biblioteques similars, pipelines de build uniformes. El benefici arriba només si es respecten conscientment els límits de plataforma (rutes de fitxers, case-sensitivity, locale/encoding, permisos d’usuari del servei, convencions de deployment). La multiplataforma en operació és sempre «treball de detall» — per això cal planificar-ho aviat.
Checklist pràctic: què necessita mínimament un servei Delphi-Linux productiu
- Unit systemd amb regles raonables de Restart/Timeout, usuari de servei propi, rutes definides.
- Graceful Shutdown (SIGTERM), sense incoherències de dades en l’aturada.
- Model de configuració amb validació, secrets segurs, cap secret als logs.
- Logging estructurat amb versió, Job-ID, ID de correlació, durada, classe d’error.
- Health Checks (com a mínim Readiness + Business-Check) i mètriques definides.
- Processament de jobs idempotent, Retry/Backoff, concepte de Dead-Letter.
- Deployment amb versionat clar, estratègia de rollback, migracions d’esquema planificables.
- Concepte de recursos i càrrega: paral·lelisme, límits, timeouts, maneig de connexions.
Conclusió: Delphi sota Linux no és un cas especial — si l’operació es pensa des d’un principi
Els serveis Linux amb Delphi són una opció molt sòlida en producció si es tracten com a components de sistema complets: amb arquitectura clara, integració neta amb systemd, model robust d’errors i d’estats, logging i monitoratge rastrejables i un deployment reproducible. La implementació tècnica rarament és el risc principal; el risc rau en els «detalls d’operació» que es resolen massa tard.
Qui planifica aquests detalls des de l’inici obtindrà un parc de serveis mantenible, que reutilitza la lògica de negoci de manera consistent, executa integracions de forma estable i es pot operar de manera fiable en el dia a dia —incloent actualitzacions, reinicis i incidències.
Si voleu examinar com es pot migrar la vostra lògica de negoci Delphi existent a serveis Linux, workers i REST-Servers (incloent concepte d’operació i deployment), podem aclarir les condicions marcant una conversa tècnica inicial de forma estructurada: Contacte.
Pas següent
Quan d'un tema se'ndevé un projecte real, s'han de considerar aviat i de manera conjunta l'arquitectura, els actius existents i l'operació.
No només donem suport en qüestions puntuals, sinó també quan, a partir de fragments de codi font, temes de sistemes heredats o idees de portal, ha de sorgir un projecte empresarial sòlid.
- L'estat actual, la visió objectiu i els riscos tècnics s'avaluen conjuntament.
- REST, accés a dades, portals i desplegament no es posposaran com a efectes retardats.
- Veu aviat quin camí és viable des del punt de vista econòmic i operatiu.