- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在使用 WCF 调用 Cisco 的 AXL SOAP API 时,我的 CPU 使用率很高。我首先使用从 wsdl 生成的类创建服务模型客户端库。我正在使用 basichttpbinding 和 transfermode 作为缓冲。执行调用时,CPU 达到极限,CPU 配置文件显示 96% 的 CPU 时间在 _TransparentProxyStub_CrossContext@0
来自 clr.dll,在 base.Channel 等调用之后调用.getPhone(请求);
。更准确地说,该调用使运行该进程的 CPU 内核达到最大。
这是从 wsdl 生成的客户端创建的片段
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class AXLPortClient : System.ServiceModel.ClientBase<AxlNetClient.AXLPort>, AxlNetClient.AXLPort
{
public AXLPortClient()
{
}
public AXLPortClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}
...
这是我创建客户端的方式:
public class AxlClientFactory : IAxlClientFactory
{
private const string AxlEndpointUrlFormat = "https://{0}:8443/axl/";
public AXLPortClient CreateClient(IUcClientSettings settings)
{
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
ServicePointManager.Expect100Continue = false;
var basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
basicHttpBinding.MaxReceivedMessageSize = 20000000;
basicHttpBinding.MaxBufferSize = 20000000;
basicHttpBinding.MaxBufferPoolSize = 20000000;
basicHttpBinding.ReaderQuotas.MaxDepth = 32;
basicHttpBinding.ReaderQuotas.MaxArrayLength = 20000000;
basicHttpBinding.ReaderQuotas.MaxStringContentLength = 20000000;
basicHttpBinding.TransferMode = TransferMode.Buffered;
//basicHttpBinding.UseDefaultWebProxy = false;
var axlEndpointUrl = string.Format(AxlEndpointUrlFormat, settings.Server);
var endpointAddress = new EndpointAddress(axlEndpointUrl);
var axlClient = new AXLPortClient(basicHttpBinding, endpointAddress);
axlClient.ClientCredentials.UserName.UserName = settings.User;
axlClient.ClientCredentials.UserName.Password = settings.Password;
return axlClient;
}
}
为 AXL API 生成的 wsdl 代码非常大。初始调用和后续调用都存在 CPU 问题,尽管后续调用速度更快。我还能做些什么来调试这个问题吗?有没有办法降低这种高 CPU 使用率?
更新
有关赏金的更多信息:
我已经像这样创建了 C# 类:
svcutil AXLAPI.wsdl AXLEnums.xsd AXLSoap.xsd /t:code /l:C# /o:Client.cs /n:*,AxlNetClient
您必须从调用管理器系统下载 Cisco 的 AXL api 的 wsdl。我使用的是 10.5 版本的 API。我相信主要的减速与 XML 处理有关。 api 的 WSDL 非常庞大,生成的类有 538406 行代码!
更新 2
我已经打开所有级别的 WCF 跟踪。最大的时间差异出现在“已写入消息”和“通过 channel 发送消息”之间的流程操作事件中,这两个操作之间几乎过了整整一分钟。其他事件(构建 channel 、打开客户群和关闭客户群)都执行得相对较快。
更新 3
我对生成的客户端类做了两处更改。首先,我从所有操作契约(Contract)中删除了 ServiceKnownTypeAttribute
。其次,我从一些可序列化的类中删除了 XmlIncludeAtribute。这两项更改将生成的客户端的文件大小减少了 50% 以上,并且对测试时间的影响很小(在 70 秒的测试结果上减少了大约 10 秒)。
我还注意到我有大约 900 个针对单个服务接口(interface)和端点的操作契约(Contract)。这是由于 AXL API 的 wsdl 将所有操作分组在一个命名空间下。我正在考虑将其分解,但这意味着创建多个客户端库,每个客户端库将实现一个简化的接口(interface),并最终破坏实现此 wcf 库的所有内容。
更新 4
看来操作次数是核心问题。我能够通过动词(例如获取、添加等)将操作和接口(interface)定义分离到他们自己的客户端和接口(interface)中(使用 sublime text 和正则表达式的非常缓慢的过程,因为 resharper 和 codemaid 无法处理仍然 250K+ 的大文件线)。对定义了大约 150 个操作的“Get”客户端进行的测试导致 getPhone 的执行时间为 10 秒,而之前的结果为 60 秒。这仍然比它应该的要慢很多,因为在 fiddler 中简单地制作这个操作会导致 2 秒的执行。解决方案可能会通过尝试进一步分离操作来进一步减少操作数。然而,这增加了一个新问题,即破坏所有使用该库作为单个客户端的系统。
最佳答案
我终于解决了这个问题。根本原因似乎确实是操作次数。将生成的客户端从 900 多个操作拆分为 12 个操作(遵循 this question 的指导)后,我能够将生成请求所花费的处理器时间减少到几乎为零。
这是优化从 Cisco 的 AXL wsdl 生成的服务客户端的最终过程:
像这样使用 wsdl 生成客户端代码:
svcutil AXLAPI.wsdl AXLEnums.xsd AXLSoap.xsd /t:code /l:C# /o:Client.cs /n:*,AxlNetClient
处理生成的客户端文件以分解为子客户端:
我创建了 this script处理生成的代码。该脚本执行以下操作:
ServiceKnownType
、FaultContract
和 XmlInclude
属性。 这些对于 xml 处理很有用,但据我所知,生成的类似乎不正确。例如,服务已知类型对于所有操作都是相同的,即使许多已知类型对于每个操作都是唯一的。这将生成的文件的总大小从 500K+ 行减少到 250K+,客户端实例化时间的性能略有增加。
将接口(interface)和方法的操作契约与实现该接口(interface)的客户端分开。
创建子客户端,每个子客户端有 12 个操作及其各自的实现。
这些子客户端具有三个主要部分。第一部分是原始 clientbase 客户端的部分类。我希望这个解决方案向后兼容,所以我在这里有引用子客户端的方法,这样通过调用新的子客户端,对旧 super 客户端的调用仍然有效。如果引用了任何已实现的操作,静态获取访问器将启动子客户端。还为调用关闭或中止时添加了事件,以便子客户端仍然可以运行这些操作。
子客户端的第二部分和第三部分是实现12个操作的接口(interface)和子客户端类。
然后我从原始生成的客户端中删除了接口(interface)和客户端方法。我替换了原始客户端的客户端构造函数,以简单地存储绑定(bind)和端点数据供子客户端在需要时使用。关闭和中止调用被重新创建为每个子客户端在实例化时都会订阅的事件调用程序。
最后,我将身份验证移至类似于 described here 的自定义端点行为.使用 IClientMessageInspector
立即发送身份验证 header 可以节省对服务器的一次往返调用,WCF 喜欢在服务器进行身份验证之前先发送匿名请求。这使我大约增加了 2 秒,具体取决于服务器。
总体而言,我的性能从 70 秒提高到 2.5 秒。
关于c# - WCF 在调用期间等待 _TransparantProxyStub_CrossContext 函数时使 CPU 最大化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35761583/
为了让我的代码几乎完全用 Jquery 编写,我想用 Jquery 重写 AJAX 调用。 这是从网页到 Tomcat servlet 的调用。 我目前情况的类似代码: var http = new
我想使用 JNI 从 Java 调用 C 函数。在 C 函数中,我想创建一个 JVM 并调用一些 Java 对象。当我尝试创建 JVM 时,JNI_CreateJavaVM 返回 -1。 所以,我想知
环顾四周,我发现从 HTML 调用 Javascript 函数的最佳方法是将函数本身放在 HTML 中,而不是外部 Javascript 文件。所以我一直在网上四处寻找,找到了一些简短的教程,我可以根
我有这个组件: import {Component} from 'angular2/core'; import {UserServices} from '../services/UserService
我正在尝试用 C 实现一个简单的 OpenSSL 客户端/服务器模型,并且对 BIO_* 调用的使用感到好奇,与原始 SSL_* 调用相比,它允许一些不错的功能。 我对此比较陌生,所以我可能会完全错误
我正在处理有关异步调用的难题: 一个 JQuery 函数在用户点击时执行,然后调用一个 php 文件来检查用户输入是否与数据库中已有的信息重叠。如果是这样,则应提示用户确认是否要继续或取消,如果他单击
我有以下类(class)。 public Task { public static Task getInstance(String taskName) { return new
嘿,我正在构建一个小游戏,我正在通过制作一个数字 vector 来创建关卡,该数字 vector 通过枚举与 1-4 种颜色相关联。问题是循环(在 Simon::loadChallenge 中)我将颜
我有一个java spring boot api(数据接收器),客户端调用它来保存一些数据。一旦我完成了数据的持久化,我想进行另一个 api 调用(应该处理持久化的数据 - 数据聚合器),它应该自行异
首先,这涉及桌面应用程序而不是 ASP .Net 应用程序。 我已经为我的项目添加了一个 Web 引用,并构建了各种数据对象,例如 PayerInfo、Address 和 CreditCard。但问题
我如何告诉 FAKE 编译 .fs文件使用 fsc ? 解释如何传递参数的奖励积分,如 -a和 -target:dll . 编辑:我应该澄清一下,我正在尝试在没有 MSBuild/xbuild/.sl
我使用下划线模板配置了一个简单的主干模型和 View 。两个单独的 API 使用完全相同的配置。 API 1 按预期工作。 要重现该问题,请注释掉 API 1 的 URL,并取消注释 API 2 的
我不确定什么是更好的做法或更现实的做法。我希望从头开始创建目录系统,但不确定最佳方法是什么。 我想我在需要显示信息时使用对象,例如 info.php?id=100。有这样的代码用于显示 Game.cl
from datetime import timedelta class A: def __abs__(self): return -self class B1(A):
我在操作此生命游戏示例代码中的数组时遇到问题。 情况: “生命游戏”是约翰·康威发明的一种细胞自动化技术。它由一个细胞网格组成,这些细胞可以根据数学规则生存/死亡/繁殖。该网格中的活细胞和死细胞通过
如果我像这样调用 read() 来读取文件: unsigned char buf[512]; memset(buf, 0, sizeof(unsigned char) * 512); int fd;
我用 C 编写了一个简单的服务器,并希望调用它的功能与调用其他 C 守护程序的功能相同(例如使用 ./ftpd start 调用它并使用 ./ftpd stop 关闭该实例)。显然我遇到的问题是我不知
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
在 dos 中,当我粘贴此命令时它会起作用: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" https://google.
我希望能够从 cmd 在我的 Windows 10 计算机上调用 python3。 我已重新安装 Python3.7 以确保选择“添加到路径”选项,但仍无法调用 python3 并使 CMD 启动 P
我是一名优秀的程序员,十分优秀!