最近做的一个ASP.NET CORE WEBAPI 项目,稳定性测试,随着运行时间的增加,响应时间逐步上涨。入下图所示:同时,TPS数据也在逐渐下降。
不清楚原因,请论坛大佬救命啊。

解决方案 »

  1.   


    应该和数据库没有关系,因为一旦把LOAD RUNNER压力机停掉,然后再重启,响应时间就会恢复,把并发数减少到10用户,再加到50用户,响应时间也会恢复。
      

  2.   


    目前最长时间的测试,是26个小时,一直在逐渐上涨,之前没有在代码里做GC.colloct(),上涨的很明显,现在定时做GC.collect()上涨的趋势有所放缓。代码里有lock()操作,但是lock区域执行的速度应该是非常快的。关键是,一个api只是返回一个hallo world字符串,没有任何其他操作,响应时间也在上涨。
      

  3.   


    目前最长时间的测试,是26个小时,一直在逐渐上涨,之前没有在代码里做GC.colloct(),上涨的很明显,现在定时做GC.collect()上涨的趋势有所放缓。代码里有lock()操作,但是lock区域执行的速度应该是非常快的。关键是,一个api只是返回一个hallo world字符串,没有任何其他操作,响应时间也在上涨。你的代码没做什么事,但iis和.net的准备工作是一样也不会拉下的,每一个访问,都要创建很多对象来支持访问处理的,内部有lock,也是一个重要的开销,而且这个会影响垃圾回收的
      

  4.   


    应该和数据库没有关系,因为一旦把LOAD RUNNER压力机停掉,然后再重启,响应时间就会恢复,把并发数减少到10用户,再加到50用户,响应时间也会恢复。这个应该是需要GC的对象太多,影响到了性能
    你手动CollectGC其实没必要,因为一般网站不可能永远处于最大压力下工作
    你可以用一个合理的并发数量来进行测试
    只是返回HelloWorld的话 ,这样应该不会有明显的响应时间变化
      

  5.   


    应该和数据库没有关系,因为一旦把LOAD RUNNER压力机停掉,然后再重启,响应时间就会恢复,把并发数减少到10用户,再加到50用户,响应时间也会恢复。这个应该是需要GC的对象太多,影响到了性能
    你手动CollectGC其实没必要,因为一般网站不可能永远处于最大压力下工作
    你可以用一个合理的并发数量来进行测试
    只是返回HelloWorld的话 ,这样应该不会有明显的响应时间变化目前稳定性测试的TPS是在200左右,系统最大的tps可以达到1000多以上
      

  6.   

    .net core版本为2.2,  服务器操作系统为Linux Redhat 7.5 , 独立部署方式,前端没有用Nginx做反向代理。代码里有引用C的动态连接库。
      

  7.   


    但是只访问一个返回字符串的API,也会有这样的现象,代码如下:
        [Route("api/[controller]")]
        [ApiController]
        public class CheckupController : ControllerBase
        {
            const string HEALTH_CHECK = "System is OK.";        // GET: /<controller>/
            public async Task<string> Index()
            {
                return HEALTH_CHECK;
            }        [HttpPost]
            public async Task<string> Post()
            {
                
                return HEALTH_CHECK;
            }
        }
      

  8.   


    但是只访问一个返回字符串的API,也会有这样的现象,代码如下:
        [Route("api/[controller]")]
        [ApiController]
        public class CheckupController : ControllerBase
        {
            const string HEALTH_CHECK = "System is OK.";        // GET: /<controller>/
            public async Task<string> Index()
            {
                return HEALTH_CHECK;
            }        [HttpPost]
            public async Task<string> Post()
            {
                
                return HEALTH_CHECK;
            }
        }
    有没有全局的配置,或者整个controller中有没有其他的逻辑层实例对象呢。
      

  9.   


    但是只访问一个返回字符串的API,也会有这样的现象,代码如下:
        [Route("api/[controller]")]
        [ApiController]
        public class CheckupController : ControllerBase
        {
            const string HEALTH_CHECK = "System is OK.";        // GET: /<controller>/
            public async Task<string> Index()
            {
                return HEALTH_CHECK;
            }        [HttpPost]
            public async Task<string> Post()
            {
                
                return HEALTH_CHECK;
            }
        }
    有没有全局的配置,或者整个controller中有没有其他的逻辑层实例对象呢。上面发的代码就是这个Controller的所有代码,全局的变量是在外面的Utils静态类里面
      

  10.   

    你们是vs2017吗?
    如果是的话可以使用Diagnostic Tool
    具体用法如下
    https://www.cnblogs.com/lonelyxmas/p/9091867.html
      

  11.   

    有一点没看懂,webapi接口,为什么要用异步?为什么要加[ApiController]特性?web接口本来就是异步的,再加一层异步,起什么作用?继承的ControllerBase难道不是已经继承了ApiController了吗?
    为什么要加这个特性??我个人严重怀疑,就是因为你这些奇怪的写法,导致系统性能严重受损!
      

  12.   


    我也不知道为什么.,.我也不敢问... 但是我也看到很多人 都在web里写什么异步 线程之类的代码..我感觉好像也没啥用 但是都说这样性能高....因为http都都一请求一相应..所以我觉得异步在这个地方 好像也没什么太大功能.假设某个地方耗时,对前台来说 都是等待.所以单独扔出来一个task 意义到底大吗?
      

  13.   

    必须用 Task 的时候就会用 Task,不必用 Task 的时候那么就可能是你“不得不用”——例如接口龟腚就必须如此。假设不是“不得不”,而你因为它时髦而用 Task,这就没有必要了。
      

  14.   

    性能的问题,更多地考虑“有没有必要用路由”,有没有必要用 asp.net webapi 这种解析形式,甚至是“有没有必要用性能低下的 http 协议”这类大问题。小问题其实不重要。Task 是一个潮流,很可能很快、绝大多数高性能的接口都让你“不得不”使用 Task 来定义返回类型,甚至牺牲性能也在所不惜。这可能是一个潮流。
      

  15.   


    这跟nodejs原理是一样的。是有道理的,即任务转交后,线程就释放了,等api返回数据后,再使用线程处理。好处是防止io阻塞。
      

  16.   

    既然这么简单的代码,都会不断上涨,感觉是Linux部署的问题
    你可以将相同的项目部署到成熟的nginx下,如果稳定,那就说明是部署的问题