3

我有一个同步应用程序,它每 10 秒向 Web 服务发送一次请求,并在本地数据库中进行一些数据转换,反之亦然。为了方便和解决一些争议,我想记录任何一对请求和响应 SOAP 消息。

但正如我的经验告诉我的那样,这将占用大量空间,用相同的请求和响应填充 SQLite 数据库。

如何以更少的磁盘空间实现相同级别的日志分解?事实上,记录整个消息有什么好处吗?也许我们可以只剪切参数值并记录它而不是完整的消息?

也许还有另一种机制可以压缩消息(或扩展/获取包含部分数据的完整消息?)并存储更少的数据,但能够在需要的地方获取源消息?

样品: 要求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:GetModifiedItems>
         <tem:Key>abcdef</tem:Key>
      </tem:GetModifiedItems>
   </soapenv:Body>
</soapenv:Envelope>

回复:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <GetModifiedItemsResponse xmlns="http://tempuri.org/">
         <GetModifiedItemsResult xmlns:a="http://schemas.datacontract.org/2004/07/Exchange" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <a:Body i:type="a:lst">
               <a:List>
                  <a:BaseItem i:type="a:asd">
                     <a:ISDELETED i:nil="true"/>
                     <a:ID>1</a:ID>                     
                     <a:SYSUSER>b2</a:SYSUSER>
                  </a:BaseItem>
                  <a:BaseItem i:type="a:asd">
                     <a:ISDELETED i:nil="true"/>
                     <a:ID>2</a:ID>
                     <a:SYSUSER>b3</a:SYSUSER>
                  </a:BaseItem>
               </a:List>
            </a:Body>
            <a:Msg>SUCCESS</a:Msg>
         </GetModifiedItemsResult>
      </GetModifiedItemsResponse>
   </s:Body>
</s:Envelope>
4

4 回答 4

2

压缩 XML 最简单的方法是一次存储多个文档,并对其应用您选择的任何通用压缩算法。关键是一次压缩多条消息,以便压缩器可以利用重复 XML 结构中存在的极端冗余。

这非常有效,以至于通常不需要专门的 XML 压缩。诸如“gzip/deflate”之类的通用算法或更强大的诸如 LZMA (7zip) 之类的算法非常非常擅长利用这一点。他们所做的只是组合重复的子字符串(就像它们在 XML 中一样)。

因此,您可以将所有 XML 消息缓冲 10 秒,然后将它们保存在某个二进制 blob 中。

于 2013-05-17T12:24:01.090 回答
2

从我的角度来看,解决方案取决于您是要存储整个消息还是只跟踪呼叫和其他一些数据。

如果您不必存储整个消息,我肯定会建议您安装Microsoft AppFabric。AppFabric 是一组集成技术,可以更轻松地执行很多事情,包括监控托管在 IIS 上的 WCF 服务,而且它是免费的!AppFabric 设置非常简单,会为您的 IIS 添加新功能/图标。

我们在生产环境中使用 AppFabric + SQL Server Express 来跟踪一些 WCF 调用。打开跟踪非常简单;您可以设置跟踪级别、目标数据库、要保留多少历史记录、大小限制等等……此外,还有一个非常酷的用户界面,可以让您查询存储的所有跟踪(它向您显示已跟踪了多少调用,多少失败,...)。好消息是,如果调用错误,您可能会有错误描述。也可以在 AppFabric 跟踪中添加用户定义的数据。更多信息在这里

现在,如果您需要存储整个消息,正如@Aron 所说,我会选择使用 NoSQL,尤其是使用logstash。正如他们网站上所写:

logstash 是一个用于管理事件和日志的工具。您可以使用它来收集日志、解析它们并存储它们以供以后使用(例如,用于搜索)。说到搜索,logstash 带有一个用于搜索和钻取所有日志的 Web 界面。

logstash 基于elasticsearch。

您必须找出的最后一件事是定义存储消息的正确时间/地点,可能使用自定义 WCF 行为。

希望有帮助!

于 2013-05-17T12:18:08.410 回答
1

好的。设置 WCF 来记录所有内容非常简单。此处显示了一个示例。您想使用 IMessageInspector 接口。

至于问题的第二部分。使用大量数据存储。我有两个答案给你。您将使用大量数据存储,因为

  1. 每条消息都很大(XML 不知道数据存储的效率)。
  2. 您正在存储大量消息。

因此,您希望减少每个部分的贡献。

第一个是你正确推测的。您可以通过压缩数据来减小有效负载大小。从简单的信息论中,我们知道数据的可压缩程度取决于数据的性质。在这种情况下,可以轻松压缩 XML。根据事先知道多少模式,您可以或多或少地对其进行压缩

其次,您可以减少有效载荷的数量。通过简单地定期截断存储请求的数量,您可以限制存储。

但是我最后要指出的是,我绝对不会使用 SQLite 作为存储机制。根据我的经验,P/Invoke 开销将严重限制服务器的性能。此外,SQLite 的并发模型很差,也限制了服务器上的并发请求数。

坦率地说,我不得不问您是否需要仅使用平面文件进行存储,或者如果您需要查询,我可能会建议切换到 XML NoSQL 解决方案。

使用 XML NoSQL 数据库的另一个好处是,即使应用程序服务器出现故障,您也可以将其从盒子中取出并查询它。

现在,至于您是应该从 XML 中提取数据还是将其存储为不兼容的格式……我认为这会适得其反。通过存储实际请求,您可以编写一个小应用程序将请求重新发送到回归测试。

于 2013-05-13T10:54:13.560 回答
1

日志执行 2 个主要目的:

  1. 出现问题时调试/跟踪应用程序问题
  2. 审计追踪

要实现这些,您需要尽可能多地记录。所以记录整个 SOAP 消息。为了节省磁盘空间,您可以存储在适当命名(包括日期和时间)的平面文件中,这些文件会间歇性压缩并定期存档。

祝你好运。希望这可以帮助

于 2013-05-18T05:10:01.890 回答