[java] 模拟QPS

在WEB服务器端,每日的访问量巨大。在非生产环境需要对服务器进行压力测试,一般使用后台线程和Sleep方式来模拟线上的压力。这里使用ScheduledExecutorService实现一种简单的QPS测试代码。

QpsProxy:

import com.google.common.base.Preconditions;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 若Runable执行的时间超过 MAX_QPS / qps,则实际的QPS会低于实际的值。
 */
public class QpsProxy {

    private final Logger logger = LoggerFactory.getLogger(QpsProxy.class);

    private final static int MAX_QPS = 1000;

    private ScheduledExecutorService scheduledExecutorService;

    private long qps = NumberUtils.LONG_ONE;

    private Runnable runnable;

    private long delay2Start = NumberUtils.INTEGER_ZERO;

    private int threads = 10;

    public QpsProxy() {
    }

    public ScheduledExecutorService getScheduledExecutorService() {
        return scheduledExecutorService;
    }

    public void setScheduledExecutorService(ScheduledExecutorService scheduledExecutorService) {
        this.scheduledExecutorService = scheduledExecutorService;
    }

    public long getQps() {
        return qps;
    }

    public void setQps(long qps) {
        Preconditions.checkArgument(qps < MAX_QPS , "设置的qps超过上限值:" + MAX_QPS);
        this.qps = qps;
    }

    public Runnable getRunnable() {
        return runnable;
    }

    public void setRunnable(Runnable runnable) {
        this.runnable = runnable;
    }

    public long getDelay2Start() {
        return delay2Start;
    }

    public void setDelay2Start(long delay2Start) {
        this.delay2Start = delay2Start;
    }

    public int getThreads() {
        return threads;
    }

    public void setThreads(int threads) {
        this.threads = threads;
    }

    public void start() {
        Preconditions.checkNotNull(runnable, "请设置执行的任务");
        long period = (long) Math.floor((double) MAX_QPS / qps);
        logger.info("间隔周期:{}ms", period);
        scheduledExecutorService = Executors.newScheduledThreadPool(threads);
        scheduledExecutorService.scheduleAtFixedRate(runnable, delay2Start,
                period, TimeUnit.MILLISECONDS);
    }

    public void stop() {
        Preconditions.checkNotNull(scheduledExecutorService, "任务未开始");
        scheduledExecutorService.shutdown();
    }
}

  构建工具:

import com.google.common.base.Preconditions;

public class QpsProxyBuilder {

    private QpsProxy qpsProxy = new QpsProxy();

    public static QpsProxyBuilder newBuilder() {
        return new QpsProxyBuilder();
    }

    public QpsProxyBuilder withDelay2Start(long delay2TimeByMillisSeconds) {
        Preconditions.checkArgument(delay2TimeByMillisSeconds > 0);
        qpsProxy.setDelay2Start(delay2TimeByMillisSeconds);
        return this;
    }

    public QpsProxyBuilder withQps(long qps) {
        Preconditions.checkArgument(qps > 0);
        qpsProxy.setQps(qps);
        return this;
    }

    public QpsProxyBuilder withRunnable(Runnable runnable) {
        Preconditions.checkNotNull(runnable);
        qpsProxy.setRunnable(runnable);
        return this;
    }

    public QpsProxyBuilder withThreads(int threads) {
        Preconditions.checkNotNull(threads > 0);
        qpsProxy.setThreads(threads);
        return this;
    }

    public QpsProxy build() {
        return qpsProxy;
    }
}

  测试代码:

import com.qunar.hotel.qps.QpsProxy;
import com.qunar.hotel.qps.QpsProxyBuilder;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class qps {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Test
    public void testBasic() throws InterruptedException {
        QpsProxy proxy = QpsProxyBuilder.newBuilder().withQps(100).withThreads(1).withDelay2Start(4000).withRunnable(new Runnable() {
            private int counter = 0;

            @Override
            public void run() {
                logger.info("{}-{}:{}", Thread.currentThread().getName(), System.nanoTime(), counter++);
            }
        }).build();

        proxy.start();
        Thread.currentThread().sleep(5020L);
        proxy.stop();
    }
}

  

posted @ 2015-07-25 21:28  life91  阅读(1753)  评论(0编辑  收藏  举报