我使用Lync客户端SDK 2013和UCMA 4.0创建了应用程序。现在我用大量用户测试我的应用程序。如何使用UCMA或Lync客户端SDK模拟大量客户端?
答案 0 :(得分:1)
这取决于你想要什么"模拟"。
如果您只是想要呼叫流量,则sipp,但这只是简单的SIP呼叫,并不能真正反映实际的Microsoft Lync客户端。
据我所知,Microsoft并未在Lync中提供任何负载测试工具。你必须根据你想要的东西自己生成它们"模拟"。
使用UCMA可信应用程序,您应该能够启动并使用大量用户端点来模拟"常见的lync服务(如随机更改状态,拨打电话,发送即时消息等)。您必须自己创建这样的应用程序。
答案 1 :(得分:1)
我在UCMA中创建了一个工具来对我的所有应用程序进行压力测试。
制作简单,由两部分组成。 这个例子是一个用于呼叫的压力测试器。当然,您可以使用此示例轻松制作另一个。
我们创建platform,按照我们的Set-CsTrustedApplication。
var platformSettings = new ProvisionedApplicationPlatformSettings("InnixiTester", "urn:application:innixitester");
var collabPlatform = new CollaborationPlatform(platformSettings);
collabPlatform.EndStartup(collabPlatform.BeginStartup(null, null));
好的,我知道我在这里做的是一个错误的链接,将Begin和End编成一行代码。但是,这只是一个代码示例。我邀请你阅读Tom Morgan的文章,他解释了为什么像我这样做是不好的。
我们在这里使用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());
});
您只需在此处创建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);
}
现在是时候拨打电话了!我们将使用计时器编写一个简单的算法。将计算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));
}