首页 > 其他分享 >高可用之限流-03-Semaphore 信号量做限流

高可用之限流-03-Semaphore 信号量做限流

时间:2024-10-11 19:59:27浏览次数:1  
标签:03 LOG Thread Semaphore 限流 semaphore public

限流系列

开源组件 rate-limit: 限流

高可用之限流-01-入门介绍

高可用之限流-02-如何设计限流框架

高可用之限流-03-Semaphore 信号量做限流

高可用之限流-04-fixed window 固定窗口

高可用之限流-05-slide window 滑动窗口

高可用之限流-06-slide window 滑动窗口 sentinel 源码

高可用之限流-07-token bucket 令牌桶算法

高可用之限流 08-leaky bucket漏桶算法

高可用之限流 09-guava RateLimiter 入门使用简介 & 源码分析

主流的限流方式

目前主要有以下几种限流方式:

  • 信号量

  • 计数器

  • 滑动窗口

  • 漏桶算法

  • 令牌桶算法

  • 分布式限流

信号量

信号量实际上就是限制系统的并发量,来达到限流的目的。

常见的用法是:创建Semaphore,指定permit的数量。

在方法开始时,调用 Semaphore.acquire() 或者 Semaphore.tryAcquire() 来获取permit,并在方法返回前,调用Semaphore.release()来返还permit。

核心代码实现

public class LimitSemaphore extends LimitAdaptor {

    /**
     * 日志
     *
     * @since 0.0.5
     */
    private static final Log LOG = LogFactory.getLog(LimitSemaphore.class);

    /**
     * 信号量
     *
     * @since 0.0.5
     */
    private final Semaphore semaphore;

    /**
     * 构造器
     *
     * @param context 上下文
     * @since 0.0.5
     */
    public LimitSemaphore(final ILimitContext context) {
        this.semaphore = new Semaphore(context.count());
    }

    @Override
    public synchronized void acquire() {
        try {
            LOG.debug("[Limit] start acquire");
            this.semaphore.acquire(1);
            LOG.debug("[Limit] end acquire");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            LOG.error("[Limit] semaphore meet ex: ", e);
        }
    }

    @Override
    public void release() {
        LOG.debug("[Limit] start release");
        this.semaphore.release(1);
        LOG.debug("[Limit] end release");
    }

}

测试

我们限定每次只有一个线程可以执行核心方法,如下:

public class LimitSemaphoreTest {

    private static final Log LOG = LogFactory.getLog(LimitSemaphoreTest.class);

    private static final ILimit LIMIT = LimitBs.newInstance(LimitSemaphore.class)
            .count(1)
            .build();

    static class LimitRunnable implements Runnable {
        @Override
        public void run() {
            for(int i = 0; i < 2; i++) {
                try {
                    LIMIT.acquire();
                    LOG.info("{}-{}", Thread.currentThread().getName(), i);
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    LIMIT.release();
                }
            }
        }
    }

    public static void main(String[] args) {
        new Thread(new LimitRunnable()).start();
        new Thread(new LimitRunnable()).start();
    }

}
  • 日志输出
13:35:37.501 [Thread-1] INFO  com.github.houbb.rate.limit.test.semaphore.LimitSemaphoreTest - Thread-1-0
13:35:38.501 [Thread-2] INFO  com.github.houbb.rate.limit.test.semaphore.LimitSemaphoreTest - Thread-2-0
13:35:39.502 [Thread-1] INFO  com.github.houbb.rate.limit.test.semaphore.LimitSemaphoreTest - Thread-1-1
13:35:40.503 [Thread-2] INFO  com.github.houbb.rate.limit.test.semaphore.LimitSemaphoreTest - Thread-2-1

可以看到每次只有一个线程可以执行方法。

小结

这种方法最为简单,但是存在很多问题。

并入并发量问题,比如控制的力度不够灵活细致等。

后续我们来看下其他的实现方式。

参考资料

限流技术总结

标签:03,LOG,Thread,Semaphore,限流,semaphore,public
From: https://www.cnblogs.com/houbbBlogs/p/18459171

相关文章

  • vue ui创建项目报错:Cannot read property 'indexOf' of undefined解决方法
    本来以为是个很简单的小报错,在网上搜了几个教程竟然都没有解决,整了快半个小时,越整越烦躁。最后忍无可忍重新安装了一遍nodejs,竟然还报这个错...突然想到自己一直没去看详细的报错日志,于是在黑窗看了一下报错内容:原来是权限不够(注:之前用系统管理员身份运行过,创建项目那里目录一......
  • GD32F303移植FreeRTOS-Plus-CLI
    FreeRTOS移植好是没有命令行交互的,刚好系统提供了相关的代码,那么就方便多了。示例基于FreeRTOS-Kernel-9.0.0.zip,再次之前需要把系统移植完毕。移植FreeRTOS-Plus-CLI需要干好几件事串口初始化串口终端服务函数添加自己定制的命令下面讲添加哪些文件新建一个分组,放CLI相......
  • Spark - [03] 资源调度模式
    题记部分 一、Local模式1.1、概述Local模式就是运行在一台计算机上的模式,通常就是用于在本机上练手和测试的。可以通过以下几种方式设置Master(1)local:所欲计算都运行在一个线程当中,没有任何并行计算,通常我们在本机执行一些测试代码,或者练手,就用这种模式。(2)local[K]:指定使......
  • jsp创意众筹网站035kb--(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,项目类型,项目信息,项目支持,项目结果,举报信息开题报告内容一、研究背景随着互联网技术的快速发展,众筹作为一种新兴的融资模式,逐渐受到广大创业者和投资......
  • 洛谷P10387 [蓝桥杯 2024 省 A] 训练士兵
    洛谷P10387[蓝桥杯2024省A]训练士兵1.Mysolution#include<stdio.h>#include<algorithm>#include<cmath>#include<iostream>#include<set>#include<string>#defineFor(i,j,n)for(inti=j;i<=n;++i)template&l......
  • 修复HTTPS升级后出现 Mixed Content: The page at 'https://xxx' was loaded over HTT
    背景由于需要使用摄像头拍照,需要将原来的http升级到https,通过一顿捣鼓,升级成功。不过页面加载出现了问题,具体的提示是说:你的页面是在https环境,但是你访问了一个资源(我这里是iframe,也可能是stylesheet等其他资源),而这个资源是在http环境下的,浏览器不给你这样玩。https只能访问h......
  • 设计方案:FMC303-两路5.6Gsps 14bit DA FMC子卡
    一、板卡概述    FMC303可实现宽波段、双通道、14位、5.6GSPS(2.8gsps直接射频综合)DAC功能,时钟可采用内部时钟源(可选择锁定到外部参考),或外部提供的采样时钟。此外还为用户提供定制采样控制的触发器输入。FMC303在机械上和电气上符合FMC标准(ANSI/VITA 57.1)。该卡具有多引脚连......
  • 20222403 2024-2025-1 《网络与系统攻防技术》实验一实验报告
    1.实验内容本周学习内容1.熟悉基本的汇编语言指令及其功能。2.掌握了栈与堆的概念及其在进程内存管理中的应用以及用户态与内核态的区别。3.熟练运用了Linux系统下的基本操作命令。2.实验过程任务一直接修改程序机器指令,改变程序执行流程下载并解压目标文件pwn1,然后拖入虚......
  • 数据库系统-03-SQL1
    一、SQL组成部分二、SQL数据定义—DDL1.数据类型2.DDL—建表语句3.DDL—完整性约束(1) 常用约束(2)外键约束4.DDL—删除droptable命令从数据库中删除关于被删除关系的所有信息(元组和模式)语法:drop tabler5.DDL—修改(1)向已存在的关系添加属性语法:altert......
  • STM32f103c8t6中PWM的配置
    1、PWM简介    PWM波形(PulseWidthModulation,脉冲宽度调制波形)是一种占空比可变的脉冲波形。这种调制方式通过改变脉冲的宽度来控制电路中的信号强度和频率。具体来说,PWM波形中的高电平持续时间和低电平持续时间可以根据需要进行调整,从而实现对模拟信号电平的数字......