首页 > 编程语言 >asp.net web api 接口控制并发研究(临时性方法)

asp.net web api 接口控制并发研究(临时性方法)

时间:2024-05-30 16:35:27浏览次数:22  
标签:web Task await private api asp var new logger

有一个业务场景,接口的业务逻辑非常复杂,对数据库的压力比较大,希望限制下接口的并发数量,研究了下:

using Microsoft.AspNetCore.Mvc;
using System.Collections.Concurrent;
using System.Threading.Tasks;

namespace TestBingFa.Controllers
{
    [ApiController]
    [Route("[controller]/[action]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        private static ConcurrentDictionary<string, long> _methodCallCounts = new ConcurrentDictionary<string, long>();

        private static int num = 0;

        private static SemaphoreSlim globalSemaphore = new SemaphoreSlim(30);

        private static int num2 = 0;


        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IEnumerable<WeatherForecast> GetWeatherForecast()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }



        [HttpGet]
        public async Task<List<string>> GetWeatherForecast2()
        {
            var semaphore = new SemaphoreSlim(10);
            
            var tasks = new List<Task<string>>();


            for (int i = 0; i < 20; i++)
            {
                if (i >= 10)
                {
                    int b = i;
                }
                // 等待直到Semaphore允许进入
                await semaphore.WaitAsync();
                int localI = i;
                tasks.Add(Task.Run(async Task<string> () =>
                {
                    try
                    {
                       return await SimulateRemoteRequest(localI);
                    }
                    finally
                    {
                        // 完成任务后释放Semaphore
                        semaphore.Release();
                        subNum();
                    }
                }));
            }

            // 等待所有任务完成
            await Task.WhenAll(tasks);

            List<string> list = new List<string>();
            foreach (var item in tasks)
            {
                list.Add(item.Result);
            }

            string msg = GetStatistics();
            list.Add(msg);

             
            return list;    
        }

        private async Task<string> SimulateRemoteRequest(int i)
        {
            _logger.LogInformation("task " + i + " started"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            addNum();

            // Simulate a delay to represent an IO-intensive operation
            await Task.Delay(10000); // Simulate a 2 second delay

            // Optionally, make a real HTTP request to simulate a remote call
            // var response = await _httpClient.GetAsync("https://example.com");
            // var content = await response.Content.ReadAsStringAsync();

            // For simulation purposes, we return a fixed message

            

            return "task " + i + " completed";
        }



        private static readonly object _lock = new object();

        private  void addNum()
        {
            lock (_lock)
            {
                num = num + 1;
                _logger.LogInformation("num:" + num);
            }
        }
        private  void subNum()
        {
            lock (_lock)
            {
                num = num - 1;
                _logger.LogInformation("num:" + num);
            }

        }

        private static void IncrementMethodCallCount(string methodName)
        {
            _methodCallCounts.AddOrUpdate(methodName, 1, (key, count) => count + 1);
        }

        private static void IncrementMethodCallCount2(string methodName)
        {
            _methodCallCounts.AddOrUpdate(methodName, 1, (key, count) => count -1);
        }

        private static string GetStatistics()
        {
            var stats = new System.Text.StringBuilder();
            stats.AppendLine("Method Call Counts:");

            foreach (var entry in _methodCallCounts)
            {
                stats.AppendLine($"{entry.Key}: {entry.Value}");
            }

            return stats.ToString();
        }



        [HttpGet]
        public async Task<List<string>> GetWeatherForecast3()
        {
            

            var tasks = new List<Task<string>>();


            for (int i = 0; i < 20; i++)
            {
                if (i >= 10)
                {
                    int b = i;
                }
                // 等待直到Semaphore允许进入
                await globalSemaphore.WaitAsync();
                int localI = i;
                tasks.Add(Task.Run(async Task<string> () =>
                {
                    try
                    {
                        return await SimulateRemoteRequest2(localI);
                    }
                    finally
                    {
                        // 完成任务后释放Semaphore
                        globalSemaphore.Release();
                        subNum2();
                    }
                }));
            }

            // 等待所有任务完成
            await Task.WhenAll(tasks);

            List<string> list = new List<string>();
            foreach (var item in tasks)
            {
                list.Add(item.Result);
            }

            string msg = GetStatistics();
            list.Add(msg);


            return list;
        }

        private async Task<string> SimulateRemoteRequest2(int i)
        {
            _logger.LogInformation("task " + i + " started" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            addNum2();
            // Simulate a delay to represent an IO-intensive operation
            await Task.Delay(10000); // Simulate a 2 second delay

            // Optionally, make a real HTTP request to simulate a remote call
            // var response = await _httpClient.GetAsync("https://example.com");
            // var content = await response.Content.ReadAsStringAsync();

            // For simulation purposes, we return a fixed message



            return "task " + i + " completed";
        }


        private static readonly object _lock2 = new object();

        private void addNum2()
        {
            lock (_lock2)
            {
                num2 = num2 + 1;
                _logger.LogInformation("num2:" + num2);
            }
        }
        private void subNum2()
        {
            lock (_lock2)
            {
                num2 = num2 - 1;
                _logger.LogInformation("num2:" + num2);
            }

        }



    }
}

 

总的来说,要全局限制一个接口的并发量,规范的方法是使用过滤器;

临时性方法是直接在控制器中定义静态信号量,然后去控制具体的接口并发量。

 

标签:web,Task,await,private,api,asp,var,new,logger
From: https://www.cnblogs.com/Tpf386/p/18222615

相关文章

  • 回顾与前瞻:百度权重API接口的发展之路
     百度权重API接口是一个用于网站关键词排名的预估工具,可以帮助网站主预测他们的网站在百度搜索结果中的排名情况,并给出一个0到9的评估等级。本文将回顾一下百度权重API接口的发展历程,并展望一下未来可能的发展方向。百度权重API接口最早是由爱站、站长工具等网站推出的,旨在帮......
  • 关于PHP的webshell免杀小结
    0X00普通的一句话木马(适用于CTF和小站)<?phpeval($_POST['a']);?>//函数的相似替换<?phpassert($_POST['a']);?> <?php@eval($_POST['110']);?>与第一个一句话木马相比多了一个"@"字符,我们发现这个字符的含义是在php语法中表示抑制错误信息即使有错误也不返回;属于不......
  • Particles.js:为Web项目增添动态粒子效果
    Particles.js:为Web项目增添动态粒子效果示例介绍Particles.js是一个轻量级的JavaScript库,用于在Web页面上创建和管理动态粒子效果。它允许开发者通过简单的配置文件实现复杂的动画效果,为网页增添视觉吸引力。粒子可以是点、线、图像等,能够根据用户交互进行动态变化,Particles.......
  • 如何在 Firebase 云消息 HTTP V1 API 中创建群组?
    我目前正在从Firebase传统API迁移到适用于Firebase云消息(FCM)的HTTPV1API。虽然HTTPV1文档提供了向组发送消息的详细信息,但我却找不到任何有关如何使用HTTPV1API创建或管理组的信息。在传统API中,我们曾经使用/notification等端点创建通知组,并在这些组中管......
  • 如何隐藏 Firefox 窗口(Selenium WebDriver)?
    在Python中使用SeleniumWebDriver隐藏Firefox窗口通常涉及到配置FirefoxOptions来禁用其图形界面的显示。以下是一个详细的步骤和代码示例:1.首先,确保你已经安装了selenium库,以及geckodriver(适用于Firefox浏览器)。如果还没有安装,可以通过pip进行安装:```bashpipinstallsel......
  • java版微信公众号开发(八)获取jsapi_ticket,生产JS-SDK签名
    jsapi_ticket是公众号用于调用微信JS接口的临时票据。只用正确的签名才能使用JS调用微信接口,小编在这里整理一个一套完整的获取方法。废话不多说,直接上干货。//importjava.security.MessageDigest;/***获取位置信息签名*@AuthorFM_南风*@Date2024......
  • 微服务新体验之Aspire初体验
    安装aspire查看vs版本我这的版本是17.9.7,不支持aspire,所以需要升级更新VS点击帮助->检查更新点击更新静等安装升级创建aspire项目项目创建成功,如下图运行Aspire项目在AspireApp1.AppHost的launchSettings.json文件中加"ASPIRE_ALLOW_UNSECURED_TRANSPORT":"tr......
  • Tron_CTF2024新生赛 WEB
    web业余憨憨简单复现一下,不过有两题环境挂了s1mple_php题目easy我的解答:源码:<?phphighlight_file(__FILE__);include("flag.php");$c=$_POST['c'];$v=$_GET['v'];$e=$_GET['e'];if(isset($_GET['v'])andisset($_GET['......
  • Aspire初体验
    安装aspire查看vs版本我这的版本是17.9.7,不支持aspire,所以需要升级更新VS点击帮助->检查更新点击更新静等安装升级创建aspire项目项目创建成功,如下图运行Aspire项目在AspireApp1.AppHost的launchSettings.json文件中加"ASPIRE_ALLOW_UNSECURED_TRANSPORT":"tr......
  • 使用Java API 操作MongoDB
    除了通过启动mongo进程进入Shell环境访问数据库外,MongoDB还提供了其他基于编程语言的数据库访问方法。MongoDB官方提供了编程语言的驱动包,利用这些驱动包可以使用编程方法连接并操作MongoDB数据库。想要使用 Java程序操作 MongoDB,需要确保您的电脑上已经安装了Mong......