Pergunta

Isto se baseia Como enviar mensagens entre empresas.Se eu decidir que a empresa S (fornecedor) deve pesquisar os pedidos da empresa (B) de alguma forma simples baseada em HTTP, qual é a melhor implementação.

  • Presumo que a Empresa B tenha um servidor Web em execução e o banco de dados back-end desse servidor Web seja durável.Devemos fazer o mínimo possível de suposições sobre os processos de armazenamento em S e se eles são capazes de manter o estado (por exemplo,uma lista de GUIDs já transmitidos)
  • A conexão com a Internet entre B e S não é confiável.
  • Temos que alcançar consistência eventual o que significa que em um determinado momento todos os pedidos entre B e S deverão ser transferidos.

Qual é a melhor prática para implementar tal sistema?

Foi útil?

Solução

Uma abordagem para esse tipo de problema é usar algum tipo de produto de fila. Como funcionário da IBM, considero imediatamente o MQ.No entanto, como na verdade não sou uma pessoa MQ, como você, provavelmente ficaria feliz com a abordagem baseada em serviços que você está adotando.

Existem duas abordagens possíveis que vêm à mente.Uma delas é usar o Mensagens Confiáveis ​​WS, o que empurra o problema de confiabilidade para a infraestrutura de serviços da Web.A outra é acionar manualmente seu próprio protocolo confiável em cima de serviços simples, mas não confiáveis.

Não tenho experiência prática séria na implementação de um sistema com WS Reliable Messaging, acredito que ele possa funcionar, mas requer algum grau de controle sobre os participantes - como é um padrão comparativamente recente, não podemos garantir que qualquer loja de TI terá uma implementação em mãos, e a interoperabilidade entre fornecedores pode ser um problema.Quanto mais controle eu tiver sobre as pilhas de SW em cada extremidade, mais inclinado estarei a usar o WS Reliable Messaging.[Devo mencionar também o WS Atomic Transaction, que também pode ser usado para construir serviços confiáveis, aplicando-se as mesmas preocupações de interoperabilidade.]

Então, que tal fazer o seu próprio?A chave aqui é tornar todos os serviços idempotentes.Como não temos garantias transacionais que abranjam os dois sistemas, devemos assumir que qualquer chamada de serviço pode falhar com resultado desconhecido.

Vou presumir que B deseja a confirmação de que S recebeu um pedido, portanto, precisamos atualizar as informações em B e S quando um pedido for transferido.

B deve oferecer serviços como estes:

 Give me the next order(s)

 I have stored {orders ...}

Então, como definimos “próximo”.O caso mais simples funciona bem se os volumes com os quais estamos lidando puderem nos permitir ter um único “thread” de transferência.Então B marca os pedidos enviados, um de cada vez, e os pedidos têm um ID crescente monotonicamente.Podemos então simplificar para:

 I have stored order <65,004> please give me the next

observe que esta é uma solicitação idempotente:pode ser repetido com segurança muitas vezes.Observe também que S deve antecipar a possibilidade de receber o mesmo pedido duas vezes e verificar se há duplicatas.

Outras dicas

O que você provavelmente está procurando é um compromisso de duas fases. Está bem descrito na Internet, aqui, por exemplo:

http://en.wikipedia.org/wiki/two-phase_commit_protocol

A essência disso:

O processo de confirmação prossegue da seguinte maneira:

* Phase 1
      o Each participating resource manager coordinates local 
        operations and forces all log records out:
      o If successful, respond "OK"
      o If unsuccessful, either allow a time-out or respond "OOPS" 
* Phase 2
      o If all participants respond "OK":
            * Coordinator instructs participating resource managers to "COMMIT"
            * Participants complete operation writing the log record
              for the commit 
      o Otherwise:
            * Coordinator instructs participating resource managers to "ROLLBACK"
            * Participants complete their respective local undos 

Deve funcionar para qualquer tipo de dados.

Ok, primeiro de tudo, você não pode garantia Qualquer coisa em um link não confiável. o Problema de dois generais prova isso para protocolos determinísticos e não determinísticos. Tudo o que você pode fazer é mitigar a falta de confiabilidade em um grau aceitável.

O método mais fácil é, no seu caso, depois que o servidor recebe uma solicitação de pesquisa, ele envia x número de respostas, tudo com o mesmo GUID. Por exemplo.

