消息智能路由組件SmartRoute

         消息傳遞在軟件開發過程當中是一件很常見的事情,而在不一樣的場景所使用消息傳遞方式也有所不一樣,在對象之間制定相關接口方法和對象結構,對於進程之間可能使用內存共享或一些通信產品,在不一樣服務器之的消息通信則使用一些通信產品(MQ)或構建知足本身的RPC通信機制.不一樣場景技術人員都要掌握不一樣的技術方法來實現,因爲應用技術和差別性容易致使開發成本和維護成本的上漲,爲了解決這一系列的問題在這段時候思考後實現一種統一的消息傳遞方式,而這種應用方式不論是對象間,進程或服務器在應用上都不會任何差,在這裏稱這技術爲消息智能路由(爲了快速驗證想法,大概花了一週的業餘時間制定了一個可用的原型). node

SmartRoute可實現場景

如何智能?

         SmartRoute是依據訂閱者的ID來進行消息發送傳遞,相似於郵件地址同樣;只要在訂閱的時候制定相應的接收實現便可接收投遞到這一ID的消息.然而這方式很是普通並無什麼所謂智能高大上在這裏.其實SmartRoute的智能優勢在於技術人員徹底不用去關心訂閱者所在的位置,不論是當前程序,其餘應用程序仍是其餘服務器,SmartRoute均可以自動地幫你投遞過去.最重要的是技術人員徹底不用配置任何環境和安裝任何中間服務,只須要在程序中加載SmartRoute這系列的工做均可以自動完成(沒錯,即便你是跨服務器投遞消息也不須要作額外的配置和安裝中間服務器);每一個SmartRoute實例除承擔着接收和投遞工做的同時也承擔了消息路由的角色;不一樣進程和不一樣服務器運行的SmartRoute實例會自動組建集羣(而這個自動構建也不須要配置或安裝服務) 數據庫

Hello應用

         一個組件的易用性才能體現它的價值,因此在設計SmartRoute的時候就遵循一個原則,在應用中儘可能作到不須要配置便可用.如下經過經過簡單的Hello程序來描述一下組件設計的易用性. c#

HelloRequest 服務器

class Request : ISubscribeHandler
    {
        public Request()
        {
            Route.Subscribe("Ken", this);
        }

        public DateTime CreateTime
        {
            get;
            set;
        }

        public void Say(string name)
        {
            Hello hello = new Hello { Name ="hello "+ name };
            hello.SendTo(s => s.From("Ken"), "henry");
        }

        public ILogHandler Log
        {
            get;
            set;
        }

        public void Process(INode node, IMessage message)
        {
            Hello hello = message.GetBody<Hello>();
            Console.WriteLine("{0} Request  receive:{1}",DateTime.Now, hello.Name);
        }
    }

HelloReqponse 網絡

class Response : ISubscribeHandler
    {
        public Response()
        {
            Route.Subscribe("henry", this);
        }
        public DateTime CreateTime
        {
            get;
            set;
        }

        public ILogHandler Log
        {
            get;
            set;
        }

        public void Process(INode node, IMessage message)
        {
            Hello hello = message.GetBody<Hello>();
            Console.WriteLine("{0} response receive:{1}",DateTime.Now, hello.Name);
            hello.Name = "hello " + message.Sender;
            hello.SendTo(message.Sender);
        }
    }

RequestResponse各自訂閱了信息,經過實現ISubscribeHandler來接收投遞過來的消息.能夠經過運行如下代碼來測試訂閱的有效性. 測試

class Program
    {
        static Request request;
        static Response response;
        static void Main(string[] args)
        {
            request = new Request();
            response = new Response();
            while (true)
            {
                request.Say("henry");
                System.Threading.Thread.Sleep(3000);
            }
        }
    }

l  運行結果 this

擴展進程間通信

         對於SmartRoute對現有的訂閱進行跨進程訪問則是一件很是簡單的事件,並不須要修改或配置任何代碼便可完成.下面分別建兩個程序分別引用HelloRequestHelloResponse spa

HelloRequestApp 設計

class Program
    {
        static Request request;
        static void Main(string[] args)
        {
          
            request = new Request();
            while (true)
            {
                request.Say("henry");
                System.Threading.Thread.Sleep(3000);
            }
        }
    }

HelloResponseApp code

class Program
    {
      
        static Response response;
        static void Main(string[] args)
        {
           
            response = new Response();
            System.Threading.Thread.Sleep(-1);
        }
    }

l  運行結果


服務器間通信

         SmartRoute在同一個局域網內會自動發現和組建路由,因此在不調整任何設計和代碼的狀況下,只須要把兩個應用部署在不一樣服務器就能夠進行信息訂閱和發送.

技術要點

l  通訊功能

除了本進程內訂閱和轉發不須要涉及到通信外,進程和服務器間都須要通信服務.因此作這樣一個功能須要點通信技術經驗,不過如今成熟的開發的通信庫也有很多能夠直接拿來用.

l  節點發現和握手

組件的靈活之處就是不須要任何配置就能實現交互,因此每一個節點都具有發其餘節點的能力;爲了知足這一需求須要使用UDP廣播技術,每一個節點都會把本身的服務信息廣播出去,當其餘節點接收到這些信息後就建立握手鍊接.

l  同步訂閱信息

因爲在設計的過程當中強調沒有數據中心點,就是整個集羣裏的全部節點都是相互直連的.因此每一個節點的訂閱信息都會同步到不一樣節點上,這樣才能保證消息投遞的有效性.爲了保證訂閱的有效性一樣訂閱取的時候須要告訴其餘節點變動狀況.

l  制定訂閱規則

訂閱在接收消息處理的狀況是多樣性的,有多是操做數據庫,HTTP或者網絡轉發;因此須要給訂閱制定規劃,讓使用者能夠實現不一樣的訂閱處理.

如下是一個簡單網絡轉發訂閱

public class TCPSubscribeHandler : ISubscribeHandler
    {
        public ILogHandler Log { get; set; }

        public IChannel Channel
        {
            get;
            set;
        }

        public void Process(INode node, IMessage message)
        {
            Channel.Server.Send(message,Channel);
        }

        public DateTime CreateTime
        {
            get;
            set;
        }
    }

下載DEMO

相關文章
相關標籤/搜索