我已经就性能问题工作了几天。 在深入研究之前,我想快速解释具体服务的工作原理。
我有一个主服务获取请求并向其他微服务发送请求,但用户的单个入口点是主服务,我认为这个图像更容易理解:
在主要服务从API获取请求之后,他做了一些逻辑,查询Db然后得到一个列表,列表上的每个项目都有Id,以获得主服务创建请求的每个项目的丰富程度。服务。
例如John请求主服务,主服务从Db获取90个项目的列表,然后主服务将创建90个微服务调用并返回包含90个项目的John单个响应。
现在问题只是关于创建异步调用微服务的正确方法。
这是我开发这个部分的方式:
GetDetailsAsync(Id, result.Items, request.SystemComponentId);
private static void GetDetailsAsync(string Id, List<MainItem> items, int systemId)
{
var getDetailsTasks = new List<Task>();
foreach (MainItem single in items)
{
getDetailsTasks.Add(SetSingleDetailsAsync(Id, single, systemId));
}
Task.WhenAll(getDetailsTasks);
}
private static async Task SetSingleDetailsAsync(string Id, MainItem single, int systemId)
{
single.ActivityExtendedDetails = await ProcessItemDetailsRequest.GetItemDetailsAsync(Id, single.TypeId,
single.ItemId, systemId);
}
public static Task<JObject> GetItemDetailsAsync(string id, short type,
string itemId, int systemId)
{
var typeList = ActivityTypeDetails.GetActivityTypes();
var url = GetActivityUrl(id, type, itemId, typeList);
if (url == null)
{
throw new Failure($"No url defined for type {type}");
}
try
{
JObject res;
using (var stream = client.GetStreamAsync(url).Result)
using (var sr = new StreamReader(stream))
using (var reader = new JsonTextReader(sr))
{
var serializer = new JsonSerializer();
res = serializer.Deserialize<JObject>(reader);
}
return Task.FromResult(res);
}
catch(Exception ex)
{
Logger.Warn(
$"The uri {url} threw exception {ex.Message}.");
//[Todo]throw exception
return null;
}
}
此代码运行且结果不够好,CPU上升非常快并且变得非常高,我认为我在GetItemDetailsAsync func上有问题,因为我使用client.GetStreamAsync(url).Result 当使用.Result它阻止,直到任务完成。
所以我对GetItemDetailsAsync进行了一些小改动,试图真正实现异步:
public static async Task<JObject> GetItemDetailsAsync(string id, short type,
string itemId, int systemId)
{
var typeList = ActivityTypeDetails.GetActivityTypes();
var url = GetActivityUrl(id, type, itemId, typeList);
if (url == null)
{
throw new Failure($"No url defined for type {type}");
}
try
{
JObject res;
using (var stream = await client.GetStreamAsync(url))
using (var sr = new StreamReader(stream))
using (var reader = new JsonTextReader(sr))
{
var serializer = new JsonSerializer();
res = serializer.Deserialize<JObject>(reader);
}
return res;
}
catch(Exception ex)
{
Logger.Warn(
$"The uri {url} threw exception {ex.Message}.");
//[Todo]throw exception
return null;
}
}
但现在我得到null我应该从Async函数获取数据。 我尝试调试,我注意到一些奇怪的事情,一切都像我期望的那样发生:调用方法,执行微服务请求并获得响应但是来自端点的响应(在主服务上找到)在异步方法从微服务返回之前返回,这导致我得到null而不是我期望的数据。
我认为也许我没有正确使用async \ await,如果有人能解释这种行为是如何发生的话会很高兴