使用windows服务和MSMQ和进行日志管理(解决高并发问题)
首先,建立一个windows服务项目
然后进行设计视图
在工作区空白处右属,添加一个安装项目
然后就可以写我们的代码了,我们的服务需要实时监视MSMQ的队列中有没有记录,如果有,就向数据库中插入
核心代码如下
/// <summary>
/// 接收来自MSMQ的消息,并保存到数据库
/// </summary>
public class MessageQueueService
{
public static bool blnStopThread;
public static string exTemp = string.Empty; public MessageQueueService()
{
//
// TODO: 在此处添加构造函数逻辑
//
} public static void Start()
{
string queuePath = ".\\Private$\\zzl";
IsQueueExists(queuePath);
MessageQueue myQueue = new MessageQueue(queuePath); myQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(Log) }); do
{
try
{
// Receive and format the message.
Message myMessage = myQueue.Receive(); //当消息队列空时,线程会挂起
Log log = (Log)myMessage.Body; if (log == null) return; Save(log);//保存到数据库,此处略详细代码
}
catch (System.Exception ex)
{
//异常处理
//……
}
} while (blnStopThread == false);
} private static void IsQueueExists(string path)
{
if (!MessageQueue.Exists(path))
{
MessageQueue.Create(path);
}
} private static void Save(Log entity)
{
using (SqlConnection sqlconn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["conn"].ToString()))
{
using (SqlCommand sqlcomm = new SqlCommand(
"INSERT INTO [Web_Logs]([LogID],[FromURL],[ExeSQL],[FromSystem],[HttpMethod],[OccurTime],[info]) VALUES (@LogID,@FromURL,@ExeSQL,@FromSystem,@HttpMethod,@OccurTime,@Info);"
, sqlconn))
{
SqlParameter parameter = new SqlParameter("@ExceptionID", SqlDbType.VarChar, );
parameter.Value = Guid.NewGuid().ToString();
sqlcomm.Parameters.Add(parameter); parameter = new SqlParameter("@LogID", SqlDbType.VarChar, );
parameter.Value = entity.ID;
sqlcomm.Parameters.Add(parameter); parameter = new SqlParameter("@FromURL", SqlDbType.VarChar, );
parameter.Value = string.Empty;
sqlcomm.Parameters.Add(parameter); parameter = new SqlParameter("@ExeSQL", SqlDbType.VarChar, );
parameter.Value = string.Empty;
sqlcomm.Parameters.Add(parameter); parameter = new SqlParameter("@FromSystem", SqlDbType.Int);
parameter.Value = ;
sqlcomm.Parameters.Add(parameter); parameter = new SqlParameter("@HttpMethod", SqlDbType.VarChar, );
parameter.Value = string.Empty;
sqlcomm.Parameters.Add(parameter); parameter = new SqlParameter("@Info", SqlDbType.VarChar, );
parameter.Value = entity.Info;
sqlcomm.Parameters.Add(parameter); parameter = new SqlParameter("@OccurTime", SqlDbType.DateTime);
parameter.Value = entity.OccerTime;
sqlcomm.Parameters.Add(parameter); sqlconn.Open();
sqlcomm.ExecuteNonQuery();
sqlconn.Close();
}
}
} public class Log
{
public string ID { get; set; } public string Info { get; set; } public DateTime OccerTime { get; set; } public void PrintAll()
{
Console.WriteLine("{0} {1} {2}", ID, Info, OccerTime);
}
}
为了使服务实时对MSMQ进行监控,需要我们在服务中使用一个定时事件,代码如下:
当然在程序初始化时,需要为一个System.Timers.Timer类型进行相应的初始化工作
this.timer1 = new System.Timers.Timer();
this.timer1.Start();
this.timer1.Interval = ;
this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed);
这个WINDOWS服务我们已经添加完成,现在需要做的就是MSMQ部分了,事实上windows服务这块主要是从MSMQ中得到消息,而在MSMQ这块主要是向MSMQ去写入消息,微软的MSMQ完全支持复杂类型,也就是说你可以将一个类对象写到MSMQ中
/// <summary>
/// 日志实体
/// 可以被序列化
/// </summary>
[Serializable()]
public sealed class Log
{
public string ID { get; set; } public string Info { get; set; } public DateTime OccerTime { get; set; }
} /// <summary>
/// MSMQ消息功能密封类
/// 向消息队列中写入日志信息
/// </summary>
public sealed class MSMQLog
{
private static object sync = new object();
private static object syncWrite = new object();
static volatile MessageQueue writer = null; private static MessageQueue MSQWriter
{
get
{
if (writer == null)
{
lock (sync)
{
if (writer == null)
{
string queuePath = ".\\Private$\\zzl";
IsQueueExists(queuePath);
writer = new MessageQueue(queuePath);
}
}
}
return writer;
}
} private static void IsQueueExists(string path)
{
if (!MessageQueue.Exists(path))
{
MessageQueue.Create(path);
}
} public static void Write(Log log)
{
lock (syncWrite)
{
MSQWriter.Send(log);
}
}
}
当需要调用它时,可以这样:
安装与卸载windows服务的方法:
installutil工具在目录:系统盘:\WINDOWS\Microsoft.NET\Framework\v4.0.30319下,运行cmd,输入
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\installutil xxxx.exe 回车,即可完成windows服务的安装。
卸载则为输入 C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\installutil /u xxxx.exe 回车。
本例经过自己实验,已经成功,当若干客户端同时进行某种操作时,可以同时写入数据库中,这就是我要说的,进行window服务和MSMQ技术实现高并发的解决方案
使用windows服务和MSMQ和进行日志管理(解决高并发问题)的更多相关文章
- C# Windows服务安装出现System.Security.SecurityException异常解决办法
我把注册windows服务所用的安装及启用服务命令写到了bat可执行文件(名称为install.bat)中,如下所示: %SystemRoot%\Microsoft.NET\Framework\v4. ...
- Datasnap 服务端 (Server)Session 管理 --- 解决 全示例慢(Google)
Datasnap 服务端 (Server)Session 管理: http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Server_Side_Ses ...
- 小D课堂 - 新版本微服务springcloud+Docker教程_6-05 高级篇幅之高并发情况下
笔记 5.高级篇幅之高并发情况下接口限流特技 简介:谷歌guava框架介绍,网关限流使用 1.nginx层限流 2.网关层限流 开始 mysql最大的连接数就是3千多.如果想把应用搞好 ...
- C# 开发 Windows 服务 使用Log4net 组件 不能生成日志文件
使用VS2012开发Windows服务,需要使用Log4net日志组件记录业务情况,但是始终生成不了日志文件. /// <summary> /// 入口方法 /// </summar ...
- 将MongoDB设为Windows服务
转自“简时空”:<将MongoDB设为Windows服务> 1.前言 MongoDB 安装.配置完后,必须先启动它,然后才能使用它.通常有3中方式来启动数据库实例:① 通过命令行方式:② ...
- 使用 Topshelf 创建 Windows 服务
Ø 前言 C# 创建 Windows 服务的方式有很多种,Topshelf 就是其中一种方式,而且使用起来比较简单.下面使用 Visual Studio Ultimate 2013 演示一下具体的使 ...
- Topshelf+Quartz3.0基于控制台应用程序快速开发可调度windows服务
1.TopShelf TopShelf是一个开源的跨平台的宿主服务框架.可通过.Net Core/.Net Framwork控制台应用程序快速开发windows服务,更加便于服务调试. 本文基于.Ne ...
- ASP.NET 下使用特定身份完成windows服务的功能操作
今天部署项目的发现一个问题: 在本地Win7系统下利用Web页面完成Windows服务的功能操作(启动.停止.安装.卸载)都是正常的,而部署到Server2008系统下,再使用Web页面完成windo ...
- 微服务(SOP)日志管理
问题: 大型企业应用规模大,调试 / 解决问题由于在生产环境中不会有开发环境的调试工具,如果需要模拟还原当时的环境, 目前的解决办法是进行日志记录 日志记录的常用方式: 使用SpringAop进行切入 ...
随机推荐
- poj1039Pipe(直线交点、叉积)
链接 之前刷poj计划时刷过,不过也没什么印象了.打铁还是趁热,还没热起来就放弃了,前面算是做了无用功,有如胡乱的看解题报告一样. 题目应该是比较经典的集合入门题,黑书上有一部分核心讲解. 题目中的最 ...
- Java编程思想学习笔记_6(并发)
一.从任务中产生返回值,Callable接口的使用 Callable是一种具有泛型类型参数的泛型,它的类型参数表示的是从方法call返回的值,而且必须使Executor.submit来去调用它.sub ...
- JavaSE复习_12 Socket网络编程
△客户端使用Scanner与BufferedReader的异同,Scanner在客户端调用s.shutdownoutput的时候,将会因为读不到行而报异常,但是BufferedReader的readl ...
- return
return作为返回关键字,有以下两种意义的返回格式: 1,返回把握与函数成果:停止函数执行,返回调用函数,并且把函数的值作为返回成果. turn只能退出当前函数,如果多个函数嵌套就不行了,要想整个退 ...
- MyBatis——实现关联表查询
原文:http://www.cnblogs.com/xdp-gacl/p/4264440.html 一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创 ...
- D3.js 让图表动起来
D3 支持制作动态的图表.有时候,图表的变化需要缓慢的发生,以便于让用户看清楚变化的过程,也能给用户不小的友好感. 一.什么是动态效果 绘制完成后不再发生变化的,这是静态的图表. 动态的图表,是指图表 ...
- hiho_1078_线段树区间修改
题目 给定一组数,要求进行若干次操作,这些操作可以分为两种类型: (1) CMD 1 beg end value 将数组中下标在[beg, end] 区间内数字都变为value (2) CMD 2 b ...
- Java的动态绑定
看这段代码 Father father = new Son(); 父类引用指向子类对象,这是java的多态特性,有多态引到动态绑定,如何引入呢,看这个代码: class Father{ private ...
- linux下创建管理员组 使用 su - 命令
通常情况下,用户通过执行“su -”命令.输入正确的root密码,可以登录为root用户来对系统进行管理员级别的配置.但是,为了更进一步加强系统的安全性,有必要建立一个管理员的组,只允许这个组的用户来 ...
- 联想手机#P1来了#P1背后的故事系列
http://bbs.lenovo.com/forum.php?mod=viewthread&fid=928&tid=560992&extra=page%3D1 联想手机#P1 ...