IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> 用JAVA实现一个简单的预热功能 -> 正文阅读

[开发工具]用JAVA实现一个简单的预热功能

背景

某服务调用,因服务器性能问题,无法直接使用最大qps进行调用,需要动态加速

逻辑

设置最大加速时间,设置允许加速到的最大qps

代码

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicLong;

/**
 * 预热控制器
 * @author chunyang.leng
 * @date 2022-03-11 6:22 PM
 */
public class WarmUpManager {
    private static final Logger logger = LoggerFactory.getLogger(WarmUpManager.class);

    /**
     * 预热总时长,单位秒
     */
    private final Long second;

    /**
     * 允许加速到的最大的qps
     */
    private final Long maxQps;

    /**
     * 描述信息
     */
    private String description;

    /**
     * 允许每秒执行的次数
     */
    private final AtomicLong secondQps;
    /**
     * 执行次数计数器
     */
    private AtomicLong requestCount = new AtomicLong(0);

    /**
     * 当前时间,预热功能使用
     */
    private long currentTimeMillis = System.currentTimeMillis();

    /**
     * 时间窗口ms,固定值,一秒
     */
    private final long interval = 1000;

    /**
     * 初始化时间
     */
    private final long initTime = System.currentTimeMillis();

    /**
     * 步进值,默认10
     */
    private final long warmUpLimitStepValue;

    /**
     * 预热结束时间戳
     */
    private final long endTimeMillis;

    /**
     * 创建预热控制对象
     *
     * @param second 预热总时长,单位:秒
     * @param maxQps 允许加速到的最大的qps,不允许为空
     * @param description 描述信息,用于打印日志
     */
    public WarmUpManager(long second,  long maxQps, String description) {
        if(maxQps <= 0){
            throw new IllegalArgumentException("maxQPs 必须大于0");
        }
        this.second = second;
        this.maxQps = maxQps;

        // 计算每秒允许通过的qps
        secondQps = new AtomicLong(maxQps / second);
        if (secondQps.get() == 0) {
            // 防止为0
            secondQps.set(1);
        }
        // 设置步进
        warmUpLimitStepValue = secondQps.get();
        if(description == null){
            this.description = "";
        }
        // 计算预热结束时间
        endTimeMillis = currentTimeMillis + second * interval;
    }


    /**
     * 开始预热
     *
     */
    public void warmUp() throws InterruptedException {
        // 当前时间戳
        long now = System.currentTimeMillis();

        if (now >= endTimeMillis ) {
            // 当前时间大于等于结束时间,预热结束
            return;
        }
        // 计算下一跳窗口起始时间戳
        long total = currentTimeMillis + interval;

        if ((now < total) && requestCount.incrementAndGet() > secondQps.get()) {
            // 当前时间小于下一窗口开始时间,并且请求次数大于限制的qps数,需要进行限速

            // ((now - initTime) / 1000) + 1 ,是因为开始时间为0
            // 日志secondQps.get() + 1 ,是因为 secondQps.getAndAdd(warmUpLimitStepValue); 会丢失1
            LogUtils.info(logger, "{} 预热中,已预热{}秒,qps限流:{}", description, ((now - initTime) / 1000) + 1, secondQps.get() + 1);

            // 执行sleep,睡眠时间为,下一跳开始时间 到 当前时间差
            Thread.sleep(total - now);

            currentTimeMillis = System.currentTimeMillis();
            // 超时后重置
            requestCount = new AtomicLong(0);

            // 重新计算qps大小,步进累加,且不能超出最大限制
            if (secondQps.get() + warmUpLimitStepValue < maxQps) {
                secondQps.getAndAdd(warmUpLimitStepValue);
            }
        }
    }
}


使用方式

public class Test {


    public static void main(String[] args) throws InterruptedException {
        WarmUpManager warmUpManager = new WarmUpManager(10L,5L,"");

        int max = 1000;
        for (int i = 0; i < max; i++) {
            warmUpManager.warmUp();
            System.out.println("==========> " + (  i));
        }
        System.out.println("====run done ");
    }

}
  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:47:55  更:2022-03-15 22:49:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:21:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码