S: B, anything new?
S: B, anything new?
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
B: Yes, S, I need some shoes (order #124).
S: B, anything new?
B: Yes, S, I need a jacket (order #123).
B: Yes, S, I need some shoes (order #124).
S: B, anything new?
B: Yes, S, I need some shoes (order #124).
S: B, anything new?
B: Yes, S, I need some shoes (order #124).
...

S Pode ser enviado por ordens, mas como o # é enviado a cada solicitação, não é grande coisa. Se perdemos antes, estamos recebendo agora. Se não conseguimos antes, woohoo! Nós temos agora. O sistema funciona! Você notará isso B envia mensagens 5 vezes no meu exemplo. Em um cenário realista, você provavelmente enviaria uma mensagem centenas ou milhares de vezes, até ter a confiabilidade desejada.

Agora, a solução acima é o processamento e a largura de banda intensiva, mas funciona. Um método mais inteligente é fazer o que o TCP faz: ter um aperto de mão de três vias.

S: Hello B. Are you there? -> SYN
B: Hello S, yep I'm here. What's up? -> SYN+ACK
S: Oh good, you're there. -> ACK
S: B, anything new?
B: Yes, S, I need a jacket (order #123).

Mas .. http já faz isso. Então, se algo não chegar a algum lugar, você saberá. A conexão cronometrada, a conexão quebrada, etc.

Agora, você pode reescrever esses cenários dentro do nível de aplicativo (digite o problema do WS), mas realmente o TCP já é confiável. Alguns críticos dessas estruturas de sabão (ISH) e protocolos falsos (eles geralmente trabalham no topo do HTTP) os acusam de reinventar essencialmente a roda - e os problemas da roda - em um nível mais alto de abstração.

A linha inferior é que qualquer sistema pode falhar, incluindo sistemas de mensagens confiáveis.

No que diz respeito à consistência eventual, acho que você pode estar confuso. A consistência eventual se aplica apenas a sistemas de armazenamento distribuídos onde após um Write(), você pode não ser capaz de recuperá -lo deterministicamente com um Read() por algum tempo. Isso não parece o seu problema. Quero dizer, eu vejo o que você está dizendo, mas em um eventually consistent Sistema, uma conexão confiável (suficiente) é assumida entre os nós. Você não assume essa suposição (mesmo que eu ache que deveria .. o TCP é bastante confiável).

Com base no quê, Dina mencionou. Os serviços da web seriam uma solução perfeita para o problema acima. Algum protocolo pode ser acordado que definiria o número de registros.

S ---> D ( Call a service which would list record keys)
D----> S ( provide xml of keys)
S----> D ( Request each of the records)
D----> S ( Submit record)

No caso de uma nova entrada de registro que está sendo feita após a sincronização, o destino pode invocar um serviço implantado na fonte, que lidaria com um novo registro.

Como a comunicação é tratada para comprar um mecanismo de serviço da Web, você não precisa se preocupar com os parâmetros da mensagem. O SSL pode ser adicionado para segurança.

Felicidades!

Eu acho que você está tentando dizer que a empresa B é um participante passivo. S (fornecedor) precisa apenas da capacidade de obter todos os pedidos que B posta (eventual consistência). Mas B não precisa ou se importa com o que os pedidos já têm (não há necessidade de comprometer).

Se a Companhia B tiver um relógio semi-preciso, você poderá usar a data como o GUID monotonicamente aumentando, dependendo da resolução de eventos-você não deseja pesquisar se precisar de uma resolução de milissegundos de qualquer maneira. Você só usa o relógio de B para não precisar se preocupar com a sincronização. Se B publicar todas as ordens, S poderá pegar os pedidos de onde parou pela última vez.

Não tenho certeza se você quis dizer práticas recomendadas ou melhores trocas para um sistema fácil de implementar. Dependendo do tempo de volume e resposta, não há necessidade de torná -lo um sistema dinâmico se você estiver pesquisando de qualquer maneira. Dump ordens como arquivos de texto (nomeados pelo timestamp) em um diretório nomeado pela data e puxá -los todos para baixo (ou seletivamente). Você pode até armazená -los em diretórios por hora ou o que quer que faça sentido. Http get é idempotente.

Isso pode ser feio, mas parece que você não espera muita complexidade da Companhia B. Use SSL e Auth e ele está bloqueado e criptografado.

Se você não precisa de desempenho, não há nada de errado com o simples. O que você realmente ganha com um protocolo complicado?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top