【问题标题】:NLog WebService target creates too much connectionsNLog WebService 目标创建了太多的连接
【发布时间】:2021-06-02 10:29:52
【问题描述】:

我有一个使用 NLog 的 .NET Core 3.1 服务。 这是我的 NLog.config 代码:

<?xml version="1.0" ?>
<nlog autoReload="true"
      xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target name="AsyncInformation" xsi:type="AsyncWrapper">
      <target type="WebService"
                  name="ws"
                  url="https://log-api.com/log/v1"
                  protocol="JsonPost">
        <parameter name="">
          <layout xsi:type="newrelic-jsonlayout">
            <attribute name="time" layout="${date}" />
            <attribute name="level" layout="${level:upperCase=true}"/>
            <attribute name="message" layout="${message}" />
            <attribute name="host" layout="${machinename}" />
            <attribute name="ActivityId" layout="${activityId}" />
            <attribute name="processId" layout="${processId}" />
            <attribute name="threadid" layout="${threadid}" />
            <attribute name="event-properties" >
              <layout type="JsonLayout" includeAllProperties="true" maxRecursionLimit="0" escapeForwardSlash="true" />
            </attribute>
            <attribute name="exception" layout="${exception}" />
            <attribute name="traceId" layout="${var:traceId}" />
          </layout>
        </parameter>
        <header name="X-License-Key" layout="${environment:LICENSE_KEY}"/>
      </target>
    </target>
  </targets>
  <rules>
    <logger name="*" minlevel="Information" maxlevel="Error" writeTo="AsyncInformation"/>
  </rules>
</nlog>

我的服务托管在 Azure 中,我可以看到代码正在运行,我还可以看到日志到达我的 API。 服务性能受到影响,CPU 使用率非常高(大部分时间为 100%),我注意到我们的打开连接已从 700 增加到 2,000(这是允许的最大连接数) 我认为这是性能问题的根源。

我试图进入 NLog 源代码并注意到 WebService 目标(我使用的)正在使用 HttpWebRequest,我认为这是打开这些大量连接的原因,因为连接不是持久性的。我想知道是否有一个选项使用 WebService 目标,但通过保持连接活动来重用连接?

或者有一个选项可以在 WebService 目标中使用 HttpClient 而不是 HttpWebRequest?

任何帮助都会很棒。

【问题讨论】:

标签: .net nlog


【解决方案1】:

HttpWebRequest 还没有完全准备好使用 NetCore3.1

  • Microsoft 最初认为 HttpWebRequest 完全是废话,不应成为 NetCore 平台的一部分。
  • 微软随后承认,将HttpWebRequest 添加到 NetCore 将使从 NetFramework 的过渡更容易。微软还决定HttpWebRequest 应该只是HttpClient 的一个精简包装,其中每个HttpWebRequest 创建自己的HttpClient-instance,从而杀死Http-Connection-pooling(忽略KeepAlive = true
  • Microsoft 后来承认,如果实现HttpWebRequest,但不符合实际文档和预期行为,则会产生不良声誉。随着 Net50 的发布,Microsoft 解决了其最初半生不熟的HttpWebRequest 的许多问题。

另见:https://github.com/dotnet/corefx/pull/41462

我可以看到两个方向:

  • 更新到 Net50(来自 NetCore31)并添加 proxyType="DefaultWebProxy" 作为 WebService-target 的选项。
  • 试试NLog.Targets.Http,看看它是否能支持您的方案。

【讨论】:

  • 我的解决方案应该支持大多数基于 .NET Core 的各种服务。所以第一个选项与我无关,但对于你提到的第二个建议 - 使用 http 目标,我很乐意使用它,但到目前为止我找不到向我的请求添加标头的方法,原因我选择 WebService 目标是因为我能够将我的标头添加到请求中(参见上面的代码)。我是否遗漏了什么,实际上有一种方法可以将标头添加到 http 目标请求中?
  • @user2055886 我想您可以从为github.com/DarekDan/NLog.Targets.HTTP 创建一个问题开始,如果您真的很兴奋,那么还可以创建一个拉取请求来解决该问题。
猜你喜欢
  • 2014-07-25
  • 2015-06-13
  • 1970-01-01
  • 2011-07-31
  • 2016-02-19
  • 1970-01-01
  • 2013-03-31
  • 2021-12-13
  • 1970-01-01
相关资源
最近更新 更多