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

上文详细讨论了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 MQ
        private MessageQueue queue;
        public Service1()
        {
            InitializeComponent();

            //create a path for queue
            string strpath = ".\\Private$\\EKTestQueue";
            //create a messagequeue and assign a path for this queue
            queue= new MessageQueue(strpath);
            //the queue formatter that can get queuebody based on the formatter
            queue.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 service
            Thread.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 MQ
            var ms=queue.Receive();
            //save the data to file
            if (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 file
                FileStream 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 服务调试

在开发完成服务后不能够直接运行使用,而是要将服务安装到系统的Services中才能够查看服务是否正常运行,因为服务不同于一般的应用程序,想要使用服务就必须将服务安装到系统当中。另外服务的调试也是很麻烦的一件事,因为服务不同于应用程序,想要调试它就不能采用普通的调试方法了,这里介绍一种附加进程的调试方法,还有其它如写日志等的调试方法,可以查看网上的文章来详细了解。

2.2.1 安装服务

首先要打开控制台并进入到C:/Windows/Microsoft.Net/Framework/v4.0.30319中,运行InstallUtil.exe工具,并添加相应的开发的服务程序,然后回车运行就可以安装,如下所示:

     C:/Windows/Microsoft.Net/Framework/v4.0.30319>InstallUtil.exe C:\Code\WindowsService1\WindowsService1\bin\Debug\WindowsService1.exe

安装完成后查看Services工具中的服务如下图所示:

安装后服务显示的名称是根据ServiceInstaller的属性来控制的,在开发时指定了ServiceName属性名称为Jack‘s Service所以安装后显示的服务名称如上图所示。

2.2.2 将WS附加到进程

首先打开Tools下面的Attach to Process窗体,然后在程序中找到该服务,具体如下面两张图所示:

找到后双击该程序即可将添加源码到服务,这时候就能够对服务的代码进行调试了。

Note3:在附加进程时,所附加的进程名称是和服务的程序名称相一致的,并不是和Services工具中的名称一致。因为该服务程序的名称为WindowsServices1所以我们要把代码附加到该服务中,如上图所示。

2.2.3 删除服务

在不使用服务后也可以删除服务,删除方法类似于服务的安装,具体方法如下所示:

     C:/Windows/Microsoft.Net/Framework/v4.0.30319>InstallUtil.exe/u C:\Code\WindowsService1\WindowsService1\bin\Debug\WindowsService1.exe

结语

文章主要介绍了WS的基本构成,并通过一个具体的示例来演示开发WS时需要注意的地方,最后介绍了一种WS的调试方法,很简单,但是新手会有很多问题,具体的问题具体分析,可以留言讨论。

WS在分布式开发中拥有重要作用,它能够协调各个程序之前的交互功能,可以作为程序的通信桥梁,但是WS本身有很多局限性,它只能运行在Windows系统中,另外WS的代码调试一直惨遭诟病,需要开发人员一次次的安装、附加进程、删除的操作,很耗费时间,所以在做分布式开发时一定要慎重考虑使用WS。

时间: 2024-12-08 10:41:42

【架构之路(分布式三部曲)】--WS的相关文章

大型网站架构系列:分布式消息队列(二)

本文是大型网站架构系列:消息队列(二),主要分享JMS消息服务,常用消息中间件(Active MQ,Rabbit MQ,Zero MQ,Kafka).[第二篇的内容大部分为网络资源的整理和汇总,供大家学习总结使用,最后有文章来源] 本次分享大纲 消息队列概述(见第一篇:大型网站架构系列:分布式消息队列(一)) 消息队列应用场景(见第一篇:大型网站架构系列:分布式消息队列(一)) 消息中间件示例(见第一篇:大型网站架构系列:分布式消息队列(一)) JMS消息服务 常用消息队列 参考(推荐)资料 本

架构之路(九)Session Per Request

前面的两篇反应很差:没评论没赞.很伤心啊,为什么呢?搞得我好长一段时间都没更新了——呵呵,好吧,我承认,这只是我的借口.不过,还是希望大家多给反馈.没有反馈,我就只能猜了:前面两篇是不是写得太“粗”了一点?所以这一篇我们尽量详细点吧. Session Per Request是什么 这是一个使用NHibernate构建Web项目惯用的模式,相关的文章其实很多.我尽量用我的语言(意思是大白话,但可能不精确)来做一个简单的解释. 首先,你得明白什么是session.这不是ASP.NET里面的那个ses

大型网站架构系列:分布式消息队列(一) (转)

以下是消息队列以下的大纲,本文主要介绍消息队列概述,消息队列应用场景和消息中间件示例(电商,日志系统). 本次分享大纲 消息队列概述 消息队列应用场景 消息中间件示例 JMS消息服务(见第二篇:大型网站架构系列:分布式消息队列(二)) 常用消息队列(见第二篇:大型网站架构系列:分布式消息队列(二)) 参考(推荐)资料(见第二篇:大型网站架构系列:分布式消息队列(二)) 本次分享总结(见第二篇:大型网站架构系列:分布式消息队列(二)) 一.消息队列概述 消息队列中间件是分布式系统中重要的组件,主要

架构之路

架构之路 www.ediandian.org 我,是一个Linux运维工程师,俗称运维亦或黑锅侠,英文:OperationEnginner;网名:沐浴春风,别名:浴春风,英文名:fonge;祖籍河南周口市,现工作于杭州;做事风格,来去如风,有始有终:性格热情豪爽,奔放而不羁,勇而有义,宽宏而有大略:表达能力-5;年龄,80的尾巴,关注技术和运动,喜爱数码产品,对于这些东西我只能说:买买买,按斤买;我会犯错误,偶尔有点坏脾气但不会任性而为,技术面前一颗敬畏和征服之心;技术人,充满创造力的自由不羁的

大型网站架构系列:分布式消息队列(一)(转)

大型网站架构系列:分布式消息队列(一) 以下是消息队列以下的大纲,本文主要介绍消息队列概述,消息队列应用场景和消息中间件示例(电商,日志系统). 本次分享大纲 消息队列概述 消息队列应用场景 消息中间件示例 JMS消息服务(见第二篇:大型网站架构系列:分布式消息队列(二)) 常用消息队列(见第二篇:大型网站架构系列:分布式消息队列(二)) 参考(推荐)资料(见第二篇:大型网站架构系列:分布式消息队列(二)) 本次分享总结(见第二篇:大型网站架构系列:分布式消息队列(二)) 一.消息队列概述 消息

CK21190-Mycat分布式架构之Mycat分布式架构实战解析

CK21190-Mycat分布式架构之Mycat分布式架构实战解析 Mycat是国内第一个卖电子书的开源软件,参与的作者们平生第一次分到了一笔开源收入的酬劳,虽然微不足道,但那一刻,他们都坚信,Mycat会越来越好.如今,Mycat的稳定参与者人数已经超过10人,包括很多美女,而第三代新生志愿者团队也正在形成中.Mycat已经有超过300个生产案例,从政府的项目.电信项目.电商项目.O2O项目.游戏到一些大数据分析的项目,Mycat的生态圈正在加速形成中,使用或者研究过Mycat的知名公司名单越

西二旗程序员家庭装修的架构之路 - 1

在北京,有这么一个神奇的地方---西二旗,这里坐落着中国最知名的IT公司群体:广联达,腾讯,百度,网易,新浪,联想,甲骨文,IBM,--(未来还会有大鸟软件:www.bigbird.wang,啊哈哈哈--). 工作生活在这里的一群人--旗人!区别三里屯的"屯儿里的人",亦庄的"庄儿里的人",中关村的"村儿里的人",这群人有点精神分裂,有点完美主义强迫症,很可爱,也很多金,却不似寻常之人,自成一体. 这群人爱看博客,爱写博客,爱把听到的,见到的一切

JavaWeb项目架构之Kafka分布式日志队列

架构.分布式.日志队列,标题自己都看着唬人,其实就是一个日志收集的功能,只不过中间加了一个Kafka做消息队列罢了. kafka介绍 Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写.Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据. 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素. 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决. 特性 Kafka是一种高吞

架构之路:nginx与IIS服务器搭建集群实现负载均衡(三)

参考网址:https://blog.csdn.net/zhanghan18333611647/article/details/50811980 [前言] 在<架构之路:nginx与IIS服务器搭建集群实现负载均衡(二)>中提到有好多有趣的地方,接下来就为大家一块儿讲讲在深入研究过程中遇到那些有趣的事情. ·实战之行--发现问题 ·探索之旅--寻出问题原因 ·解决之道--解决问题 [实战之行] 在<架构之路:nginx与IIS服务器搭建集群实现负载均衡(二)>中做了小Demo,当时做

架构之路:nginx与IIS服务器搭建集群实现负载均衡(二)

[前言] 在<架构之路:nginx与IIS服务器搭建集群实现负载均衡(一)>中小编简单的讲解了Nginx的原理!俗话说:光说不练假把式.接下来,小编就和大家一起来做个小Demo来体会一下Nginx的神奇之处. [准备工作] ·安装一款文本编辑器(这里以Notepad++为例) ·下载Nginx(这里以Nginx-1.4.7为例,其他版本操作相同) ·建两个简单网页:在文件夹test1新建一个html页内容为--我是Test1,在文件夹test2新建一个html页内容为--我是Test2) ·将