题目
有一个消息队列集群,集群里每台Broker的响应时间RT都不一样,但是每台Broker的极限服务QPS都是一样的,超过这个QPS会出现过载雪崩。而消息的生产者客户端,每次发送都会选择其中的一台broker来发送,一般来说发送逻辑是运行在一个线程池里面。假设cpu资源充足,通过实现一个负载均衡算法,使得生产者能够达到最大吞吐量,最优的平均响应时间,但是又不能把任何一台服务器压垮。已知每个broker的rt、极限qps,消息生产者的线程数量,请求总数,如果采用吞吐量最优的算法,求处理完所有请求需要的耗时,单位毫秒。
概念说明:
QPS:query per second, 每秒请求量
RT:response time,请求的响应时间(单位为ms)
Broker:消息队列的服务器
背景知识
有一个重要的公式:
每台服务器都有一个最大的QPS,服务器的响应时间的倒数是1台客户访问时,每秒服务器可以处理的事务数。当有多个客户进行访问的话,服务器就会开多个线程(进程),在每个线程(进程)中,响应时间不会有太大变化(在客户数不多的情况下),那么QPS就可以随着并发数的增加而增加了。但凡事都有个度,当并发数增加到一定时,响应时间就会明显增加了。线程(进程)变多了,服务器花费在调度上的时间比例就增加了。
在真实情况下,响应时间可以根据业务情况进行估算。比如对于人们浏览一个网站,响应时间100ms和500ms是没有区别的。根据QPS的公式,在服务器最大QPS不变的情况下,增大响应时间可以增大并发数,就是一台服务器可以服务更多的客户,从而减少服务器成本。
回到题目
题目中已经给出了main()函数,我们需要完成doneTime()函数。对于题目中给出的例子,共有10个线程,5个服务器。我原本以为只有一个客户端,最多只能有10个线程,后来发现并不是这样的。我们可以5个客户端50个线程一起去访问5个服务器。那么对于每个服务器,响应时间和并发数都已知,那么QPS就可以计算出来,若QPS太大,就取QPS的上限。将5个QPS相加,就是这个集群的QPS。请求总数除以集群的QPS就是花费的时间。
按照自己的理解,画出题目中的例子表达图,有利于理解情景。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int maxQps= Integer.valueOf(in.nextLine());
final String[] rtList = in.nextLine().split(",");
final int requestNum = Integer.valueOf(in.nextLine());
final int threadNum = Integer.valueOf(in.nextLine());
System.out.println(doneTime(maxQps, rtList, requestNum, threadNum));
}
/**
* 如果使用最优的最大吞吐量负载均衡算法,按照最优模型多久能够处理完所有请求,单位毫秒。
* @return
*/
static long doneTime(int maxQps,String[] rtList,int requestNum,int threadNum) {
//TODO
int qpsSum = 0;
for (String rtString : rtList) {
int singleMaxQps = threadNum * 1000 / Integer.valueOf(rtString);
if (singleMaxQps > maxQps) {
qpsSum += maxQps;
}else {
qpsSum += singleMaxQps;
}
}
return requestNum / qpsSum * 1000;
}
}
【Reference】
http://www.cnblogs.com/zhulin-jun/p/6597074.html
https://dearhwj.gitbooks.io/itbook/content/test/performance_test_qps_tps.html