博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Silverlight实现对Sql Server Profiler的SQL实时监控
阅读量:6938 次
发布时间:2019-06-27

本文共 5343 字,大约阅读时间需要 17 分钟。

      Sql Server Profiler作为Microsoft Sql Server数据库系列的性能工具,通过它可以对数据库的运行状况进行实时跟踪,从中可以找到慢查询或者死锁的SQL语句,从而去优化系统。本文介绍如果通过Silverlight来对Sql Server Profiler进行实时监控(数据库环境以Sql Server 2005为例)

 

      首先,先来看下SqlServer数据库自带的性能工具Sql Server Profiler,新建一个跟踪:

我们选择默认的模板Standard,其他都不变,点击运行:

从中可以看到数据库中的SQL的运行状态,EventClass作为事件类型,TextData作为运行的SQL脚本,ApplicationName作为一个应用程序的执行源的名称,比如说,从.Net应用程序执行的SQL脚本就是.Net SqlClient Data Provider,再比如说,我直接从数据库客户端工具执行一条SQL语句,可以看到ApplicationName为 ”Microsoft SQL Server Management Studio - 查询“,因此我们通过ApplicationName字段得到程序的执行源,LoginName作为一个数据库的账户,一般系统用户为sa,包括CPU/Reads/Writes在此上面也是一目了然,Duration比较有用,可以查看执行语句的耗时,后面还包括StartTime的开始时间和EndTime的结束时间,当然一些隐藏的列我就不一一列举了,有兴趣大家可以勾选查看下。

      如果我要定义一个符合自己需要的模板呢,那么可以通过新建/编辑模板来实现:

上面有很多的事件类型的选择,可以根据自己的需要定制Event,这里我以最简单的方式,就选择了TSQL:SQL BatchCompleted:

并且列选择一个数据库DatabaseName,类似于编辑 MyEnt,这样该模板文件只会在MyEnt为名称的数据库中进行SQL执行跟踪了:

最后点击保存即可

 

      那么,在.Net上怎么实现对于Sql Server Profiler的使用和监控,实际上,Sql ServerProfiler本身为.Net开发的,后来我在SqlServer2005数据库的安装目录 C:\Program Files\Microsoft SQL Server\90\SDK\Assemblies 中,找到一个Microsoft.SqlServer.ConnectionInfo.dll,这个dll就可以实现执行Sql的监控。

      开始创建项目,其中,监控程序是一个控制台程序,而Silverlight客户端程序是一个对于SqlServerProfiler实时监控的展示,Silverlight的客户端程序通过Socket和监控程序进行通信。由于Silverlight对于TCP通信的限制,必须往监控程序发送策略请求,并且对于TCP通信来说,目前Silverlight的使用端口必须为4502-4530,于是必须在监控端先设置一个Policy.xml的策略文件:

<?
xml version="1.0" encoding ="utf-8"
?> 
<
access-policy
> 
  
<
cross-domain-access
> 
    
<
policy
> 
      
<
allow-from
> 
        
<
domain 
uri
="*"
 
/> 
      
</
allow-from
> 
      
<
grant-to
> 
        
<
socket-resource 
port
="4502-4530"
 protocol
="tcp"
 
/> 
      
</
grant-to
> 
    
</
policy
> 
  
</
cross-domain-access
> 
</
access-policy
>

现在我将策略请求,监听SL客户端连接/数据收发请求,数据库监听跟踪请求,分别创建3个线程:

//创建Socket来监听策略请求和发送

this._policyThread = 
this.CreateThread(
this.PolicyRequest); 
//
创建Socket来监听信息请求和发送 
this._infoThread = 
this.CreateThread(
this.InfoRequest); 
//
创建Socket来监听数据库跟踪请求和发送 
this._traceServerThread = 
this.CreateThread(
this.TraceServerRequest); 

PolicyRequest,InfoRequest的方法具体看文章末尾的附件源代码,这里主要说一下TraceServerRequest的方法:

SqlConnectionInfo conninfo = 
new SqlConnectionInfo(); 
conninfo.ServerName = 
"
机器名
"
conninfo.UserName = 
"
数据库账户
"
conninfo.Password = 
"
数据库密码
"
conninfo.UseIntegratedSecurity = 
false;
TraceServer trace = 
new TraceServer(); 
trace.InitializeAsReader(conninfo, TDF_FILE); 
SqlConnectionInfo, TraceServer类来自于对Microsoft.SqlServer.ConnectionInfo的引用,其中TDF_FILE就是我前面说的跟踪模板文件名,它的文件后缀为tdf。
while (trace.Read()) 
    
