服务调用的QPS控制(Java)

  • QPS控制器实现类代码:
/**
 * @desc QPS控制器
 * @author visy.wang
 * @date 2020/9/29 10:13
 */
public class QPSCtrl {
	/**
	 * QPS值
	 */
	private int qps;
	/**
	 * 一个周期内的调用次数
	 */
	private int count;
	/**
	 * 一个周期的起始时间(时间戳)
	 */
	private long startTime;
	/**
	 * 周期长度(毫秒)
	 */
	private static final int PERIOD = 1000;

	/**
	 * 通过指定QPS创建控制器(内部使用)
	 * @param qps QPS值
	 */
	private QPSCtrl(int qps){
		this.qps = qps;
	}

	/**
	 * 创建QPSCtrl实例
	 * @param qps QPS值
	 * @return Object
	 */
	public static QPSCtrl create(int qps){
		return new QPSCtrl(qps);
	}

	/**
	 * 开始下一个周期
	 * @param startTime 起始时间戳
	 */
	private void next(long startTime){
		this.count = 1;
		this.startTime = startTime;
		//测试用,可删除
		System.out.println(" ");
	}

	/**
	 * qps控制(线程阻塞,休眠实现)
	 * 适用于多线程环境
	 */
	public synchronized void ctrl(){
		long now = System.currentTimeMillis();
		long duration = now - this.startTime;
		if(duration < PERIOD){
			if(this.count < this.qps){
				this.count ++;
			}else{
				try{
					Thread.sleep(PERIOD - duration);
				}catch (InterruptedException e){
					e.printStackTrace();
				}
				this.next(System.currentTimeMillis());
			}
		}else{
			this.next(now);
		}
	}
}

*使用(测试):

/**
 * @desc QPS控制器测试
 * @author visy.wang
 * @date 2020/9/29 10:25
 */
public class TestQPS {
	/**
	 * 在多线程环境下,请确保拿到的QPSCtrl对象是同一个,
	 * 建议在此处初始化,当然也可用别的方式创建(但需保证是同一个)
	 * 不同的QPSCtrl对象是彼此独立的
	 */
	private static QPSCtrl qpsCtrl1 = QPSCtrl.create(2);
	private static QPSCtrl qpsCtrl2 = QPSCtrl.create(3);
	
	public void test1(int i){
		//调用ctrl()来实现QPS的控制
		qpsCtrl1.ctrl();
		System.out.print(i+"(I) ");
	}

	public void test2(int i){
		//超出QPS值会阻塞在这里,直到下一个周期
		qpsCtrl2.ctrl();
		System.out.print(i+"(II) ");
	}

	public static void main(String[] args) {

		TestQPS testQPS = new TestQPS();

		new Thread(()->{
			for(int i=1; i<=6; i++){
				testQPS.test1(i);
			}
		}).start();

		new Thread(()->{
			for(int i=7; i<=12; i++){
				testQPS.test1(i);
			}
		}).start();

		new Thread(()->{
			for(int i=13; i<=18; i++){
				testQPS.test2(i);
			}
		}).start();
	}
}
  • 输出:
 
7(I) 8(I)  
13(II) 14(II) 15(II)  
9(I) 10(I)  
16(II) 17(II) 18(II)  
11(I) 1(I)  
12(I) 2(I)  
3(I) 4(I)  
5(I) 6(I) 
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
单副本支持5万QPSJava demo可以通过以下步骤实现: 1. 数据库优化:首先,对于高QPS的应用程序,选择高性能的数据库非常重要。可以考虑使用高性能、可伸缩性强的数据库,如MySQL Cluster或Cassandra。另外,可以通过调整数据库的缓存大小、索引优化、分表等方式来提升数据库的性能。 2. 垂直扩展:通过增加服务器的处理能力来提高QPS。可以使用更高性能的硬件、使用多核处理器、增加内存容量等方式来提升单个服务器的处理能力。 3. 并发处理:使用多线程或线程池的方式来实现并发处理。通过将请求分发给多个线程来提高系统的并发能力。 4. 缓存机制:将查询结果缓存起来,避免重复查询数据库。可以使用内存数据库如Redis或使用缓存框架如Ehcache来实现缓存机制。 5. 异步处理:将耗时的操作(如网络请求、IO操作)采用异步方式进行处理,以提高系统的并发能力。 6. 代码优化:对关键代码进行优化,例如避免不必要的循环、减少对象创建和销毁等,以提高代码的执行效率和系统的响应速度。 7. 负载均衡:通过负载均衡器将请求分发到多个副本上,以提高系统的并发能力和可靠性。 通过以上的优化和调整,可以将单副本的Java demo的QPS提升到5万。需要注意的是,实际的性能还受到许多因素的影响,如网络带宽、硬件设备状况、代码质量等,因此要全面考虑系统的各个方面,并综合优化才能达到目标QPS

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值