allbet代理:如何用利特尔规则调整线程池巨细

admin 2个月前 (05-27) 科技 3 0

利特尔规则

利特尔规则派生于排队论,用以下数学公式示意:

L = λW

L 系统中存在的平均请求数目。

λ 请求有用到达速率。例如:5/s 示意每秒有5个请求到达系统。

W 请求在系统中的平均守候执行时间。

排队论:研究服务系统中排队征象随机纪律的学科,探讨排队有关的数目指标的概率纪律性。

场景

我们先假设一个店肆员工调整场景。

条件

  • 每个客户一次只买一只炸鸡;

  • 每位员工制作一个炸鸡需要1分钟。

  • 客户买炸鸡时守候时间越短,体验越好。

若是你是一家炸鸡店老板,今年受疫情影响需要对店里的员工举行调整,你会若何处置?

这个问题本质就是员工利用率客户体验之间的权衡。

  1. 为了让客户保持极佳体验,需要保持员工数目或增添员工;

  2. 为制止资源虚耗,控制人力成本,需要淘汰空闲员工。

假设店里现在有3名员工。你若何举行员工调整决议。我们剖析以下几种情形。

平均客流量 = 3人/分钟 客户守候时间稍短,体验优越,而且员工事情都是饱和。此时不需要调整。

平均客流量 < 3人/分钟 客户守候时间稍短,体验优越,然则始终有一个员工在打酱油,此时可以思量减裁一人。

平均客流量 > 3人/分钟 客户5,6,7守候时间延伸体验稍差,此时可以凭据现实情况增添员工。

平均每分钟客流量 ≈ 员工数 为最佳。

线程池

实在线程池处置也算是一个排队模子。简化Java线程池处置模子如下:

线程池义务执行大致阶段:提交 --> 入行列或直接执行 ---> 现实执行

allbet代理:如何用利特尔规则调整线程池巨细 第1张

  • 义务提交频率:每秒义务提交数;

  • 义务行列守候平均耗时:义务行列守候总耗时除以现实执行数;

  • 义务现实执行平均耗时:义务现实运行总耗时除以现实执行数;

  • 义务执行平均耗时:义务行列守候平均耗时加义务现实执行平均耗时;

我们可以凭据以下指标来评估调整线程池参数

线程池中平均义务数 = 义务提交频率 * 义务执行平均耗时

线程守候耗时与响应时间比率 = 义务行列守候总耗时 / (义务行列守候总耗时 + 义务现实执行总耗时

线程守候耗时与响应时间比率 过高,说明义务排队较多,评估当前线程池巨细是否合理,连系系统负载举行响应调整。

线程池中平均义务数 < 现在线程池巨细 应适当削减线程数目。

系统平均处置义务数 > 现在线程池巨细 在这种情况下,先评估当前系统是否有能力支持更大的线程数目(如CPU数,内存等),然后再举行调整。

代码片断

@Slf4j
public class MonitoredThreadPoolExecutor extends ThreadPoolExecutor {

    //义务提交乐成时间
    private final ConcurrentHashMap<Runnable, Long> timeOfRequest = new ConcurrentHashMap<>();
    //义务现实最先执行时间
    private final ThreadLocal<Long> startTime = new ThreadLocal<>();
    //上一个义务提交乐成时间
    private long lastArrivalTime;

    // 义务现实执行总数
    private final AtomicInteger numberOfRequestsRetired = new AtomicInteger();
    // 义务提交总数
    private final AtomicInteger numberOfRequests = new AtomicInteger();
    // 义务现实执行总耗时
    private final AtomicLong totalServiceTime = new AtomicLong();
    // 义务在行列守候总耗
    private final AtomicLong totalPoolTime = new AtomicLong();
    // 新义务提交总耗时
    private final AtomicLong aggregateInterRequestArrivalTime = new AtomicLong();


    public MonitoredThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                                       BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    @Override
    protected void beforeExecute(Thread worker, Runnable task) {
        super.beforeExecute(worker, task);
        startTime.set(System.nanoTime());
    }

    @Override
    protected void afterExecute(Runnable task, Throwable t) {
        try {
            long start = startTime.get();
            totalServiceTime.addAndGet(System.nanoTime() - start);
            totalPoolTime.addAndGet(start - timeOfRequest.remove(task));
            numberOfRequestsRetired.incrementAndGet();
        } finally {
            if (null != t) {
                log.error(AppSystem.ERROR_LOG_PREFIX + "线程池处置异常:", Throwables.getRootCause(t));
            }
            super.afterExecute(task, t);
        }
    }

    @Override
    public void execute(Runnable task) {
        long now = System.nanoTime();
        numberOfRequests.incrementAndGet();
        synchronized (this) {
            if (lastArrivalTime != 0L) {
                aggregateInterRequestArrivalTime.addAndGet(now - lastArrivalTime);
            }
            lastArrivalTime = now;
            timeOfRequest.put(task, now);
        }
        super.execute(task);
    }
}

测试

两组迭代请求,一次提交10个义务,线程数为1

allbet代理:如何用利特尔规则调整线程池巨细 第2张

两组迭代请求,一次提交10个义务,线程数为10

allbet代理:如何用利特尔规则调整线程池巨细 第3张

两组迭代请求,一次提交10个义务,线程数为50

allbet代理:如何用利特尔规则调整线程池巨细 第4张

上面测试对照片面。现实应凭据系统历久平均指标举行调整。

总结

利特尔规则应用场景许多。迎接人人留言交流!

,

Sunbet

Sunbet www.sunbet.xyz是Sunbet指定的Sunbet官网,Sunbet提供Sunbet(Sunbet)、Sunbet、申博代理合作等业务。

皇冠APP声明:该文看法仅代表作者自己,与本平台无关。转载请注明:allbet代理:如何用利特尔规则调整线程池巨细

网友评论

  • (*)

最新评论

文章归档

站点信息

  • 文章总数:548
  • 页面总数:0
  • 分类总数:8
  • 标签总数:1049
  • 评论总数:165
  • 浏览总数:2821