目标:将连续生成的记录可靠地传输到中央 SQL。
总结:卫星需要向中央询问自己这边的最新数据是什么,然后它会不断地发送更新的数据。
卫星 SQL 服务器有时可能会(重新)启动(与物理生产机器有关),中央 SQL 机器可能会运行更长时间,但也可能会有一些停机时间。这些线路大多是可靠的,但人们永远不知道......我希望SQL Server 服务代理能够自然地解决连接问题。但是,我需要解决初始握手和发送数据的问题。我需要设计协议,而我的 SSB 知识仍然很差。
我希望我了解使用 SSB 进行通信的基础知识,这些基础知识被很好地简要描述为
您应该从每个工作项开始进行自己的对话。生产者(发起者)开始对话并发送描述工作项的消息,然后提交。消费者(目标)接收消息(或被激活),检查有效负载以了解工作项详细信息,执行工作,然后结束对话并提交。生成的 EndDialog 消息被发送回发起者服务队列,发起者队列上的一个激活过程通过结束发起者端的对话来响应它。
... 由 Remus 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服务器之间的通信机制刚刚激活......
卫星 SQL 获得了新数据,不知怎的,它知道卫星和中央之间没有待处理的消息。但它也不知道哪些数据已经发送到中央。因此,它必须询问中央它最后可用的数据是什么。
如果我理解
END CONVERSATION
正确,该命令会导致仅发送一种空消息N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
。因此,中央可能应该ReplyMessage
在END CONVERSATION
.同时,卫星可能不应该做任何异步行为(即在发送后等待
RequestMessage
)。一旦ReplyMessage
到达,它就会激活一个卫星程序,该程序:- 接收消息并获得想要的信息,
- 接收到 EndDialog 消息并在卫星端结束之前的对话,
- 准备要发送到中央的数据(XML 字符串形式),
- 打开新对话框,
- 发送准备好的数据,
- 并让自己处于休眠状态,直到另一个
ReplyMessage
人到来。
中央应该有类似的行为。一旦
RequestMessage
到达,它就会激活中央程序:- 接收请求消息,
- 提取 XML 信息并更新中央数据库,
- 获取有关卫星最后可用数据的信息,
- 形成并发送
ReplyMessage
, - 在中间结束对话。
到目前为止,我的观点正确吗?
现在有一些我不确定的细节:因为我想让它变得健壮,在没有人为接触的情况下工作,它应该在安装机制时自行启动。通信应始终由卫星启动(即使卫星工作甚至存在,中央也可能不知道)。
卫星已经使用由原始数据触发的触发器,该触发器被处理以构建在中央收集的记录。这样,触发器可以以某种方式向中心发起卫星的第一个 SSB 请求。但...
- 触发器如何检查卫星和中央之间没有挂起的通信?由于卫星始终是发起者,问题也可以表述为……触发器如何检查卫星是否等待一些
ReplyMessage
?或者,如何知道卫星和中央之间有一些开放的对话?- 如果没有对话,触发器形成数据记录(存储在本地表中),然后它可以启动通信过程(参见上面的第 1 点)。
- 如果有任何对话,触发器只会形成稍后要发送的记录,不会做任何其他事情。
ReplyMessage
当通过激活的程序获得时,将发送数据(参见上面的第 3 点)。
- 关于使卫星休眠(参见上面第 3 点的最后一个项目符号),我的意思是消息队列中可能没有其他消息(循环中没有要处理的内容),并且激活的过程自然会完成。但我不确定我在这里是否正确地思考。你能对此发表评论吗?
- 如果没有任何问题,并且数据产生的速度足够快,那么卫星和中央总有一些东西可以交换。这样,触发器永远不应该尝试开始通信。
- 当激活的卫星程序没有其他内容要发送到中央时(实际上,它不是活动的),或者当系统以某种方式重新启动(尚不存在对话)时,触发器启动通信过程。但我怎么能做到呢?触发器是否应该简单地将 发送
RequestMessage
到中央?(这种方式ReplyMessage
将激活卫星程序,并且程序将继续,直到有任何事情要处理。) - 比如说,这里的
RequestMessage
手段是一些数据,处理它们,然后回复最后一个(或者下一个应该发送什么或者从中央推荐下一个动作——取决于业务逻辑,在这里可能并不重要)。在我不知道您还需要什么的意义上发送空 XML是否可以 - 告诉我?RequestMessage
第一次更新- 基于以下 Remus Rusanu 的回答。
我不得不同意这将是健谈的协议。此外,这些记录是作为来自真实环境的温度样本创建的,并且采样频率相当低。这意味着复杂的协议只有在重启一切的特殊情况下才有用。
但是当对话应该永远打开时,对话句柄的唯一标识符应该永久存储在某个配置表中,或者它甚至可以硬连线到代码中。触发器将立即即时发送记录,而中央根本不会发送ReplyMessage
. 这是对的吗?这种覆盖可以有效地被认为是独白吗?
第二次更新使这个问题相当简短。