数据实时监视如何实现最小资源消耗? 数据实时监视发现有三种方法:(1)timer (2)Socket(3)Sql 触发+Dll请问 2、3如何实现?或者大家有别的方法? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 如果是sql2005的话安装SQL Server 2005性能监视器计数器,资源消耗很少 先说说:是server 端的exe 对数据库进行监控吗? (1)timer (2)Socket(3)Sql 触发+Dll这是3个方案么?如同如何做一个面包,方案1:黄油、面粉,方案2:烤箱,方案3:巧克力面包。 同LS...LZ再吃点亏,多打点字吧 c/s结构,socket通讯,协议封装; 你这样做的话,你的服务端对于数据库来说其实也是客户端1.你已经知道每秒会最多插入5条数据,那么你就每隔1秒从数据库中把最新的5条记录取出不就行了吗(如果每条记录有时间字段)?2.这种方法个人认为是不错的, 你的客户端将数据插入到数据库的同时,通过SOCKET/WCF等方式,把数据传递给监视画面,这样做的实时性更高,对数据库的开销更小 每秒查询一次服务器资源消耗就太大了,什么服务器啊~我这里每天单台处理百万级的,偶尔千万,cpu不会超过20%还有统计系统和业务系统是不是做在一起了? 使用日志文件如log4net,DAL方法上监视触发器用线程定时刷新 总共3-500w还是每天,如果总共的话普通pc足能胜任了.钱多的话首推IBM,SUN,HP,DELL,国产品牌曙光联想什么的没用过.性能都差不多,备灾方案各异, 还有就是服务的区别,我这里的DataCenter也就8核 32-64G内存的配置 不是很高,品牌就不说了,免得做广告的嫌疑. socket是实现 C/S的一种方式,对你所提的这个问题没有任何意义,不知道为什么你会说"套接字不会用,怕在实际使用出现新的问题"现在我从你的主题以及回帖里大概确定了以下几点:1,你的C/S模式不是用SOCKET实现的.(这个无所谓,HTTP也无妨)2,你是这个模式 C->S->SQLSERVER如果真是这样的话,则证明 你的 S端是个请求中转站,也就是说你的S端会比数据库更具有数据库统计的准确性.所以我就不明白,为什么你还非得从数据库获得最新数据来统计.如果按我的理解是对的话,那么可以这样做:以S端为中心,每天临晨从和数据库相互同步一次数据,这样确保数据的准确性.-------------------------------------如果不是我理解的这个模式 那么请你细说你现在的 环境结构. 你至少得把整体通讯结构说出来,我们才能给你确切解决方案,否则你得到的也是我们猜测的答案. 我再确认一个问题:到底是1:client ---上传数据提交到SQL--> sqlserver2005 然后 再在 sqlserver2005的服务器上写一个程序对数据进行统计还是2:client ---上传数据提交到服务器上的一个程序--> server -----数据提交到SQL--> sqlserver2005 现在我从你最后一次的答复中发现1的可能性比较大. 1、就不说了,是基于轮询完成的监控。2、套接字,这个基本上应该是一个基于监听端口的实现,有个监听端口一直在监听。3、触发器,这个基本上不是用于实时数据监控的,这个在Insert,Update,Delete时触发,这个没有一般性。第二个方案在一般的C/S项目中比较合适,这实际上是一个消息模型,可以应用到非套接字的应用中。 我们公司也在做类似的东西,就是监控主机及进程的资源(cpu,内存,虚拟内存,网卡流量等),刚刚把系统设计做完,通讯你肯定要用socket了, 呵呵 既然确认了问题那这就好办了.有2个办法1: client和server 都改代码.client 每次和数据库同步成功之后 都通知server一次(如果你不会写socket那么你写http吧,会简单很多)这样的话就回到我提的方案2的轨道上来了,你只需要在夜晚让server何sqlserver进行同步即可,数据库压力小很多.并且程序压力也不大每秒处理5个HTTP请求对你的server端来讲也没什么问题.2:只改server端就是server端每间隔N秒就去数据库同步 一次数据.这样的话你最好是设计成日表/月表 机制(如果你设计了日表的话就可以只取最近1天的数据,历史数据不用每N秒取1次,)最后说下数据库优化.考虑到将来维护,其实月表机制是很不错的办法.(不过程序就得大改了)如果不用日表月表,那么至少得每个月都把历史数据移到备份库 socket 客户端、服务端如何实现远程通信,安全如何?效率如何? 你自己实现http server 阻塞+多线程 也是从socket层来实现的,只不过是短连接处理而已.安全性没必要考虑,非要考虑安全的话就加密数据包(这个实在无必要.) 自己UP一下!!UP又分呀!!(可以看我以前的帖子) 我说一下第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', @MsgContextIF @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,INSERTASdeclare @MessageText varchar(4000)declare @TmpStr varchar(100)declare @MenuID varchar(10)DECLARE @MenuIDSTR varchar(4000)declare @cnt intselect @cnt = count(*) from insertedif @cnt = 0 begin select @cnt return endselect @TmpStr ='3|all|192.168.0.198|update+1+['select @MenuIDSTR=''declare Cur_Meunu CURSOR FOR select MenuID from inserted OPEN Cur_MeunuFETCH NEXT FROM Cur_Meunu INTO @MenuIDWHILE @@FETCH_STATUS=0 BEGIN if @MenuIDSTR='' SELECT @MenuIDSTR=@MenuID else SELECT @MenuIDSTR=@MenuIDSTR+','+@MenuID FETCH NEXT FROM Cur_Meunu INTO @MenuID ENDCLOSE Cur_MeunuDEALLOCATE Cur_Meunuif @cnt<50 begin SELECT @MessageText = @TmpStr+@MenuIDSTR+']' exec Proc_SendMsgToClient @MessageText endelse begin --需要更新的菜品太多,通知更新全部 exec Proc_SendMsgToClient '3|all|192.168.0.198|update+1' end 救命:如何用C#做远程桌面的IP限制 做个网站,请人设计界面 关于正则表达式的菜鸟问题 C#连接Access问题,急需帮忙!谢谢! ADO.NET 的两个问题,50分求解 难题,如何创建不失真的矢量图格式,比如我生成一串数字,如果用gdi+生成后,保存为wmf格式,用freehand打开后缩放还是会失真? 。net三大核心技术是什么呀?知道的说一下,很急的。 TextBox Text 改变时触发事件 如何真正的关闭程序的运行 数据调用问题,请高手赐教,拜谢! C#自带数据库,有这种说法吗? 请问用socket 如何发送字符串数组啊?? 谢谢了!!!
安装SQL Server 2005性能监视器计数器,资源消耗很少
(2)Socket
(3)Sql 触发+Dll这是3个方案么?如同如何做一个面包,方案1:黄油、面粉,方案2:烤箱,方案3:巧克力面包。
你这样做的话,你的服务端对于数据库来说其实也是客户端1.你已经知道每秒会最多插入5条数据,那么你就每隔1秒从数据库中把最新的5条记录取出不就行了吗(如果每条记录有时间字段)?2.这种方法个人认为是不错的, 你的客户端将数据插入到数据库的同时,通过SOCKET/WCF等方式,把数据传递给监视画面,这样做的实时性更高,对数据库的开销更小
我这里每天单台处理百万级的,偶尔千万,cpu不会超过20%还有统计系统和业务系统是不是做在一起了?
触发器
用线程定时刷新
性能都差不多,备灾方案各异, 还有就是服务的区别,我这里的DataCenter也就8核 32-64G内存的配置 不是很高,品牌就不说了,免得做广告的嫌疑.
1,你的C/S模式不是用SOCKET实现的.(这个无所谓,HTTP也无妨)
2,你是这个模式 C->S->SQLSERVER如果真是这样的话,则证明 你的 S端是个请求中转站,也就是说你的S端会比数据库更具有数据库统计的准确性.所以我就不明白,为什么你还非得从数据库获得最新数据来统计.如果按我的理解是对的话,那么可以这样做:
以S端为中心,每天临晨从和数据库相互同步一次数据,这样确保数据的准确性.
-------------------------------------如果不是我理解的这个模式 那么请你细说你现在的 环境结构. 你至少得把整体通讯结构说出来,我们才能给你确切解决方案,否则你得到的也是我们猜测的答案.
我再确认一个问题:
到底是1:
client ---上传数据提交到SQL--> sqlserver2005 然后 再在 sqlserver2005的服务器上写一个程序对数据进行统计还是2:
client ---上传数据提交到服务器上的一个程序--> server -----数据提交到SQL--> sqlserver2005 现在我从你最后一次的答复中发现1的可能性比较大.
2、套接字,这个基本上应该是一个基于监听端口的实现,有个监听端口一直在监听。
3、触发器,这个基本上不是用于实时数据监控的,这个在Insert,Update,Delete时触发,这个没有一般性。第二个方案在一般的C/S项目中比较合适,这实际上是一个消息模型,可以应用到非套接字的应用中。
呵呵 既然确认了问题那这就好办了.有2个办法
1: client和server 都改代码.
client 每次和数据库同步成功之后 都通知server一次(如果你不会写socket那么你写http吧,会简单很多)
这样的话就回到我提的方案2的轨道上来了,你只需要在夜晚让server何sqlserver进行同步即可,数据库压力小很多.并且程序压力也不大每秒处理5个HTTP请求对你的server端来讲也没什么问题.2:只改server端
就是server端每间隔N秒就去数据库同步 一次数据.这样的话你最好是设计成日表/月表 机制(如果你设计了日表的话就可以只取最近1天的数据,历史数据不用每N秒取1次,)最后说下数据库优化.
考虑到将来维护,其实月表机制是很不错的办法.(不过程序就得大改了)
如果不用日表月表,那么至少得每个月都把历史数据移到备份库
安全性没必要考虑,非要考虑安全的话就加密数据包(这个实在无必要.)
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