服务代理:设计两个SQL服务器之间的通信(Service Broker: Designing the

2019-09-29 11:42发布

我们的目标:不断生成的记录可靠的传输到中央SQL。

摘要:卫星需要问的中央是什么在其一侧的最新数据,然后它会不断发送较新的。

卫星SQL服务器可能是(重新)有时开始(以基于物理的生产机器有关的),中央SQL机器可能运行的时间更长,但也可以有一些停机时间。 该行大多是可靠的,但没有人知道......我想到了连接问题,可以通过在SQL Server Service Broker的自然解决。 但是,我需要解决的初始握手的问题,并发送数据。 我需要设计的协议,我SSB知识仍然很差。

我希望我的理解通信的使用SSB这是很好的,并简要描述为基础

你应该对自己的谈话每个工作项目启动。 生产者(引发剂)开始一个对话,并发送描述该工作项的消息,然后提交。 消费者(目标)接收消息(或被激活),检查有效载荷了解工作项目的详细信息,执行的工作,然后结束该对话和提交。 将所得的EndDialog消息被发送回到发起者服务队列中,并且在启动器队列的活化过程通过结束对引发剂侧的对话框响应它。

...由瑞摩斯Rusanu(如果有兴趣看到在他早期的回答更多的细节 )。

我想(在这里一个多字符串)发送记录,因为像这样的XML消息

<row a="1" b="11" c="111" />
<row a="2" b="22" c="222" />
<row a="3" b="33" c="333" />
<row a="4" b="44" c="444" />

我已经学会了如何写SELECT获得从XML消息的信息 。

通讯:假设SQL服务器之间的通信机制,只是激活...

  1. 卫星SQL获得的新数据,并以某种方式它知道有卫星和中央之间没有未决消息。 但是,这也并不知道什么数据已被发送到中央。 因此,它有权要求中央是什么它最后可用的数据。

  2. 如果我理解的END CONVERSATION正确,该命令的原因只发送一种空消息的N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog' 。 正因为如此,中央也许应该把我的类型ReplyMessage与答案前回END CONVERSATION

  3. 同时,卫星也许应该什么都不做的行为异步地(即发送后等待RequestMessage )。 一旦ReplyMessage到达时,它会激活卫星的过程,:

    • 接收到该消息,并得到想要的信息,
    • 接收的EndDialog消息,并且在卫星侧端先前的对话框,
    • 准备要发送到中央(XML字符串形式)中的数据,
    • 打开新的对话框,
    • 发送准备好的数据,
    • 并且使自己处于休眠状态,直到另一个ReplyMessage到达。
  4. 中央应该表现相似。 一旦RequestMessage到达时,它会激活中心的过程,:

    • 接收到该请求消息时,
    • 提取XML信息并更新中央数据库,
    • 得到有关卫星的最后一个可用的数据信息,
    • 形式并发送ReplyMessage
    • 结束于中央侧的对话框。

到目前为止,我的观点正确吗?

现在的一些细节,我不知道:我想让它强大的,没有人情味的工作,在安装的时候机制就应该开始了自己。 通信应该总是通过卫星开始(中央可能不知道,即使卫星的工作原理,甚至存在)。

该卫星已经使用由被处理,以建立一个在中心收集的记录的原始数据发射的扳机。 通过这种方式,触发可启动莫名其妙卫星到中央的第一SSB请求。 但...

  • 如何触发器可以检查有卫星和中央之间没有悬而未决的沟通? 由于卫星总是始作俑者,这个问题也可配制成...如何触发器可以检查是否卫星等待一些ReplyMessage ? 或者说,如何知道有卫星和中央之间的一些打开的对话框?
    • 如果没有对话,触发形成的数据记录(存储在本地表),然后就可以开始通信理线(见上文第1点)。
    • 如果有任何对话,触发仅形成是记录稍后发送,并没有别的做。 当数据将被发送ReplyMessage由活化的方法得到(参见上面的点3)。
  • 使卫星处于休眠状态 (见第3点的最后一颗子弹或以上)我的意思是,应该有可能是在消息队列中没有其他消息(没有在环中处理的)和被激活的过程是自然完成。 但我不知道如果我想在这里正确。 你对此有何评论?
  • 如果没有被打破,如果数据产生速度不够快,卫星和中央一贯的东西来交换。 通过这种方式,触发决不应该试图开始通信。
  • 如果没有别的通过激活卫星程序发送到中央(实际上,它是不活动),或当系统重新启动某种方式(无对话还不存在),触发启动通信过程。 但是,我怎么能这样做呢? 如果触发只需发送RequestMessage到中央? (这样的ReplyMessage会激活卫星的过程和程序将继续下去,直到有什么事情要处理。)
  • 说了, RequestMessage意味着这里是一些数据,对它们进行处理,并回复什么是最后一个 (或何去何从应该是发送或从中央建议采取什么下一步行动-依赖于经营业务逻辑,也许这里并不重要)。 是否确定发送空XMLRequestMessage我不知道你需要什么其他的意义-告诉我吗?

首先更新 -基于以下莱姆斯Rusanu的答案 。

我不得不承认,这将是健谈的协议。 此外,记录被从所述真实环境创建为温度样本和取样的频率是相当低的。 这意味着复杂的协议,只有在重新启动一切左右的特殊情况是有用的。

但是,当谈话要永远保持开放,在该对话框手柄或唯一标识应持久地存储在一些配置表,或者它甚至可以被硬连接到代码。 触发器将立即在飞行中发送的记录,和中央根本不会发送ReplyMessage 。 这是正确的吗? 可那种coversation来有效地认为是独白?

第二次更新 ,使这个问题相当短。

见延续服务代理:应该如何触发启动无限打开的对话框?

Answer 1:

我需要解决的初始握手的问题,并发送数据。

我不能告诉你怎么读这从2004年带回闪存......当时我们在设计发布 - 订阅协议(“monologs”与“对话”)和设计要点之一是为需求的“检查点”。 想想在这样说:“出版商”分配目录的项目。 它最初发送目录作为一个检查点消息的内容,然后将其继续任何更新发送到目录(添加或删除项目,价格变动等)作为更新消息。 每当有人订阅本刊物,它需要获得检查点信息和所有后续更新消息,因此他的目录是最新的。 在时间的更新列表变得过于长,所以定期发布商重新将当前目录状态为“检查点”。 随后用户只需要在最后一个检查点,从那以后的任何更新。 另外,发行商的基础设施可以删除所有在此之前,最后一个检查点发送,因为没有用户会需要它了消息。 这解决了新用户“中间”的数据流的加入并得到一致的状态的问题。 问题(和解决方案)没有从SQL Server本身是如何处理的日志记录和恢复(和名称“检查点”是不是巧合...)不同。 现在当然,整个酒吧-sub实现最终得到了罐头和你已经是对话,不提供必要的手段来实现我描述了“外的即装即用”,这就是为什么我看得出你正想去创造自己的替代品......但是,我离题。

我会总结你提出的消息交换模式如下:一sattelite需要向中心站对中心的当前状态(“水印”)。 它这样做在典型的请求 - 响应模式:在发送器侧BEGIN_TRAN-> BEGIN_DIALOG-> SEND_Request-> COMMIT,活化 - > BEGIN_TRAN->接收 - > SEND_Response-> END->接收器上的尺寸COMMIT,活化 - > BEGIN_TRAN - >接收 - > END-> COMMIT发送侧。

这是一般的好模式,但我不认为这是你想要的图案。 什么你会最终是这样的: 每一个新作品的sattelite有信息,它会问中心:“你有这个已经” 然后该中心将回应“嗯,是我做的”或“否,请发送给我。” 这是一个令人难以置信的繁琐协议,涉及每一个信息,最终使得它从sattelite到中心进行交换大量信息。 我想你应该让你的谈话开了很久,认为他们作为通信信道。 一旦建立,sattelite会简单地发送每一次它有一些新的信息的数据。 你并不需要问中心的地位,是国家统计局工作,以确保任何你发送并到达中心,即使在网络故障的存在。 开始交谈,发送1MM消息,并任由在SSB编程完全确定 。 那么,3个月后发送另一个1MM消息。 即使这样在系统断开2周,感恩节过后只能实际交付的消息。 这正是 SSB是专门用来处理。 该小问题,就是你的程序代码也应该做好准备来处理这个(即从来没有等待回复,它可能会在... 2周)。

关于SSB编程模型几句话。 正常情况下随时无处任何人任何东西积极“等待”,SSB节目是所有关于对事件作出响应。 激活模型更接近于时下什么是“函数编程”。 认为node.js中 绝大多数您的代码将依赖于激活程序。 你的代码应该总是在形式“开始交易 - >收到MESSAGE->读取数据库当前状态该项目的消息属于TO->决定注重结果>更新数据库国有>发送响应(如果有的话) - > commit- >退出。 该磺酰基例外之类的东西,你有扳机,这是代码,在激活驱动程序这个乒乓注入了新的消息。 此代码(触发)应该永远等待上不管它发送一个响应。 它应该发送和继续。 这触发的发送任何响应应该由活化处理。 异步一次。 认为C#的新的await异步。



文章来源: Service Broker: Designing the communication between two SQL servers