使用MS Bond

时间:2019-01-16 18:09:55

标签: c# json azure-functions azure-application-insights

我们正在使用客户端SDK中的标准接收器可扩展性,将Application Insights生成的数据的副本发送到事件中心。我们遵循与默认接收器相同的批处理和压缩逻辑-而不是简单地将数据发送到事件中心端点。

因此在接收数据的功能应用程序中,单个EventHub消息将包含带有多个遥测点的JSON流,并使用gzip对其进行压缩。

我们需要对流进行反序列化,并根据遥测类型采取许多措施。我们将每秒接收约50k,因此性能非常重要。

我注意到SDK正在使用Bond,并定义了公共模式-https://github.com/Microsoft/ApplicationInsights-aspnetcore/tree/develop/Schema/PublicSchema

我目前正在做类似的事情,

foreach (var eventHubMessage in messages)
{
    // decompress the entire gzipped payload
    var decompressedData = DeserializeCompressedStream(eventHubMessage.Body.Array);

    // deframe the JSON stream into individual items, (e.g. data.Split(new[] { Environment.NewLine })
    var payloadItems = decompressedData.Deframe();

    foreach (var item in payloadItems){

        // A  standard JSON.NET conversion to get the item
        Envelope telemetryItem = ItemConverter.CreateTelemetryFromPayloadItem(item);

        // etc etc
    }
}

这可行,但是使用JSON.Net在项目级别进行转换在此规模上是一项昂贵的操作,并且会占用大量CPU。

假设进行反序列化的应用程序可以访问类型,例如https://github.com/Microsoft/ApplicationInsights-aspnetcore/tree/develop/test/ApplicationInsightsTypes,那么使用Bond定义反序列化JSON流的推荐和最有效方法是什么?

1 个答案:

答案 0 :(得分:0)

很遗憾,由于延迟反序列化的问题https://github.com/Microsoft/bond/issues/96,您无法对整个信封进行反序列化。

因此,您需要以其他方式解析baseData,然后将其传递给Bond De-serializer。或者,也许像我们在unit tests中所做的那样,使用一些JSON解析器将其解析为JSON。

JsonReader reader = new JsonTextReader(new StringReader(Encoding.UTF8.GetString(b, 0, b.Length)));
reader.DateParseHandling = DateParseHandling.None;
JObject obj = JObject.Load(reader);
return obj.ToObject<AI.TelemetryItem<TelemetryDataType>>();

由于我不确定您的任务是什么,因此我无法评论最有效的方法。在某些情况下,最有效的方法是根本不对整个有效负载进行反序列化。