var eventData = 
new EventData() 
    { 
        EventClass = trace[
"
EventClass
"].ToString(), 
        TextData = trace[
"
TextData
"] != 
null ? trace[
"
TextData
"].ToString() : 
""
        ApplicationName = trace[
"
ApplicationName
"] != 
null ? trace[
"
ApplicationName
"].ToString() : 
""
        NTUserName = trace[
"
NTUserName
"] != 
null ? trace[
"
NTUserName
"].ToString() : 
""
        LoginName = trace[
"
LoginName
"] != 
null ? trace[
"
LoginName
"].ToString() : 
""
        CPU = trace[
"
CPU
"] != 
null ? trace[
"
CPU
"].ToString() : 
""
        Reads = trace[
"
Reads
"] != 
null ? trace[
"
Reads
"].ToString() : 
""
        Writes = trace[
"
Writes
"] != 
null ? trace[
"
Writes
"].ToString() : 
""
        Duration = trace[
"
Duration
"] != 
null ? trace[
"
Duration
"].ToString() : 
""
        ClientProcessID = trace[
"
ClientProcessID
"] != 
null ? trace[
"
ClientProcessID
"].ToString() : 
""
        SPID = trace[
"
SPID
"] != 
null ? trace[
"
SPID
"].ToString() : 
""
        StartTime = trace[
"
StartTime
"] != 
null ? trace[
"
StartTime
"].ToString() : 
""
        EndTime = trace[
"
EndTime
"] != 
null ? trace[
"
EndTime
"].ToString() : 
""
    }; 
    
var sendData = JsonConvert.SerializeObject(eventData); 
    
if (
string.IsNullOrEmpty(sendData)) 
        
continue
    
lock (_lock) 
    { 
        
this._queues.Enqueue(sendData); 
    } 

通过trace.Read()方法来得到trace的跟踪记录,这里我不会马上通过Socket发送到SL客户端,而是通过一个队列对跟踪记录进行人队,通过InfoRequest从队列中取出数据,发送给SL客户端:

while (
true
     
lock (_lock) 
     { 
         
if (
this._queues.Count == 
0
         { 
             Thread.Sleep(
200); 
             
continue
         } 
         
var sendData = 
this._queues.Dequeue(); 
         Console.WriteLine(sendData);
         
byte[] data = Encoding.GetEncoding(
"
gb2312
").GetBytes(sendData);
         
//
 移除已断开的套接字 
         
this._clientList.RemoveAll(o => o.Connected == 
false); 
         
foreach (Socket s 
in 
this._clientList) 
         {            
             
if (s.Connected) 
             { 
                 
try 
                 { 
                     
//
发送数据 
                     s.Send(data); 
                 } 
 

SL客户端通过Socket异步编程接收数据

///
 
<summary>
 
///
 当接收完成 
///
 
</summary>
 
///
 
<param name="e"></param>
 
void ProcessReceive(SocketAsyncEventArgs e) 
     
if (e.SocketError == SocketError.Success) 
     { 
         
try 
         { 
             Gb2312Encoding encoding = 
new Gb2312Encoding(); 
    
             
string data = Regex.Replace(encoding.GetString(e.Buffer, 
0, e.Buffer.Length), 
@"
\0
"
""); 
    
             EventData eventData = JsonConvert.DeserializeObject<EventData>(data);
             
byte[] bytes = 
new 
byte[
1024]; 
             e.SetBuffer(bytes, 
0, bytes.Length);
             
this._syn.Send(
this.GetText, eventData);
             
//
执行连接 
             
this._socket.ReceiveAsync(
this._socketArgs);    
         } 
//
同步上下文调用的方法 
private 
void GetText(
object data) 
    
if (data == 
null
        
return
    EventData eventData = (EventData)data; 
    _list.Add(eventData); 
    
this.Dispatcher.BeginInvoke(
new Action(() => 
    { 
        
this.dataGridRecords.ItemsSource = 
null
        
this.dataGridRecords.ItemsSource = _list;
        
this.dataGridRecords.UpdateLayout(); 
        
this.dataGridRecords.SelectedIndex = _list.Count - 
1
        
this.dataGridRecords.ScrollIntoView(
this.dataGridRecords.SelectedItem, 
null); 
    })); 

这样就实现了Silverlight客户端对于Sql Server Profiler的实时监控。

两个项目很简单:

先运行 SqlServerProfier.Host程序:

正在对外发送监控数据,

然后运行宿主SL客户端程序的Web端:

如果是慢查询的部分,我会用红色把它标红,从而确定慢查询语句,优化系统

 

总结:

      当然,你还可以在监控程序中,对于跟踪记录进行Log写入或者一个特定Log表的插入,通过Web端(不管是Silverlight还是asp.net mvc均可以查询相关的跟踪记录),从而达到对于数据库SQL执行的监控。

 

附上源代码:

转载地址:http://vvinl.baihongyu.com/

你可能感兴趣的文章
Ansible file资源
查看>>
短视频APP源码直播APP源码什么样的好
查看>>
这届百度搜索不太行
查看>>
Zabbix3.0实战安装部署
查看>>
SpringMVC整合Shiro
查看>>
PostgreSQL 与 MSSQL(SQL Server) 之间 数据相互迁移、导入、导出测试
查看>>
python 多进程与子进程
查看>>
Git常用命令
查看>>
自开发Web应用和SAP Customer Data Cloud Identity服务的集成
查看>>
HanLP Android 示例
查看>>
推荐四十多条纯干货 Java 代码优化建议
查看>>
「镁客·请讲」太平洋未来科技李建亿:深耕AR技术,布局垂直领域
查看>>
如何用纯 CSS 创作一种侧立图书的特效
查看>>
中软酒店管理系统CSHIS操作手册_数据结构_数据字典
查看>>
跳出弹窗页面禁止滚动(PC端和手机端)
查看>>
HTML5/CSS3鼠标悬停动画菜单按钮
查看>>
Android Studio打包错误(Cannot merge new index 67578 into a non-jumbo instruction!)
查看>>
SLS机器学习介绍(03):时序异常检测建模
查看>>
4.1ASP.NET Core请求过程「深入浅出ASP.NET Core系列」
查看>>
安装elasticsearch中文切词插件hanlp
查看>>