最简单的部署是以下配置:
- 到处使用相同的消息类型和合同。这在任何情况下都是必须的,所以这是不言而喻的。
- 不要使用对话安全。简直
GRANT SEND ON SERVICE::[<servicename>] TO [public]
无处不在。这消除了对数据库证书和远程服务绑定的需要。
- 为端点使用证书,但不要交换它们(导出、导入、创建登录等)。有一个技巧:即使不交换证书
GRANT CONNECT ON ENDPOINT::[<brokerendpointname>] TO [public]
,也允许两个端点使用 SSL(证书)进行连接。
- 使用传输路由(意味着启用特殊路由并使用约定
TRANSPORT
命名您的服务。[tcp://hostname:port/servicename]
让我解释一下为什么我推荐这个设置:
- 删除对话安全性将部署简化了 10 倍。对话安全性允许服务对每条消息的发送者进行身份验证和自动化,但在相对受控的环境(内联网)中,您可以基于信任进行部署:服务接收到的任何消息都被信任来自授权的发送者。
- 为端点使用证书通常被认为很复杂,因为需要交换证书以允许连接,但是在
public
代理端点上授予连接的技巧消除了交换证书的要求。所有使用此技巧的机器都可以在没有任何先前设置的情况下相互通信,这甚至比在端点上使用 Windows 身份验证更好(需要授予连接到domain\machine$
ro 需要使用特定域帐户部署 SQL Server 实例)。同样,您失去了对连接说“不”的能力,您将接受来自Intranet 中任何SQL 实例的连接。
- 使用 TRANSPORT 路由,任何加入“party”的 SQL Server 实例都准备好了:因为服务名包含主机名,所有其他机器已经知道如何与这台机器通信,并且不需要添加显式路由。
这种配置真的很接近“即插即用”。新机器可以立即加入与任何现有 SQL Server SSB 服务的通信,而无需对其他现有机器进行任何配置更改。
以下是如何为此类部署配置机器的示例。假设您想首先在以下位置部署中央服务器MACHINE1
:
use master;
go
create database master key...
create certificate [MACHINE1] with subject 'MACHINE1';
create endpoint BROKER as tcp (listener_port 4022) for service_broker
(authentication certificate [MACHINE1]);
grant connect on endpoint::BROKER to [public];
go
use db1;
create message type...
create contract ...
create queue ...
create service [tcp://MACHINE1:4022/CentralService]
on ...
([...]);
grant send on service::[tcp://MACHINE1:4022/CentralService] to [public];
create route transport with address = 'TRANSPORT';
go
而已。现在让广告一个节点,比如在主机 MACHINE2 上:
use master;
go
create database master key...
create certificate [MACHINE2] with subject 'MACHINE2';
create endpoint BROKER as tcp (listener_port 4022) for service_broker
(authentication certificate [MACHINE2]);
grant connect on endpoint::BROKER to [public];
go
use db2;
create message type...
create contract ...
create queue ...
create service [tcp://MACHINE2:4022/Satellite]
on ...
([...]);
grant send on service::[tcp://MACHINE2:4022/Satellite] to [public];
create route transport with address = 'TRANSPORT';
go
而已。现在发生了两件事:
- 因为 MACHINE1 和 MACHINE2 上的两个端点都使用基于证书的身份验证并已授予连接到公共的权限,所以它们可以按原样连接和交换消息,而无需交换(导出和导入)它们的端点证书
- 因为两个数据库都创建了特殊的 TRANSPORT 路由,并且服务名称具有特殊的
[tcp://machine:port/service]
语法,所以两个服务可以立即按原样交换消息,而无需任何显式路由。
最好的是如何添加一个新节点,比如 MACHINE3:
use master;
go
create database master key...
create certificate [MACHINE3] with subject 'MACHINE3';
create endpoint BROKER as tcp (listener_port 4022) for service_broker
(authentication certificate [MACHINE3]);
grant connect on endpoint::BROKER to [public];
go
use db2;
create message type...
create contract ...
create queue ...
create service [tcp://MACHINE3:4022/Satellite]
on ...
([...]);
grant send on service::[tcp://MACHINE3:4022/Satellite] to [public];
create route transport with address = 'TRANSPORT';
go
现在,忽略对 MACHINE1 或 MACHINE2的任何单个更改,新节点 MACHINE3 可以与中央服务交换消息,如果需要,实际上也可以与 MACHINE2 的卫星交换消息。端点接受任何人连接,因此欢迎使用 MACHINE3,并且使用的服务名称由特殊的 TRANSPORT 路由机制自动路由。这就是这种配置的美妙之处,即插即用:添加一个新节点需要其他节点上的 0 配置。
那么给了什么?最大的问题是安全性。任何员工都可以在其桌面上下载 SQL Server Express,设置未经授权的 Satellite 节点并开始与 Central 服务交换消息。真的没有什么可以阻止他,你已经明确地打开了所有的大门。一个更微妙的问题是服务何时移动。当服务[tcp://MACHINE3:4022/Satellite]
被移动(例如,通过数据库备份/恢复)时MACHINE4
,服务的名称仍然是有效的 TRANSPORT 路由语法名称,但不正确。根据保留现有对话的重要性,您可以选择取消服务并创建一个新服务,命名为[tcp://MACHINE4:4022/Satellite]
派对(您不能重命名服务,您必须删除并创建一个新服务)。如果维护现有对话至关重要,那么有一些变通方法,因为在中央服务数据库上为其添加显式路由将优先于最后的 TRANSPORT 路由,并且消息将被正确重定向。重要的是有解决方案:)