天天看点

WCF Routing服务,负载均衡

WCF4.0支持路由机制,通过RoutingService实现请求分发、拦截处理。

  一、应用场景

  1、暴露一个endpoint在外网,其余服务部署于内网;

  2、请求分发,能对服务做负载功能;

  二、WCF4.0 路由服务

  

WCF Routing服务,负载均衡

  图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)服务的实现:

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:

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协议传输。

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协议传输。

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、客户端调用

WCF Routing服务,负载均衡

  2、服务端显示,每次将请求分发到不同的服务处理。

WCF Routing服务,负载均衡

  五、总结

  以上是一个简单的路由服务例子,可以根据实际情况扩展路由功能,实现上述描述是应用场景。考虑到路由的压力,可以在路由前架上Nginx负载。

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

继续阅读