【架构之路(分布式三部曲)】

上文详细讨论了MQ的使用方法,MQ作为一种信息存储机制,将消息存储到了队列中,这样在做分布式架构时可以考虑将消息传送到MQ服务器上,然后开发相应的服务组件获取MQ中的消息,自动获取传送的消息,将消息发送给处理的程序。那么上文就MQ做了详细的讨论,并没有介绍有关服务组件的内容,也就是说如果我们开发的程序想要实现自动的消息接收和推送的服务的话,这里就必须考虑使用Windows Service来实现了,Windows Service是一种实时运行的组件,可以实时处理消息,该篇文章将会讨论Windows Service的开发方法。一、WS理论篇

MQ和WS技术相结合其实就可以看做是一个简单的ESB程序,这样可以通过调用服务来实现消息中间件的处理功能,可以开发包括消息推送、接收、处理的应用程序。WS是在Windows操作系统中才会有的,是集成到系统中的,一个WS在开启后会一直运行,直到停止该WS。在具体的项目中开发的WS是作为组件存在的,也就是说系统中的某部分需要实时运行,这时候可以考虑开发WS组件。

1.1 windows service VS web service

那么这里需要思考一个问题,windows Service和web Service它们两个都是服务,但是服务的对象是不同的。在web应用程序中web service是一个行业的信息服务标准,它为web应用程序之间架设了一个桥梁,使得应用程序之间可以互相的交流通信,也就是说web service是在web分布式应用中必然会用到的技术。 相较下来windows Service就比较狭窄了,它只能在windows system中运行,可以为windows的应用提供功能服务上的支持,在开发windows Service时常常会考虑两种情况,一是运行的组件考虑需要实时运行,另外是组件可以需要被多个程序调用,比如经常在开发中用到的sql server,它有很多子程序,这些程序之间会共用某个功能,,所以此时就把它做成了一个服务。

1.2 ws开发

ws的组成是比较简单的,因为它本身固有的属性很少,大部分功能是通过调用其它的类库或者组件来组合功能,具体的ws的组成如下导图所示:

在开发ws时会有两个大的部分,分别是Service和Installer,Service是服务的内部功能逻辑,也就是服务的本体,服务要做的操作都是写到里面的;Installer是服务的安装部分,也就是配置了该服务在windows中显示的属性。 Service:继承自ServiceBase,其中包括服务所有的运行内容,开发界面类似于winForm中的自定义控件的开发,能够添加系统控件及第三方控件。 Installer:分为两种,其中的serviceProcessInstaller配置服务的被调用的用户类型,serviceInstaller配置服务本身属性,如服务名称、服务启动方法等。二、WS Demo

上文对WS的基本内容做了详细的了解,通过理论来指导实践,这样在开发的时候思路才能够很清晰,关于WS的理论部分这里不再详细的讨论,接下来我们开发一个简单的WS Demo。 上篇文章详细讨论了MQ的开发方法,并开发了一个简单的MQ项目,这里就继续使用上文的MQ的项目来开发一个对MQ消息处理的WS组件,该组件主要是负责处理消息队列中的信息,获取消息,并把消息的主题内容保存到文本中。 具体程序的分布图如下所示:

2.1 服务代码

上面的程序分布图是结合上文的MQ来绘制的详细的架构图,其中的数据发送部分的程序在上文已经有介绍,这里不再详细讨论,下面的代码就是演示了分布图中的Service Handle data和Save data部分的功能,具体功能如下代码:

using System;using System.IO;using System.ServiceProcess;using System.Threading;using System.Timers;using System.Messaging;namespace WindowsService1{public partial class Service1 : ServiceBase{//declare a MQprivate MessageQueue queue;public Service1(){InitializeComponent();//create a path for queuestring strpath = ".\\Private$\\EKTestQueue";//create a messagequeue and assign a path for this queuequeue= new MessageQueue(strpath);//the queue formatter that can get queuebody based on the formatterqueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });}/// <summary>/// service start event/// when we start this service then it will run this method/// </summary>/// <param name="args"></param>protected override void OnStart(string[] args){//used to debug the code when start this serviceThread.Sleep(30000);}/// <summary>/// service stop event/// </summary>protected override void OnStop(){}/// <summary>/// get message from queue and save the message to file/// </summary>private void GetAndWriteMessage(){//recevie a new one MQvar ms=queue.Receive();//save the data to fileif (ms!=null){this.AddTextLine(ms.Body.ToString());}}/// <summary>/// save the MQ message to file/// </summary>/// <param name="line">the message that want save</param>private void AddTextLine(string line){try{//save the message to Message.txt fileFileStream file=new FileStream("D:\\Message.txt",FileMode.OpenOrCreate,FileAccess.ReadWrite);StreamWriter writer=new StreamWriter(file);writer.BaseStream.Seek(0, SeekOrigin.End);writer.WriteLine(line+"\r\n");writer.Flush();writer.Close();file.Close();file.Dispose();}catch (Exception ex){throw new Exception(ex.Message);}}private void timer1_Elapsed(object sender, ElapsedEventArgs e){GetAndWriteMessage();}}} 上面的代码主要是在服务中添加了信息处理的模块,这样就能够实现时时获取queue中的数据并对数据进行操作。 Note1:在服务的OnStart事件中添加了Thread.Sleep(3000)是为了调试服务启动代码而存在的,因为服务启动的时候是很快的也就是说我们在调试代码时经常会将项目附加到服务中,但是这时候服务是已经启动的了,是没有办法调试它的,所以我们添加了改行代码,这样就可以延迟服务的启动时间,给我们制造了充足的时间将代码附加到服务中来调试服务的启动代码。 Note2:Timer控件,该控件一定要是System.Timers.Timer控件,因为在添加时可能会误添加为在Thread命名空间下载Timer控件,这样就会导致服务在启动时出错,不能正常注册该控件。

2.2 服务调试

用开怀的笑容去迎接每一个黎明,

【架构之路(分布式三部曲)】

相关文章:

你感兴趣的文章:

标签云: