当前位置: 首页 > news >正文

品划网络做网站新闻头条最新消息今天发布

品划网络做网站,新闻头条最新消息今天发布,重庆承越网站建设地址,网站方案报价高并发下的接口请求重复提交问题 在.Net开发中,我们经常遇到用户疯狂点击同一按钮,或者服务响应慢时重复发送请求,导致数据重复添加或混乱。这不仅浪费资源,更会得到错误的业务结果。如何高效解决这一普遍问题呢? 常规…

     高并发下的接口请求重复提交问题 在.Net开发中,我们经常遇到用户疯狂点击同一按钮,或者服务响应慢时重复发送请求,导致数据重复添加或混乱。这不仅浪费资源,更会得到错误的业务结果。如何高效解决这一普遍问题呢?

        常规方案使用分布式锁 面对这问题,分布式锁是一种有效的传统解决方案,可以确保同一时间只有一个请求被处理。但面对众多需要锁定的接口,配置分布式锁无疑是一项繁重的工作。如何优化这一流程?

        今天,我带来了一种简洁高效的方案。透过.Net中间件的强大功能,我们可以用一行代码轻松实现防并发。首先,我们定义一个特性ApiLock,并在中间件中实现基于用户Token的Redis锁定。如此设计,简单实用又易于扩展。

        首先,我们需要创建一个ApiLock得特性,用于判断哪些接口需要执行分布式锁

public class ApiLockAttribute : ValidationAttribute{    public ApiLockAttribute(int maxLockTime = 10, string msg = "正在处理,请稍等,请勿重复提交")    {        MaxLockTime = maxLockTime;        Msg = msg;    }
    public int MaxLockTime { get; set; }    public string Msg { get; set; }}
然后我们需要写一个中间件,如果不了解中间件的小伙伴可以查看下面文章进行学习:
https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-8.0

图片

        我们需要创建一个中间件:

public class ApiLockMiddleware : MiddlewareBase{    public override async Task Invoke(HttpContext context)    {    }}

        然后我们需要再这个中间件里写一写逻辑,我需要通过HttpContext 获取到Token(用户或者客户端),来进行唯一标识的判定。

public class ApiLockMiddleware : MiddlewareBase{    public override async Task Invoke(HttpContext context)    {        //获取请求路由        string url= context.Request.Path.Value.ToLower();    }}

        然后我们需要编写一个获取Endpoint的方法:

private static Endpoint GetEndpoint(HttpContext context){    if (context == null)    {        throw new ArgumentNullException(nameof(context));    }    return context.Features.Get<IEndpointFeature>()?.Endpoint;}

        这个方法用于获取请求的EndPoint来判断是否包含ApiLock的特性

public class ApiLockMiddleware : MiddlewareBase{    public override async Task Invoke(HttpContext context)    {         //获取请求路由         string url= context.Request.Path.Value.ToLower();         var endpoint = GetEndpoint(context);         if (endpoint != null)         {             var apiLock = endpoint.Metadata.GetMetadata<ApiLockAttribute>();             if (apiLock == null)             {                 //没有特性直接走                 await base.Invoke(context);                 return;             }             else             {                   //这里才是我们要写 核心逻辑。我们需要获取token,//然后拼接token和url进行锁定                   using (var scope = _scopeFactory.CreateScope()){              var redisLock = scope.ServiceProvider.GetRequiredService<IRedisLock>();                var expiry = TimeSpan.FromSeconds(apiLock .MaxLockTime);//超时时间,如果内部执行超过expity则会释放锁                var wait = TimeSpan.FromSeconds(3);//获取锁的时候等待的时间                   var retry = TimeSpan.FromSeconds(1);//每隔多少时间请求一次                  string key = $"ApiLock:{用户/客户端Token}:{url}";//锁的key 用户唯一ID+API路由作为锁条件,同一个接口没执行完前不允许执行下一次        using (var redLock = await redisLock.CreateLockAsync(key, expiry, wait, retry))                       {                           if (!redLock.IsAcquired)                           {                               //如果被锁定,则返回特性传入的失败消息      await HandleExceptionAsync(context, new Exception(apiLock.Msg), (int)HttpStatusCode.OK);                               return;                           }                           else                           {                               //没有锁定才继续往后走Controller等业务逻辑                               await base.Invoke(context);                               return;                           }                       }                   }                               }         }    }}

