Skip to main content
Statut : un enregistrement de décision, pas un élément de roadmap. Rien sur cette page n’est implémenté. Il existe pour que la prochaine personne à demander « peut-on faire tourner deux de ceci ? » obtienne une vraie réponse au lieu de redécouvrir les contraintes depuis le source.
Non, pas aujourd’hui. Deux instances contre une seule base perdront la plupart des accusés de réception, et jusqu’à récemment double-créditaient chaque recharge prépayée. Ce qui suit est pourquoi, et ce qu’il faudrait. Pour des gateways indépendants sur un hôte, ce qui fonctionne bien, voir Plusieurs instances.

Ce qui est déjà cluster-safe

Plus que vous ne le penseriez. Le chemin d’envoi a été construit sans cluster en tête et est néanmoins correct à travers les instances.

Ce qui casse

Argent et enregistrements

Perte de messages

Toute la corrélation des accusés vit dans un stockage local au nœud.
  • Un accusé arrivant à une instance qui n’a pas soumis le message ne trouve rien, est supprimé avec une seule ligne de log, et ne produit pas d’accusé client, pas de webhook et pas de ligne cdr_final. Avec N instances c’est environ (N−1)/N de tous les accusés.
  • Le stockage prend un verrou fichier exclusif. La seconde instance à démarrer sur le même chemin échoue, l’échec est attrapé, journalisé en WARN, et elle continue silencieusement sans aucune persistance — donc « deux instances partageant un répertoire de données » ressemble à « en bonne santé ».
  • Les accusés non poussés sont parqués localement, donc un client se reconnectant à une instance différente ne les reçoit jamais.
  • Les sessions bindées sont suivies par JVM, donc une instance ne peut pas dire qu’un client est connecté ailleurs.

Messages concaténés, concrètement

Des segments arrivant sur différentes instances ne se réassemblent jamais. Pour un message à trois segments divisé deux-et-un sur deux instances :
  • chaque instance répond ESME_ROK et facture les segments qu’elle a reçus ;
  • chacune attend l’expiration de reassembling.timeoutMillis, 30 secondes par défaut ;
  • chacune transmet alors ses segments comme fragments orphelins portant un en-tête de concaténation pour un message qui ne se complètera jamais.
Le combiné les garde jusqu’à ce que son propre minuteur expire et ne montre typiquement rien. Le client est facturé pour les trois. La seule trace est un avertissement message.parts.incomplete par instance, dont aucune ne sait que l’autre existe.
La session SMPP d’un client est normalement sticky au niveau TCP, donc ceci mord à la reconnexion en milieu de message, au rééquilibrage du load balancer, et sur des clients tenant plusieurs binds qui répartissent les segments entre eux.Le whitelisting de contenu s’applique toujours à ce que chaque instance envoie. Le chemin de timeout est vérifié en contenu. L’échec est donc la livraison et la facturation, pas l’application.

Dégradé mais pas perdu

TPS vendeur, limites de débit d’ingress, échantillonnage de débit et curseurs de groupe de routage sont tous par processus. N instances envoient jusqu’à N × le débit contractuel à un opérateur. C’est un garde-fou contre un émetteur emballé, pas un quota distribué. Voir Limites.

Ce qu’il faudrait

En gros : déplacer la corrélation des accusés et le réassemblage dans un stockage partagé, donner à cdr_final une clé unique et un upsert, et rendre le sweeper élu-leader ou idempotent. Chacun est traitable ; aucun n’est fait. Jusque-là, mettez à l’échelle verticalement, et utilisez plusieurs instances indépendantes là où le trafic peut être partitionné par client.