WCF Routing 服務


  WCF4.0支持路由機制,通過RoutingService實現請求分發、攔截處理。

  一、應用場景

  1、暴露一個endpoint在外網,其余服務部署於內網;

  2、請求分發,能對服務做負載功能;


 

  二、WCF4.0 路由服務

  

  圖1- WCF路由示意圖

    WCF RoutingService使用了消息過濾器的功能,內置定義了6個過濾器滿足不同的需求:

    1、ActionMessageFilter:滿足指定的操作集之一,也就操作匹配;

    2、EndpointAddressMessageFilter:滿足指定的終結點地址;

    3、XPathMessageFilter:使用 XPath指定匹配的條件,用於實現基於內容路由的核心消息過濾器;

    4、MatchAllMessageFilter 與所有消息相匹配;

    5、MatchNoneMessageFilter 與所有消息都不匹配;

    對於以上默認提供的過濾器不能滿足需求,還可以通過創建自己的 MessageFilter 實現消息過濾器。如下我們通過一個demo實現wcf服務分發負載處理。


 

  三、WCF RoutingService負載處理請求

  1、創建一個WCF服務,名稱為:Aden.FK.WcfServiceA,基於console hosting實現,創建兩個ServiceHost。

    (1)接口定義和實現為:

[ServiceContract]
    public interface IWcfServiceA
    {
        [OperationContract]
        int GetNumber();

        [OperationContract]
        string GetString();
    }

    (2)服務的實現:

public class WcfServiceA : IWcfServiceA
    {
        public int GetNumber() 
        {
            string msg = "Service :" + OperationContext.Current.EndpointDispatcher.EndpointAddress.Uri;
            Console.WriteLine(string.Format("print: {0}", msg));

            return new Random().Next();
        }


        public string GetString()
        {
            string msg = "Service :" + OperationContext.Current.EndpointDispatcher.EndpointAddress.Uri;
            Console.WriteLine(string.Format("print: {0}", msg));

            return msg;
        }
    }

    (3)創建服務host:

int num = 2;
                int index = 0;
                List<ServiceHost> serviceHost = new List<ServiceHost>();
                for (int i = 1; i <= num; i++)
                {
                    serviceHost.Add(new ServiceHost(typeof(WcfServiceA)));
                }

                serviceHost.ToList().ForEach(u =>
                {
                    var netTcp = new NetTcpBinding();
                    netTcp.Security.Mode = SecurityMode.None;
                    u.AddServiceEndpoint(typeof(IWcfServiceA), netTcp, string.Format("net.tcp://127.0.0.1:910{0}/services/WcfServiceA{1}", ++index, index));
                    u.Open();
                    Console.WriteLine("{0} Service Start,Address is {1}", u.Description.Name, u.Description.Endpoints[0].Address.Uri);
                }
                );

  

  2、創建一個路由服務,自定義擴展實現MessageFilter進行請求分發,路由與服務之間以TCP協議傳輸。

            var serverEndpoints = new List<ServiceEndpoint>();
            var netTcp = new NetTcpBinding();
            netTcp.Security.Mode = SecurityMode.None;

            serverEndpoints.Add(new ServiceEndpoint(new ContractDescription("IWcfServiceA"), netTcp, new EndpointAddress("net.tcp://127.0.0.1:9101/services/WcfServiceA1")));
            serverEndpoints.Add(new ServiceEndpoint(new ContractDescription("IWcfServiceA"), netTcp, new EndpointAddress("net.tcp://127.0.0.1:9102/services/WcfServiceA2")));

            using (var router = new ServiceHost(typeof(RoutingService)))
            {
                int index = 10;
                string routerAddress = "net.tcp://127.0.0.1:8101/router/routerendpoint";
                router.AddServiceEndpoint(typeof(IRequestReplyRouter), netTcp, routerAddress);
                var config = new RoutingConfiguration();
                LoadBalancerFilter.EndpointsNumber = 2;

                serverEndpoints.ForEach(x => config.FilterTable.Add(new LoadBalancerFilter(), new[] { x }, index--));
                router.Description.Behaviors.Add(new RoutingBehavior(config));

                var debugBehavior = router.Description.Behaviors.Find<ServiceDebugBehavior>();
                debugBehavior.IncludeExceptionDetailInFaults = true;

                if (router.State != CommunicationState.Opening)
                    router.Open();


                while (Console.ReadKey().Key == ConsoleKey.Enter)
                {
                    break;
                }
                router.Close();
            }

  

  3、創建一個客戶端,客戶端與路由之間以TCP協議傳輸。

var endpoint = new EndpointAddress("net.tcp://127.0.0.1:8101/router/routerendpoint");
            var netTcp = new NetTcpBinding();
            netTcp.Security.Mode = SecurityMode.None;
            var client = ChannelFactory<IWcfServiceA>.CreateChannel(netTcp, endpoint);
            while (Console.ReadKey().Key == ConsoleKey.Enter)
            {
                Console.WriteLine("--" + client.GetNumber());
            }

 

  四、運行結果

  1、客戶端調用

 

  2、服務端顯示,每次將請求分發到不同的服務處理。

 


 

  五、總結

  以上是一個簡單的路由服務例子,可以根據實際情況擴展路由功能,實現上述描述是應用場景。考慮到路由的壓力,可以在路由前架上Nginx負載。

 

作者:andon
出處: http://www.cnblogs.com/Andon_liu
關於作者:專注於微軟平台項目架構、管理。熟悉設計模式、領域驅動、架構設計、敏捷開發和項目管理。現主要從事ASP.NET MVC、WCF/Web API、SOA、MSSQL、redis方面的項目開發、架構、管理工作。 如有問題或建議,請一起學習討論!
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接。
如有問題,可以郵件:568773262@qq.com 聯系我,謝謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM