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)接口定义和实现为:

1
2
3
4
5
6
7
8
9
[ServiceContract]
     public  interface  IWcfServiceA
     {
         [OperationContract]
         int  GetNumber();
 
         [OperationContract]
         string  GetString();
     }

    (2)服务的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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协议传输。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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协议传输。

1
2
3
4
5
6
7
8
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负载。

 

引用:http://www.cnblogs.com/Andon_liu/p/5433538.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值