大并发量下的线程数据问题
今天在做性能测试时为了方便知道哪个过程用了多长时间,所以在代码里写了处理时间记录。以提交业务时的时间为开始点,每一个处理过程获取系统时间减开始时间,记录开始时间到处理完当前过程用了多少ms。
然后跑1W个业务过程,每秒上20个,当同时运行过程数达到2K多个时,时间记录出了问题,一个过程完成的每个段的总ms数应是增加的,结果出现了ms数小于前一个处理段ms数的问题。(1000用户并发时没有问题)
400用户并发时的正常过程如下:
加载xml:0 获取信息:0 保存XML:0 评分完成:46 保存XML:46 保存错误数据:187 保存信息到库:187
加载xml:15 获取信息:15 保存XML:15 评分完成:62 保存XML:62 保存错误数据:203 保存信息到库:203
1W用户到达2000并发时会出以如下错误:
加载xml:0 获取信息:0 保存XML:578 评分完成:718 保存XML:0 保存错误数据:828 保存信息到库:828
加载xml:0 获取信息:31 保存XML:703 评分完成:968 保存XML:140 保存错误数据:984 保存信息到库:984
加载xml:0 获取信息:0 保存XML:796 评分完成:921 保存XML:109 保存错误数据:15 保存信息到库:15
加载xml:15 获取信息:15 保存XML:687 评分完成:812 保存XML:15 保存错误数据:15 保存信息到库:15
加载xml:0 获取信息:0 保存XML:343 评分完成:375 保存XML:609 保存错误数据:484 保存信息到库:484
原来担心StringBuilder的线程安全问题,所以把timeInfo由StringBuilder改成了string。
代码基本过程如下:
- C# code
using System;class class1{ static StringBuilder infoAll = new StringBuilder(); private void Page_Load() { //如果要保存,将信息保存到文件中 if (Request.QueryString["save"] == "1") { System.IO.StreamWriter sw = new StreamWriter("c:\\logs\\test\\examcount.txt", true); sw.WriteLine(timeInfoAll.ToString()); sw.Close(); infoAll = new StringBuilder(); return; } //初始化 DateTime dtS = DateTime.Now; TimeSpan ts = new TimeSpan(); string timeInfo = ""; //过程1 ts = DateTime.Now - dtS; timeInfo += ";加载xml:" + ts.Milliseconds; //过程2 ts = DateTime.Now - dtS; timeInfo += "; 从库获取信息:" + ts.Milliseconds; //过程3 ts = DateTime.Now - dtS; timeInfo += "; 保存XML:" + ts.Milliseconds; if(1=1)//分支条件 Pro1(dtS, timeInfo, ts); else Pro1A(dtS, timeInfo, ts); } private void Pro1(DateTime dtS, string timeInfo, TimeSpan ts) { //过程 Pro2(dtS, timeInfo, ts); } private void Pro1A(DateTime dtS, string timeInfo, TimeSpan ts) { //过程 Pro2(dtS, timeInfo,ts); } private void Pro2(DateTime dtS, string timeInfo, TimeSpan ts) { ts = DateTime.Now - dtS; timeInfo += "; 数据处理完成:" + ts.Milliseconds; //过程4 ts = DateTime.Now - dtS; timeInfo += "; 保存XML:" + ts.Milliseconds; //过程5 ts = DateTime.Now - dtS; timeInfo += "; 保存错误数据:" + ts.Milliseconds; //过程6 ts = DateTime.Now - dtS; timeInfo += "; 保存信息到库:" + ts.Milliseconds + "\r\n"; infoAll.Append(timeInfo); }}
[解决办法]
个人认为你的日志记录,不是一个用户使用的结果,比如用户A执行了过程一并记录了时间,马上要执行过程2,但是还没有记录时间,这是用户B进入页面并执行过程,这时会写入日志吧,但这个值和用户A的值就不一样了
[解决办法]
孩,用TotalMilliseconds 。
Milliseconds只是指这个时间持续中的毫秒分量。
1000个没问题是因为都不超过1秒,所有怎么减都没错。
超过1秒,你知道的。