我目前正在测试我的应用程序的扩展,但遇到了一些我没有预料到的问题。
该应用程序在一个 5 节点集群上运行,它有多个服务/actortypes 并使用共享进程模型。对于某些组件,它使用 actor 事件作为尽力而为的 pubsub 系统(有回退,因此如果删除通知,则没有问题)。当参与者的数量增加(又名订阅主题)时,问题就会出现。目前,actorservice 被划分为 100 个分区。此时的主题数量约为 160.000,其中每个主题订阅了 1-5 次(需要它的节点),平均订阅量为 2.5 个(大约 40 万个订阅)。
那时集群中的通信开始中断,不会创建新订阅,取消订阅超时。但它也影响其他服务,对诊断服务的内部调用超时(询问 5 个副本中的每一个),这可能是由于分区/副本端点的解析,因为对网页的外部调用很好(这些端点使用相同的技术/代码堆栈)。
事件查看器充满了警告和错误,例如:
EventName: ReplicatorFaulted Category: Health EventInstanceId {c4b35124-4997-4de2-9e58-2359665f2fe7} PartitionId {a8b49c25-8a5f-442e-8284-9ebccc7be746} ReplicaId 132580461505725813 FaultType: Transient, Reason: Cancelling update epoch on secondary while waiting for dispatch queues to drain will result in an invalid state, ErrorCode: -2147017731
10.3.0.9:20034-10.3.0.13:62297 send failed at state Connected: 0x80072745
Error While Receiving Connect Reply : CannotConnect , Message : 4ba737e2-4733-4af9-82ab-73f2afd2793b:382722511 from Service 15a5fb45-3ed0-4aba-a54f-212587823cde-132580461224314284-8c2b070b-dbb7-4b78-9698-96e4f7fdcbfc
Run Code Online (Sandbox Code Playgroud)
我试过扩展应用程序,但没有激活此订阅模型,我很容易达到两倍大的工作负载,没有任何问题。
所以有几个问题
在Azure中的Windows Server 2012 R2上运行Postgresql 9.5
在我的应用程序上运行一些加载测试时,由于无法连接到postgres服务器而出现错误.在postgres的日志中,我收到以下消息:
无法从客户端接收数据:无法建立连接,因为目标计算机主动拒绝它.
只有在loadtest进入下一个场景时才会发生这种情况,这会触及代码的不同部分.因此需要与数据库建立新连接.但是在10-20秒之后,其余的场景完美无瑕,没有遇到任何其他打嗝.所以问题似乎是tcp连接.(我的代码重试了几次,但让它重试20秒是不可行的)
我在配置文件中使用以下设置
postgresql.conf中
listen_addresses = '*'
max_connections = 500
shared_buffers = 1024MB
temp_buffers = 2MB
work_mem = 2MB
maintenance_work_mem = 128MB
Run Code Online (Sandbox Code Playgroud)
的pg_hba.conf
host all all 0.0.0.0/0 trust
host all all ::/0 trust
Run Code Online (Sandbox Code Playgroud)
我知道,我知道..接受来自所有人的连接并不是保存,但这仅用于测试目的,并确保这些设置不会阻止任何连接.所以这个答案是无效的
我一直在监视服务器上的连接数量,在负载下它稳定在75. Postgres使用大约350mb的RAM.因此,给定配置和vm规范(7gb ram),应该有足够的空间来创建更多连接.但是,当下一个场景开始旋转时,连接数不会增加,它会保持水平并开始提供这些关于无连接的日志消息.
这可能是什么问题?
windows postgresql database-connection azure windows-server-2012-r2
在研究Service Fabric上的资源平衡器和动态负载指标时,我们遇到了一些问题(运行devbox SDK GA 2.0.135).
在Service Fabric Explorer(门户网站和独立应用程序)中,我们可以看到平衡是经常运行的,大部分时间它几乎立即完成,这种情况每秒都会发生.在查看节点或分区上的负载度量信息时,它不会在报告负载时更新值.
我们根据交互(对服务的HTTP请求)发送动态负载报告,大量增加单个分区的报告负载数据.这个尖峰在5分钟内变得可见,此时平衡器实际上开始平衡.这似乎是加载数据刷新的间隔.在上次报告的时间得到更新所有的时间,但没有新的价值.
我们将指标添加到applicationmanifest和clustermanifest以确保它在平衡中使用.这意味着资源平衡器使用相同的数据5分钟.这是可配置的设置吗?是约束因为它是在devbox上运行的吗?我们在clustermanifest中尝试了很多变量,但似乎都没有影响这个刷新时间.
如果这不适应,有人可以解释为什么你会使用陈旧数据运行平衡器?为什么选择这5分钟的间隔?
在应用程序的负载测试期间(使用动态负载报告服务),整个应用程序停止工作,因为有状态分区的一个副本会发出警告.
Warning System.RAP IStatefulServiceReplica.ChangeRole(S)Duration Thu, 21 Jul 2016 3:36:03 GMT Infinity 131135817636324745 false false Start Time (UTC): 2016-07-21 13:35:43.632
Run Code Online (Sandbox Code Playgroud)
这是在副本的负载平衡之后发生的,这发生在分区的第4个副本上,尽管我们只针对3.所以即使SF只是杀了它,应用程序也应该没问题(因为主要和其他2个辅助设备都已启动).然而整个事情都堵塞了.(从记录我可以看到至少10k事件仍然需要处理,但整个过程停止)
在上面的图像中,您可以看到特定副本的详细信息.此副本与其他辅助副本之间的唯一区别在于以下值:
我也觉得奇怪的是副本状态说:准备就绪而不是重新配置.由于读/写状态表明它仍在重新配置,我正在运行最新的SDK(2.1.163,发布于18-07-2016).我认为错误修正在那里,但尽管它变得更难以重现它仍然发生.有谁知道可能导致这个或如何解决这个问题?
在Vaclav的响应后,我开始记录RunAsync中的所有内容,以确定实际导致问题的原因.因此,如果请求取消,代码的哪一部分不会退出.正如瓦茨拉夫指出,当要求取消时,该方法并没有停止.然而,似乎它被卡住的代码部分是本机Service Fabric.
using(ITransaction tx = StateManager.CreateTransaction())
{
await queue.TryDequeueAsync(tx, _queueTimeout, cancellationToken);
await tx.CommitAsync();
}
Run Code Online (Sandbox Code Playgroud)
队列是ReliableQueue,超时设置为默认值4秒,cancelationtoken来自RunAsync.在每行之间添加日志记录后,我们得到了以下日志记录模式
//pre transaction
using(ITransaction tx = StateManager.CreateTransaction())
{
//pre dequeue
await queue.TryDequeueAsync(tx, _queueTimeout, cancellationToken);
//dequeued
await tx.CommitAsync();
//committed
}
//post transaction
Run Code Online (Sandbox Code Playgroud)
在每一行我都记录了cancelationrequest的值,并且当取消请求被触发时,后台任务将记录.结果我们得到了这样的例子:
pre transaction: False
predequeue: False
dequeued: False
CancelationTokenFired: True
Run Code Online (Sandbox Code Playgroud)
精确的位置可能会有所不同,但CancelationTokenFired之前的最后一个日志始终是
借助Service Fabric,我们可以获得创建自定义指标和容量的工具.通过这种方式,我们可以创建资源平衡器用于在运行时执行的资源模型.我想监视和使用物理资源,如:内存,CPU和磁盘使用情况.只要我们继续使用默认负载,这样就可以正常工作.
但是对于服务/角色来说,Load不是静态的,所以我想使用内置的动态负载报告.这是我遇到问题的地方,ReportLoad在分区级别上工作.但是,分区在节点上都在同一进程中.我发现的所有监视物理资源的方法都是使用进程作为最小的度量单位,例如PerformanceCounter.如果使用此值,则可能存在报告相同负载的分区数和不代表分区的负载.
所以问题是:如何在分区级别上测量资源使用情况?