   这里我们的中间件就写完了。我们需要写一个注册的方法:

  public static class ApiLockExtensions  {      /// <summary>      /// 防止重复提交中间件      /// </summary>      /// <param name="builder"></param>      /// <returns></returns>      public static IApplicationBuilder UseApiLock(this IApplicationBuilder builder)      {          if (builder == null)          {              throw new ArgumentNullException(nameof(builder));          }          return builder.UseMiddleware<ApiLockMiddleware>();      }  }

        然后,我们需要再Configure里进行注册:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider){    //……    app.UseApiLock();}

        到这里我们的封装就已经完成了,那么我们改如何使用它呢

[ApiController][Route("api/[controller]/[action]")]public class TestController : ControllerBase{    [HttpPost]    [ApiLock(10,"接口被锁定,请稍后再试")]    public async Task<IActionResult> TestApiLock()    {        await Task.Delay(20000);        return Ok();    }}

        这里也非常简单,我们直接再需要使用锁定的接口上添加ApiLock的特性就可以啦,我再这里对中间件提供了2个参数,分别是锁定的最大时间和锁定后的错误提示。这个大家也可以按照自身业务需求来进行扩展。

        然后我们测试一下这个接口,这个接口里面做了20秒的延迟

图片

        我们可以看到,当我们连续点击2次测试接口时,我们发现第二次调用就会返回被锁定了。

        简洁之美,效率之王 这不仅是一种技术优化,更是一种产品哲学的体现。在追求高效的同时,我们更希望能让开发者从重复的工作中解放出来,将更多的精力投入到创新和业务的核心中去。

        即刻行动起来,用最简洁的代码,解决.Net API的高并发头疼问题吧!

http://www.yidumall.com/news/45363.html

相关文章:

  • 在做好政府网站建设方面龙网网络推广软件
  • 怎样做士产品销售网站品牌广告视频
  • 域名网站排名网站流量统计查询
  • 佛山网站建设永网百度竞价推广开户内容
  • 怎么把自己的网站推广出去交换友情链接的渠道
  • 建设银行网站 一带一路城市更新论坛破圈
  • 绵阳模板网站seo专业培训seo专业培训
  • 普集网站制作常州seo收费
  • app开发公司怎么学东西周口网站seo
  • 一台云服务器可以做多少个网站怎么做好推广
  • 网站开发网站中国十大流量网站
  • 苏州网页设计制作seo软件视频教程
  • 嘉兴免费网站制作模板建站优点
  • 网站维护提示代码免费seo优化工具
  • 购买 做网站 客户万网域名官网
  • 做公众号app 网站 app新媒体运营培训班
  • 云虚拟主机建设网站一定要域名网页设计软件有哪些
  • 有哪些做海报好的网站信息流优化师是做什么的
  • 美女做那种视频网站有哪些珠海百度seo
  • 本地wordpress卸载怎么优化一个网站
  • 昆明电子商务网站建设靠谱的推广平台有哪些
  • 网站系统的建设与管理怎么投放网络广告
  • 网站克隆好后该怎么做企业培训计划方案
  • 滕州个人兼职做网站2345网址导航智能主板
  • 乡村建设规划网站郑州纯手工seo
  • 引流网站怎么做正规的网店培训机构有哪些
  • 做资讯类网站需要特殊资质吗app运营
  • 在线做电商banner的网站营销目标分为三个方面
  • 网站 展示大连做优化网站哪家好
  • 公司做网站排名常用seo站长工具