记一次高并发场景下.net监控程序数据上报的性能调优
最近在和小伙伴们做充电与通信程序的架构迁移。迁移前的架构是,通信程序负责接收来自充电集控设备的数据实时数据,通过Thrift调用后端的充电服务,充电服务收到响应后放到进程的Queue中,然后在管理线程的调度下,启动多线程进程数据处理。
随着业务规模的不断扩大和对系统可用性的逐步提高。现在这个架构存在很多的问题,比如:
1.充电服务重启,可能会丢数据。
2.充电服务重启会波及影响通信服务。
3.充电服务与通信服务面对的需求和变化是不一样,强依赖的架构带来很多的问题。
为了解决上述的这些问题,项目组决定借助Kafka对程序进行改造 。总体思路是,通信服务收到数据后,把数据存储到kafka,然后通过一个异步任务处理框架实时消费Kafka数据,并调用业务插件处理。
通过上面思路我们可以看到,系统整体架构仅是引入了一个MQ中间件,业务逻辑并没有发生本质的变化。但是在实际的压测中,却发现新架构下的程序性能比原来要慢很多。顺便说一下,压测场景是模拟10万充电终端离网上下线,短时间内会生成大约32万的消息量,遥信:10万,遥测:10万,电量10万,其他:2万。
通过ANTS分析相关进程,发现MonitorDataUploader.AddToLocalCache方法占用了78%左右的CPU。此方法不是业务方法,是为了监控程序的运行情况而加入的埋点监控。通过进一步分析看,在30多万消息量下,会产生约1000万甚至更高的监控消息。在如此高的并发下,这部分程序存在很严重的性能问题,导致系统的资源占用很高,系统运行变慢。
OK。既然问题已经清楚,那就开始优化吧。虽然可以把监控埋点屏蔽,临时解决程序的性能问题。但是,这对一个互联网应用来说是要不得的。没有监控,系统的运行健康状况就一无所知,这对一个SLA要求99.95%的系统来说,是不现实的。所以,必须全力优化监控程序在上报海量监控日志上的性能问题。
为了便于验证问题,写了一个模拟程序.通过模拟程序,很容易的再现了CPU占用很高的情况。
代码实现中,监控消息的存储是通过BlockingCollection存储的,并且设置了Collection大小为1000万。
var cache = new BlockingCollection<MonitorData>(boundedCapacity);
通过阅读BlockingCollection 的说明,可以看到空构造函数可以不设置Collection的上限。看到这个解释,怀疑是限制了上线的Collection存在性能问题。与是把代码中对BlockingCollection 的构造改成空构造,再次测试。测试结果大出意料,性能表现有了非常好的提升。
为了进一步验证问题,把对BlockingCollection 的构造改了限制大小,并设置上线为1个亿。测试时消息总量为5000万,验证一下是否是BlockingCollection 达到上限后,引起的严重性能问题。通过测试数据看,CPU消耗与不限制时基本一致。通过此可以确定,BlockingCollection 在设置了容量上限后,如果消息超过容量,性能将会非常差。
通过上面的调优,在发送5000万监控消息的情况下,程序的CPU在60% 左右持续30s左右。虽然性能有所改善,但是还不是很尽如人意。 有没有更好的解决方案呢?通过不算的思考和尝试,终于找到了一个更好的解决方案:基于双缓存+线程级多桶式Collection。此种模式下性能表现如下,CPU平均在30%左右,持续时间在15s左右。性能又有近一倍的提升。具体实现方案下次再分享。
记一次高并发场景下.net监控程序数据上报的性能调优的更多相关文章
- Qunar机票技术部就有一个全年很关键的一个指标:搜索缓存命中率,当时已经做到了>99.7%。再往后,每提高0.1%,优化难度成指数级增长了。哪怕是千分之一,也直接影响用户体验,影响每天上万张机票的销售额。 在高并发场景下,提供了保证线程安全的对象、方法。比如经典的ConcurrentHashMap,它比起HashMap,有更小粒度的锁,并发读写性能更好。线程安全的StringBuilder取代S
Qunar机票技术部就有一个全年很关键的一个指标:搜索缓存命中率,当时已经做到了>99.7%.再往后,每提高0.1%,优化难度成指数级增长了.哪怕是千分之一,也直接影响用户体验,影响每天上万张机 ...
- 【转】记录PHP、MySQL在高并发场景下产生的一次事故
看了一篇网友日志,感觉工作中值得借鉴,原文如下: 事故描述 在一次项目中,上线了一新功能之后,陆陆续续的有客服向我们反应,有用户的个别道具数量高达42亿,但是当时一直没有到证据表示这是,确实存在,并且 ...
- 高并发场景下System.currentTimeMillis()的性能问题的优化 以及SnowFlakeIdWorker高性能ID生成器
package xxx; import java.sql.Timestamp; import java.util.concurrent.*; import java.util.concurrent.a ...
- HttpClient在高并发场景下的优化实战
在项目中使用HttpClient可能是很普遍,尤其在当下微服务大火形势下,如果服务之间是http调用就少不了跟http客户端找交道.由于项目用户规模不同以及应用场景不同,很多时候可能不需要特别处理也. ...
- 高并发场景下System.currentTimeMillis()的性能问题的优化
高并发场景下System.currentTimeMillis()的性能问题的优化 package cn.ucaner.alpaca.common.util.key; import java.sql.T ...
- C++高并发场景下读多写少的解决方案
C++高并发场景下读多写少的解决方案 概述 一谈到高并发的解决方案,往往能想到模块水平拆分.数据库读写分离.分库分表,加缓存.加mq等,这些都是从系统架构上解决.单模块作为系统的组成单元,其性能好坏也 ...
- C++高并发场景下读多写少的优化方案
概述 一谈到高并发的优化方案,往往能想到模块水平拆分.数据库读写分离.分库分表,加缓存.加mq等,这些都是从系统架构上解决.单模块作为系统的组成单元,其性能好坏也能很大的影响整体性能,本文从单模块下读 ...
- MySQL在大数据、高并发场景下的SQL语句优化和"最佳实践"
本文主要针对中小型应用或网站,重点探讨日常程序开发中SQL语句的优化问题,所谓“大数据”.“高并发”仅针对中小型应用而言,专业的数据库运维大神请无视.以下实践为个人在实际开发工作中,针对相对“大数据” ...
- 高并发场景下System.currentTimeMillis()的性能优化
一.前言 System.currentTimeMillis()的调用比new一个普通对象要耗时的多(具体耗时高出多少我也不知道,不过听说在100倍左右),然而该方法又是一个常用方法, 有时不得不使用, ...
随机推荐
- git使用教程之git分支
1 分支简介 让我们来看一个简单的分支新建与分支合并的例子,实际工作中你可能会用到类似的工作流. 你将经历如下步骤: 开发某个网站. 为实现某个新的需求,创建一个分支. 在这个分支上开展工作. 正在此 ...
- SSH三大框架整合步骤
Struts2:需要整合的第一个框架: 1.创建一个动态web项目 2.导入struts2必须的jar 放到 lib目录下 ,再 build path 添加web工程中 3.配置struts2的核心配 ...
- win10提示管理员已阻止你运行此应用,如何强制运行
方法/步骤 这里以自己遇到的一个软件为例,下图就是禁止的图画: 在开始菜单中输入"cmd",然后以管理员身份运行: 按住"shift"键,同 ...
- HTML中动态生成内容的事件绑定问题【转载】
转自 http://www.hitoy.org/event-binding-problem-of-dynamically-generated-content.html 由于实际的需要,有时需要往网页中 ...
- 原生addClass 方法 添加类函数
function addClass(id,new_class){ var i,n=0; new_class=new_class.split(","); ...
- 通用的contain函数
用来检测节点所属关系:document.documentElement.contains(document.body) function contains(refNode, otherNode) {i ...
- Easy UI下拉列表默认选中(多行)与为文本框赋值
1.为单行文本框赋值 var data2 = $('#LoadArea').combobox("getData"); if (data2) { $('#id).combobox(' ...
- 有关ActiveXObject的兼容性问题(浏览器的特有属性)
这个问题还得从一开始时候学习有关javascript中有关对文件的一些操作. 对于每个前端的人应该都清楚有关File对象,其中包括多种方法,就不一一描述了,比如说她是通过FileSystemObjec ...
- get和post与服务端的交互方式
在网上看了不少关于get和post的文章,看到博主这个,现在手录下来. 原博客地址:http://www.cnblogs.com/warrior4236/p/5675756.html 一:B/S结构, ...
- insert时报Cannot add or update a child row: a foreign key constraint fails (`yanchangzichan`.`productstatusrecord`, CONSTRAINT `p_cu` FOREIGN KEY (`cid`) REFERENCES `customer` (`cid`))错误
mybatis在insert时报Cannot add or update a child row: a foreign key constraint fails (`yanchangzichan`.` ...