如何使用UCMA模拟大量客户端进行负载测试?

时间:2015-11-27 06:04:33

标签: ucma lync-client-sdk

我使用Lync客户端SDK 2013和UCMA 4.0创建了应用程序。现在我用大量用户测试我的应用程序。如何使用UCMA或Lync客户端SDK模拟大量客户端?

2 个答案:

答案 0 :(得分:1)

这取决于你想要什么"模拟"。

如果您只是想要呼叫流量,则sipp,但这只是简单的SIP呼叫,并不能真正反映实际的Microsoft Lync客户端。

据我所知,Microsoft并未在Lync中提供任何负载测试工具。你必须根据你想要的东西自己生成它们"模拟"。

使用UCMA可信应用程序,您应该能够启动并使用大量用户端点来模拟"常见的lync服务(如随机更改状态,拨打电话,发送即时消息等)。您必须自己创建这样的应用程序。

答案 1 :(得分:1)

我在UCMA中创建了一个工具来对我的所有应用程序进行压力测试。

制作简单,由两部分组成。 这个例子是一个用于呼叫的压力测试器。当然,您可以使用此示例轻松制作另一个。

  1. 我们创建platform,按照我们的Set-CsTrustedApplication。

    var platformSettings = new ProvisionedApplicationPlatformSettings("InnixiTester", "urn:application:innixitester"); 
    var collabPlatform = new CollaborationPlatform(platformSettings);
    
    collabPlatform.EndStartup(collabPlatform.BeginStartup(null, null));
    
  2. 好的,我知道我在这里做的是一个错误的链接,将Begin和End编成一行代码。但是,这只是一个代码示例。我邀请你阅读Tom Morgan的文章,他解释了为什么像我这样做是不好的。

    1. 我们在这里使用Parallel loop来创建我们所有的用户端点。这样,它就会更快。

      /*
       * Proprieties of the class 
       */
      
      private AutoResetEvent _waitForStressTestToFinish = new AutoResetEvent(false);
      private List<UserEndpoint> _listUserEndpoints = new List<UserEndpoint>();
      private int _maxUsers = 200;
      private int _tickTotal;
      private int _tickCount;
      private int _nbrCallsByIntervall;
      
      /*
       * End
       */
      
      _maxUsers = 200; // Nbr max of users
      const var callsTotal = 200; // Nbr of total call
      const var timeToTest = 30; // Total time to test
      const var intervalOfCalls = 5; // We want to make our calls between specific intervals
      
      
      Parallel.For(0, _maxUsers, i => 
              {
                  CreateUserEndpoint(collabPlatform, i.ToString());
              });
      
    2. 您只需在此处创建UserEndpoint。方案是我在活动目录中的用户是stressuser0到stressuser200。扩展名从+14250到+1425200

      private void CreateUserEndpoint(CollaborationPlatform cp, string iteration)
      {
          try
          {
              UserEndpointSettings settingsUser = new UserEndpointSettings($"sip:stressuser{iteration}@pferde.net", "pool2010.pferde.net", 5061);
      
              settingsUser = InitializePublishAlwaysOnlineSettings(settingsUser);
      
              var userEndpoint = new UserEndpoint(cp, settingsUser);
      
              userEndpoint.EndEstablish(userEndpoint.BeginEstablish(null, null));
      
              PublishOnline(userEndpoint);
      
              _listUserEndpoints.Add(userEndpoint);
      
              Console.WriteLine($"The User Endpoint owned by URI: {userEndpoint.OwnerUri} was created\n");
          }
          catch (Exception)
          {
              Console.WriteLine($"failed to create for --> sip:stressuser{iteration}@pferde.net");
              throw;
          }
      
      }
      
      private UserEndpointSettings InitializePublishAlwaysOnlineSettings(UserEndpointSettings settings)
      {
          settings.AutomaticPresencePublicationEnabled = true;
          settings.Presence.PreferredServiceCapabilities.AudioSupport = CapabilitySupport.Supported;
      
          return (settings);
      }
      
    3. 现在是时候拨打电话了!我们将使用计时器编写一个简单的算法。将计算X时间以及Y呼叫和Z间隔需要进行多少次呼叫。

         Console.WriteLine("Tape a key to place calls...");
         Console.ReadKey();
      
         PlaceCalls(callsTotal, timeToTest, intervalOfCalls);
      
         _waitForStressTestToFinish.WaitOne();
      
         }
        catch (Exception ex)
       {
       Console.WriteLine($"Shutting down platform due to error {ex}");
       ShutdownPlatform(collabPlatform);
       }
       ShutdownPlatform(collabPlatform);
      }
      
      private void PlaceCalls(int callsMax, int timeMax, int timeIntervall)
      {
          _tickTotal = timeMax / timeIntervall;
          _nbrCallsByIntervall= callsMax / _tickTotal;
      
          Console.WriteLine($"_nbrCallsByIntervall --> {_nbrCallsByIntervall}");
      
          var timeIntervalTimespan = new TimeSpan(0, 0, 0, timeIntervall);
          _timer = new Timer(timeIntervalTimespan.TotalMilliseconds);
          _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
          _timer.Enabled = true;
      }
      
      
      void _timer_Elapsed(object sender, ElapsedEventArgs e)
      {
          if (_tickCount < _tickTotal)
          {
              Console.WriteLine($"\n Pause Timer | On {_tickCount} to {_tickTotal}\n");
              _timer.Enabled = false;
              for (var i = 0; i <= _nbrCallsByIntervall - 1; ++i)
              {
                  ConversationSettings convSettings = new ConversationSettings();
                  Conversation conversation = new Conversation(_listUserEndpoints[generateNumber(0, _listUserEndpoints.Count)], convSettings);
      
                  var audioVideoCall = new AudioVideoCall(conversation);
                  CallEstablishOptions options = new CallEstablishOptions();
      
                  var gNbr = generateNumber(0, _listUserEndpoints.Count);
                  try
                  {
                   // Here I'm calling a single phone number. You can use GenerateNumber to call stressusers each others. But you have to extend your code to accept the calls coming.
                      audioVideoCall.BeginEstablish($"3322", options, null, audioVideoCall);
                  }
                  catch (Exception)
                  {
                      Console.WriteLine("Fail to Call the remote user...");
                      throw;
                  }
                 Console.WriteLine($"Call--> +1425{gNbr}.Counter--> {_tickCount} Ticket--> {_tickTotal} and thread id {Thread.CurrentThread.ManagedThreadId}");
              }
              _tickCount++;
              _timer.Enabled = true;
              Console.WriteLine("\n reStart Timer \n");
          }
          else
          {
              Console.WriteLine("\n!!! END Stress test !!!\n");
              _timer.Enabled = false;
              _waitForCallToEstablish.Set();
          }
      }
      
      private int generateNumber(int min, int max)
      {
          var r = new Random();
          Thread.Sleep(200);
          return (r.Next(min, max));
      }