改进SQL Server服务代理的性能

日期: 2009-01-04 作者:SearchSQLServer.com翻译:曾少宁 来源:TechTarget中国 英文

之前我与一个Microsoft Support Engineer交谈时,他提到在一些像我们这样的高负载的服务代理环境中,通过重用服务代理会话能够大大提升服务代理的性能。   为每一个消息创建和关闭会话需要的开销大约是4X,而对于接收消息的性能提升大约能达到10X。Remus Rusanu在他发布在Reusing Conversations的博客上,谈到这个估值可能更大,并且还提出了一种重用会话的解决方案。   我喜欢Remuss的解决方案,但其中有一个问题:我不愿意为每一个SPID创建不同的会话。

如果我使用这种方法,就会有大量的会话打开,这样我还需要去关闭它们。在应用中,许多问题都可能触发一个……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

之前我与一个Microsoft Support Engineer交谈时,他提到在一些像我们这样的高负载的服务代理环境中,通过重用服务代理会话能够大大提升服务代理的性能。

  为每一个消息创建和关闭会话需要的开销大约是4X,而对于接收消息的性能提升大约能达到10X。Remus Rusanu在他发布在Reusing Conversations的博客上,谈到这个估值可能更大,并且还提出了一种重用会话的解决方案。

  我喜欢Remuss的解决方案,但其中有一个问题:我不愿意为每一个SPID创建不同的会话。如果我使用这种方法,就会有大量的会话打开,这样我还需要去关闭它们。在应用中,许多问题都可能触发一个服务代理消息的发送。而且通常情况下都会有大量的线程在同一时间对数据库进行访问。这就要求我们在实际环境使用Remuss的方法之前要对它进行优化,使之更灵活。我的想法是为我们应用中的每一个进程创建一个会话。并且在一定周期内,有一些会话会被关闭,也有些新的会话被创建。

  首先我先介绍一些关于安装服务代理的背景知识。我已经有2个队列和2个服务。每一个服务都在它自己的队列中。同时我有一个专门的消息类型,它用于将消息从源发送到目标位置。

  • 我的消息类型是MT_ObjectDelete,
  • 我的契约:CT_ObjectDelete,
  • 我的队列:Q_ObjectDelete_Source和Q_ObjectDelete_Destination,
  • 我的服务:Svc_ObjectDelete_Source和Svc_ObjectDelete_Destination,  

  另外我的另一个消息类型是MT_ConversationSwitch,它也是契约CT_ObjectDelete的一部分。

  为了存储我将生成的会话句柄,我会使用现有一个保存各种配置信息的表Setting。我已经添加了一些新的会话终端记录到表中。其中在Setting表中的查询名称是SSB_Session_Delete。我使用GetSystemSettingValue方法来查询Setting表得到配置值。发送数据的存储过程是这样的:

CREATE PROCEDURE [dbo].[SendDelete]
@FileName varchar(1024)
AS
DECLARE @DialogHandle uniqueidentifier,
@msg XML,
@date nvarchar(100)
BEGIN
IF @msg IS NOT NULL
BEGIN
    SET @DialogHandle = cast(dbo.GetSystemSettingValue('SSB_Session_Delete') as uniqueidentifier)
    IF CAST(RAND()*100 AS INT) = 0 OR @DialogHandle IS NULL
BEGIN
IF @DialogHandle IS NOT NULL
SEND ON CONVERSATION @DialogHandle
MESSAGE TYPE [MT_ConversationSwitch]

BEGIN DIALOG CONVERSATION @dialogHandle
FROM SERVICE [Svc_ObjectDelete_Source]
TO SERVICE Svc_ObjectDelete_Destination
ON CONTRACT [CT_ObjectDelete_Multi];
        UPDATE Setting
SET DefaultValue = @DialogHandle
WHERE SettingName = SSB_Session_Delete;
END;
SEND ON CONVERSATION @dialogHandle
MESSAGE TYPE [MT_ObjectDelete]
(@msg)

IF @DialogHandle <> cast(dbo.GetSystemSettingValue(SSB_Session_Delete) as uniqueidentifier)
SEND ON CONVERSATION @DialogHandle
MESSAGE TYPE [MT_ConversationSwitch]
END
END
GO

  你可以从代码中看到,我通过查询获取当前的会话句柄。如果没有找到句柄,我会创建一个新句柄并将句柄值保存到我的Setting表中。如果CAST(RAND()*100 AS INT)返回0,我会使用现在会话中的MT_ConversationSwitch消息类型发送一条消息,它将触发接收程序的逻辑,终止该会话。在我终止该会话后,我再创建新的会话并将它存储在数据库中。

  然后我在该会话句柄上发送一条消息。接着我会再次检查Setting表,以确保我使用的值与表中的值是相匹配的。如果不匹配,我会认为另一个线程已经在相同的代码块中运行,然后关闭该会话,因为我不希望该会话继续存在。

  我的接收程序非常简单:


CREATE PROCEDURE [dbo].[util_ProcessDelMonitorData]
@MsgToRead INT = 1000
AS
DECLARE @message_type_name sysname;
DECLARE @message_body VARBINARY(max)
DECLARE @msgTable TABLE
(
message_body VARBINARY(max),
[conversation_handle] UNIQUEIDENTIFIER
);
BEGIN
DECLARE @conversation_handle UNIQUEIDENTIFIER
WHILE 1=1
BEGIN
WAITFOR (RECEIVE TOP (1) @Message_Body = message_body,
@conversation_handle = [conversation_handle],
@message_type_name = message_type_name
FROM [Q_ObjectDelete_Destination]), TIMEOUT 1000
    IF @conversation_handle IS NULL
BEGIN
break
END
IF @message_type_name = MT_ConversationSwitch
END CONVERSATION @conversation_handle
    IF @message_body IS NOT NULL
BEGIN
INSERT INTO @msgTable
(message_body, [conversation_handle])
values
(@message_body, @conversation_handle)
END
    SET @conversation_handle = NULL
SET @message_type_name = NULL
END
/*Business Logic happens here*/
END
GO

  你可以看到,我会对于第一条消息做标准的接收。如果消息没有发现值,我会转而处理我之前存储在@msgTable表变量中的数据。

  如果消息类型message_type_name是MT_ConversationSwitch,我会对该会话做一个中止会话(END CONVERSATION)的操作。

  如果@message_body变量中有数据,我会将该值存储到表变量中,给后面的业务逻辑进行处理。

  另外在发送队列中还有一个激活的程序,它只是对它接收的每一个消息做简单的中止会话(END CONVERSATION)操作。

  我真心希望这个例子能对你有所帮助。如果你对此有任何问题,请提交你的问题,我将尽快地回复你。

  Denny

翻译

曾少宁
曾少宁

TechTarget中国特约技术编辑,某高校计算机科学专业教师和网络实验室负责人,曾任职某网络国际厂商,关注数据中心、开发运维、数据库及软件开发技术。有多本关于思科数据中心和虚拟化技术的译著,如《思科绿色数据中心建设与管理》和《基于IP的能源管理》等。

相关推荐