数据实时监视发现有三种方法:
(1)timer 
(2)Socket
(3)Sql 触发+Dll请问 2、3如何实现?或者大家有别的方法?

解决方案 »

  1.   

    如果是sql2005的话
    安装SQL Server 2005性能监视器计数器,资源消耗很少
      

  2.   

    先说说:是server 端的exe 对数据库进行监控吗?
      

  3.   

    (1)timer  
    (2)Socket
    (3)Sql 触发+Dll这是3个方案么?如同如何做一个面包,方案1:黄油、面粉,方案2:烤箱,方案3:巧克力面包。
      

  4.   

    同LS...LZ再吃点亏,多打点字吧
      

  5.   

    c/s结构,socket通讯,协议封装;
      

  6.   


    你这样做的话,你的服务端对于数据库来说其实也是客户端1.你已经知道每秒会最多插入5条数据,那么你就每隔1秒从数据库中把最新的5条记录取出不就行了吗(如果每条记录有时间字段)?2.这种方法个人认为是不错的, 你的客户端将数据插入到数据库的同时,通过SOCKET/WCF等方式,把数据传递给监视画面,这样做的实时性更高,对数据库的开销更小
      

  7.   

    每秒查询一次服务器资源消耗就太大了,什么服务器啊~
    我这里每天单台处理百万级的,偶尔千万,cpu不会超过20%还有统计系统和业务系统是不是做在一起了?
      

  8.   

    使用日志文件如log4net,DAL方法上监视
    触发器
    用线程定时刷新
      

  9.   

    总共3-500w还是每天,如果总共的话普通pc足能胜任了.钱多的话首推IBM,SUN,HP,DELL,国产品牌曙光联想什么的没用过.
    性能都差不多,备灾方案各异, 还有就是服务的区别,我这里的DataCenter也就8核 32-64G内存的配置 不是很高,品牌就不说了,免得做广告的嫌疑.
      

  10.   

    socket是实现 C/S的一种方式,对你所提的这个问题没有任何意义,不知道为什么你会说"套接字不会用,怕在实际使用出现新的问题"现在我从你的主题以及回帖里大概确定了以下几点:
    1,你的C/S模式不是用SOCKET实现的.(这个无所谓,HTTP也无妨)
    2,你是这个模式 C->S->SQLSERVER如果真是这样的话,则证明 你的 S端是个请求中转站,也就是说你的S端会比数据库更具有数据库统计的准确性.所以我就不明白,为什么你还非得从数据库获得最新数据来统计.如果按我的理解是对的话,那么可以这样做:
    以S端为中心,每天临晨从和数据库相互同步一次数据,这样确保数据的准确性.
    -------------------------------------如果不是我理解的这个模式 那么请你细说你现在的 环境结构. 你至少得把整体通讯结构说出来,我们才能给你确切解决方案,否则你得到的也是我们猜测的答案.
      

  11.   


    我再确认一个问题:
    到底是1:
    client ---上传数据提交到SQL--> sqlserver2005 然后 再在 sqlserver2005的服务器上写一个程序对数据进行统计还是2:
    client ---上传数据提交到服务器上的一个程序--> server -----数据提交到SQL--> sqlserver2005 现在我从你最后一次的答复中发现1的可能性比较大.
      

  12.   

    1、就不说了,是基于轮询完成的监控。
    2、套接字,这个基本上应该是一个基于监听端口的实现,有个监听端口一直在监听。
    3、触发器,这个基本上不是用于实时数据监控的,这个在Insert,Update,Delete时触发,这个没有一般性。第二个方案在一般的C/S项目中比较合适,这实际上是一个消息模型,可以应用到非套接字的应用中。
      

  13.   

    我们公司也在做类似的东西,就是监控主机及进程的资源(cpu,内存,虚拟内存,网卡流量等),刚刚把系统设计做完,通讯你肯定要用socket了,
      

  14.   


    呵呵 既然确认了问题那这就好办了.有2个办法
    1: client和server 都改代码.
    client 每次和数据库同步成功之后 都通知server一次(如果你不会写socket那么你写http吧,会简单很多)
    这样的话就回到我提的方案2的轨道上来了,你只需要在夜晚让server何sqlserver进行同步即可,数据库压力小很多.并且程序压力也不大每秒处理5个HTTP请求对你的server端来讲也没什么问题.2:只改server端
    就是server端每间隔N秒就去数据库同步 一次数据.这样的话你最好是设计成日表/月表 机制(如果你设计了日表的话就可以只取最近1天的数据,历史数据不用每N秒取1次,)最后说下数据库优化.
    考虑到将来维护,其实月表机制是很不错的办法.(不过程序就得大改了)
    如果不用日表月表,那么至少得每个月都把历史数据移到备份库
      

  15.   

    socket 客户端、服务端如何实现远程通信,安全如何?效率如何?
      

  16.   

    你自己实现http server 阻塞+多线程 也是从socket层来实现的,只不过是短连接处理而已.
    安全性没必要考虑,非要考虑安全的话就加密数据包(这个实在无必要.)
      

  17.   

    自己UP一下!!UP又分呀!!(可以看我以前的帖子)
      

  18.   

    我说一下第3种的实现方式,我的例子是sql server 的。使用了扩展存储过程.-----------------------------存储过程调用COM+组件-------------------------------
    ALTER    proc Proc_SendMsgToClient(@MsgContext varchar(4000))
    /*
    使用COM+发送局域网广播消息
    @MsgContext varchar(4000) 消息内容
    返回值: Send Message OK.表示发送成功
     */
    asDECLARE @object int 
    DECLARE @hr int 
    DECLARE @property varchar(255) 
    DECLARE @return varchar(255) 
    DECLARE @src varchar(255), @desc varchar(255) EXEC @hr = sp_OACreate 'SQLInterop.RMSMessageSendCOM', @object OUT 
    IF @hr <> 0 
    BEGIN 
    EXEC sp_OAGetErrorInfo @object, @src OUT, @desc OUT 
    SELECT hr=convert(varbinary(4),@hr), Source=@src, Description=@desc 
    RETURN 
    END EXEC @hr = sp_OASetProperty @Object, 'MsgContext', @MsgContext
    IF @hr <> 0 
    BEGIN 
    EXEC sp_OAGetErrorInfo @object, @src OUT, @desc OUT 
    SELECT hr=convert(varbinary(4),@hr), Source=@src, Description=@desc 
    RETURN 
    END 
    EXEC @hr = sp_OAMethod @object, 'SendMsgToClient', @return OUT 
    IF @hr <> 0 
    BEGIN 
    EXEC sp_OAGetErrorInfo @object, @src OUT, @desc OUT 
    SELECT hr=convert(varbinary(4),@hr), Source=@src, Description=@desc 
    RETURN 
    END 
    PRINT @returnEXEC @hr = sp_OADestroy @object 
    IF @hr <> 0 
    BEGIN 
    EXEC sp_OAGetErrorInfo @object, @src OUT, @desc OUT 
    SELECT hr=convert(varbinary(4),@hr), Source=@src, Description=@desc 
    RETURN 
    END
    -----------------------------------C#写的COM+组件-----------------------------------
    using System;
    using System.Runtime.InteropServices;
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;[assembly: AssemblyTitle("Shining Res Msg Server")]
    [assembly: AssemblyDescription("Msg Server")]
    [assembly: AssemblyVersion("1.0.0.1")]
    [assembly: AssemblyDelaySign(false)]
    [assembly: AssemblyKeyFile("MsgSendKey.snk")]
    namespace SQLInterop
    {
        public interface IResMsg
        {
            string SendMsgToClient();
        }    [ClassInterface(ClassInterfaceType.AutoDual)]
        public class RMSMessageSendCOM : IResMsg
        {
            public string MsgContext = "";
            public string SendMsgToClient()
            {
                //初始化一个Scoket实习,采用UDP传输
                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                //初始化一个发送广播和指定端口的网络端口实例
                IPEndPoint iep = new IPEndPoint(IPAddress.Broadcast, 6888);
                //设置该scoket实例的发送形式
                sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
                IPHostEntry ipHost = Dns.Resolve(Dns.GetHostName());
                IPAddress ipAddr = ipHost.AddressList[0];
                //string msg = Encoding.GetEncoding("GBK").GetString(buffer,0,buffer.Length);
                byte[] buffer = Encoding.GetEncoding("GBK").GetBytes(MsgContext);
                sock.SendTo(buffer, iep);
                sock.Close();
                return "Send Msg OK!";
            }
        }
    }
    --------------在数据库表的触发器里调用存储过程,通知其他程序数据已经改变------------------ALTER    TRIGGER [Tgr_SendMenuChgMessageToPOS] ON [dbo].[RMSMenu] 
    FOR UPDATE,INSERT
    ASdeclare @MessageText varchar(4000)
    declare @TmpStr varchar(100)
    declare @MenuID varchar(10)
    DECLARE @MenuIDSTR varchar(4000)
    declare @cnt intselect @cnt = count(*) from inserted
    if @cnt = 0 
       begin
          select @cnt      
          return
       end
    select @TmpStr ='3|all|192.168.0.198|update+1+['
    select @MenuIDSTR=''
    declare  Cur_Meunu CURSOR  FOR select MenuID  from inserted 
    OPEN Cur_Meunu
    FETCH NEXT FROM Cur_Meunu INTO @MenuID
    WHILE @@FETCH_STATUS=0
        BEGIN
          if @MenuIDSTR=''
             SELECT @MenuIDSTR=@MenuID
          else 
             SELECT @MenuIDSTR=@MenuIDSTR+','+@MenuID     
          FETCH NEXT FROM Cur_Meunu INTO @MenuID      
        END
    CLOSE Cur_Meunu
    DEALLOCATE Cur_Meunuif @cnt<50
       begin
          SELECT @MessageText = @TmpStr+@MenuIDSTR+']'
          exec Proc_SendMsgToClient @MessageText
       end
    else
       begin
         --需要更新的菜品太多,通知更新全部
         exec Proc_SendMsgToClient '3|all|192.168.0.198|update+1'
       end