2017-01-24 3 views
0

Je suis à la recherche d'un moyen ou d'une meilleure/meilleure décision de conception pour un problème d'enregistrement. J'utilise des acteurs Akka dans les clusters pour mes services dorsaux et Play dans le frontal pour accepter les requêtes HTTP. Ma question est en quelque sorte étendue de l'ancienne question de l'ensemble du journal de l'application pour être identifiable aux mêmes requêtes HTTP, qui utilisent simplement le MDC qui existe dans la plupart des frameworks de journalisation actuels en générant un UUID au début et mettre dans le contexte .Regroupement/identification des journaux d'acteurs pour la même "demande"

Un exemple de notre flux de données pourrait ressembler à:

"Http Demande/Système A" -> "actionneur1/Cluster B" -> "Actor2/Groupe C" -> « Répondre au système A et complet demande "

Cela signifie qu'il y a au moins 3 systèmes distincts impliqués dans le processus. Tout mon journal va à Logstash. Je peux générer un UUID depuis le début de la requête depuis le Système A. Cependant, je souhaite que l'UUID puisse être reporté sur tous les sous-systèmes, qui utilisent tous la sérialisation Protobuf pour communiquer entre eux, traiter les tâches d'appartenir à la même demande http.

Je sais que je peux toujours ajouter un champ id à tous mes messages, mais c'est très moche.

Je me demande s'il existe un meilleur moyen ou un meilleur mécanisme pour transmettre l'information à tous les autres systèmes Akka d'appel sans introduire trop de bruit dans mon traitement de la logique métier?

+0

"moche" option est le seul que je connaisse. – Rumoku

+0

Vous pouvez rendre votre génération d'identifiant déterministe basée sur la requête http, de cette façon tous vos systèmes génèreront simplement le même identifiant lors de la connexion. – C4stor

+0

@ C4stor Je ne suis pas tout à fait sûr comment cela pourrait être fait. En fait, excepté le point d'entrée sur le système A, tous les autres systèmes d'acteur reçoivent la sérialisation protobuf et je suppose que je n'étais pas clair sur ce point, désolé à ce sujet. – lunaspeed

Répondre

1

Vous pouvez envelopper vos messages originaux dans un récipient avec UUID:

case class MessageWithUuid(message: Any, uuid: UUID) 

Ensuite, dans votre receive vous devez déballer et de préserver uuid pour l'enregistrement:

var uuid: Option[UUID] = 
def receive: Receive = { 
    case MessageWithUuid(message, uuid) => 
    this.uuid = Some(uuid) 
    //TODO: put UUID to MDC logging context 
    receive(message) 
    //TODO: remove UUID from MDC 
    this.uuid = None 
    case ... => 
} 

Et chaque fois que vous envoyez un message à un autre acteur, vous devez envelopper avec UUID:

def send(actor: ActorRef, message: Any) = actor ! MessageWithUuid(message, uuid.get) 
+0

cela ressemble à la "id partout", mais en effet une meilleure solution. cependant j'ai oublié de mentionner que j'utilise la sérialisation Protobuf, et j'ai édité mon post, ce qui semble troublant pour ce genre d'approche. – lunaspeed