zoukankan      html  css  js  c++  java
  • WCF实例与并发的一些测试

    环境.net4.0 使用NetTcpBinding

    概要

    实例管理可以理解为服端怎么管理(创建与销毁)Service 类的实例
    并发可以理解为WCF框架在收到客户端请求后针对目标Service实例的派发行为,Single表现为如果Service已经在处理请求了,那么新的请求(注意是针对同一个Service实例的)将排队,如果是Mutiple那么请求将立即执行,其实质是请求的处理基于同一个Service实例的锁定同步行为。

    进一步说明,WCF针对请求的处理是基于池线程的,当使用NetTcp的同个proxy(对应物理上的一Tcp链接)发出多个请求时,如果服务器使用的是PerCall+Single组合,那么该条TCP链接的请求将串行华处理(无法说是分配一个固定线程处理,因观察到同个proxy,50个并发请在两个线程上运行--指更换过一次线程)。

    //==========测试代码服务端=============

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.Threading;
    namespace WCFServer
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                var timer = new Timer((o) => { GC.Collect(); }, null, 0, 100);
    
                using(ServiceHost host=new ServiceHost(typeof(CalculatorService)))
                {
                    host.AddServiceEndpoint(typeof(ICalculator), new NetTcpBinding(),
                    "net.tcp://192.168.1.31:8888/CalculatorService");
                    host.Opened += (s,e) => {
                        Console.WriteLine("服务启动!");
                    };
                    host.Open();
                    Console.Read();
    
                }
            }
        }
    
    
        [ServiceContract]
        public interface ICalculator
        {
            [OperationContract]
            int Add(int x, int y);
        }
    
    
        [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single,ConcurrencyMode=ConcurrencyMode.Single)]
        public class CalculatorService : ICalculator,IDisposable
        {
    
            public CalculatorService()
            {
                Console.WriteLine( AddThreadMsg( "Instantiated!"));
            }
    
            public int Add(int x, int y)
            {
                Console.WriteLine(AddThreadMsg( string.Format("index:{0}, Time:{1}, Operation method is invoked.",x,DateTime.Now)));
               Thread.Sleep(1000);
                return x + y;
            }
    
            ~CalculatorService()
            {
                Console.WriteLine(AddThreadMsg( "Finalized!"));
            }
    
            public void Dispose()
            {
                Console.WriteLine(AddThreadMsg( "Dispose!"));
            }
            private string AddThreadMsg(string msg)
            {
                return msg + ",ThreadId:" + Thread.CurrentThread.ManagedThreadId;
            }
        }
    }

    //==========测试代码客户端=============

    View Code
     static void Main(string[] args)
            {
                using (ChannelFactory<ICalculator> channelFac =
                    new ChannelFactory<ICalculator>(new NetTcpBinding(),
                    "net.tcp://192.168.1.31:8888/CalculatorService"))
                {
                    var proxy = channelFac.CreateChannel();
                    if (null != proxy as ICommunicationObject)
                    {
                        (proxy as ICommunicationObject).Open();
                    }
            
                    Random rnd=new Random();
                    for (int i = 1; i < 50; i++)
                    {
                        var index = i;
                       Thread t=new Thread(()=>{
                           try
                           {
                               Thread.Sleep(rnd.Next(100, 10000));
    
                 
                               Console.WriteLine(string.Format("{3}:{0}+{1}={2}", index, 2, proxy.Add(index, 2), index));
                               //(proxy as ICommunicationObject).Close();
                           }
                           catch (Exception ex)
                           {
                               Console.WriteLine(string.Format("Error-{0}:{1}", index, ex.Message));
                           }
                   
                            
                       });
                       t.Start();
    
                        
                    }
    
                    Console.Read();
                }
    
                Console.WriteLine("完成");
                Console.Read();
            }
    
        }

    //说明

    1.在使用NetTcpBinding时,一个客户端proxy跟一条连接对应(可以通过创建多个proxy模拟多个客户端),在调用open后,可以通过netstat命令看到建立的TCP 连接。

    2.当使用多线程模拟多个并发的链接时(proxy),服务器默认只能并行的接收11个连接,这个跟socket编程时监听端口允许并发的链接数设置一致。

    3.PerCall + Mutiple时,建立一个proxy在未打开的情况下在多个线程中调用,proxy会根据调用先后对这些调用请求进行串行华处理。

    4.PerCall + Mutiple时,建立多个proxy进行并发调用,服务器表现是并行处理请求。

    5.PerCall + Single时,建立多个proxy并发请求时,服务器呈现并行处理,而单个proxy并发请求时,服务器呈现串行处理,当把NetTcpBingding换成BasicHttpBinding时服务器又变为出并行处理,不过可以通过netstat看到,使用http协议后单个proxy的并发调用实际上是建立了多个tcp连接的,
    可见PerCall +Single时针对同个链接发来的请求是串行处理的

     6.针对同一个客户端代理的并发调用,其请求会在客户端被串行后发出。不支持回话的信道绑定不受会话节流阀限制

    参考:

    http://www.cnblogs.com/tyb1222/archive/2012/05/23/2515535.html

  • 相关阅读:
    Jmeter系列(29)- 详解 JDBC Connection Configuration
    Jmeter系列(28)- 发送 soap 协议的接口
    Jmeter系列(27)- 详解正则提取器
    Jmeter系列(26)- 详解 JSON 提取器
    Jmeter系列(25)- 详解用户参数
    (五)、python 函数
    (四)、python 集合与格式化
    (三)、python运算符和基本数据类型
    Mysql: pt-table-checksum 和 pt-table-sync 检查主从一致性,实验过程
    (二)、Python 基础
  • 原文地址:https://www.cnblogs.com/wdfrog/p/2517443.html
Copyright © 2011-2022 走看看