接口调用频率限制代码

有很多时候我们写的代码不是你想跑多快就能跑多快的, 因为一些陈旧的核心系统支撑不了,在此万般无奈的情况下,

 

调用老系统的接口,服务 就需要运维给一个可以接受的范围参考, 情景大概是这样,现实还是很难接受,明明写好的代码

 

还用了一些自己优化技术来使代码运行的更快, 现实都是残酷的,不那么完美的, 与其被弓虽女干,不如好好享受一番。

 

 

分享一下基于ThreadLocal限制调用频率的代码:

 

其中引入了commons-lang里的StopWatch计时器

 

 

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.opencfg.core.limit;

import org.apache.commons.lang.time.StopWatch;

/**
 * <p>
 * Frequence Utils
 * <p>
 * 
 * <p>#ThreadSafe#</p>
 * 
 * @author Opencfg Software Foundation
 * @since 0.0.1-SNAPSHOT
 * @version $Id: FrequenceUtils.java 2011-06-11 23:58:53 reymondtu $
 */
public final class FrequenceUtils {

	/**
	 * <p>
	 * Limit call count in split time
	 * </p>
	 * 
	 * @param limitSplitTime
	 * @param limitCount
	 * @throws InterruptedException
	 */
	public static void limit(final long limitSplitTime, final int limitCount) throws InterruptedException {
		FrequenceUnit funit = threadLocal.get();
		funit.limitSplitTime = limitSplitTime;
		funit.limitCount = limitCount;
		funit.watch.split();
		long diffTime = funit.limitSplitTime - funit.watch.getSplitTime();
		if (diffTime >= 0) {
			if (funit.realCount >= funit.limitCount) {
				funit.watch.suspend();
				Thread.sleep(diffTime);
				funit.watch.resume();
				funit.realCount = 0;
			}
		}
		funit.realCount++;
	}
	
	/**
	 * FrequenceUnit
	 */
	private static class FrequenceUnit {		
		FrequenceUnit() {
			this.watch = new StopWatch();
		}
		long limitSplitTime;
		int limitCount;
		StopWatch watch;		
		int realCount = 0;
	}

	private static ThreadLocal<FrequenceUnit> threadLocal = new ThreadLocal<FrequenceUnit>(){
        protected synchronized FrequenceUnit initialValue() {
        	FrequenceUnit funit = new FrequenceUnit();
        	funit.watch.start();
            return funit;
        }
    };

}

 

 

下边是测试用例:

 

 

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.opencfg.core.limit;

import static org.junit.Assert.assertTrue;

import org.junit.Test;

/**
 * <p>
 * Frequence Utils Test
 * <p>
 * 
 * <p>JUnit4 Test</p>
 * 
 * @author Opencfg Software Foundation
 * @since 0.0.1-SNAPSHOT
 * @version $Id: FrequenceUtilsTest.java 2011-06-12 01:36:53 reymondtu $
 */
public class FrequenceUtilsTest {

	@Test
	public void testLimit() throws InterruptedException {
		FrequenceTestClass ftc = new FrequenceTestClass(1000, 10);
		for(int i = 0; i < 100; i++) {
			ftc.method(i);
		}
		assertTrue(true);
	}
	
	@Test
	public void testLimitMutiThreads() throws InterruptedException {
		Thread t1 = new Thread(new FrequenceTestClass(1000, 10));
		t1.start();
		
		Thread t2 = new Thread(new FrequenceTestClass(1000, 20));
		t2.start();

		Thread.sleep(10000);
	}

	class FrequenceTestClass implements Runnable {
		final long limitTime;
		final int limitCount;
		FrequenceTestClass(final long limitTime, final int limitCount) {
			this.limitTime = limitTime;
			this.limitCount = limitCount;
		}
		public void method(int i) throws InterruptedException {
			FrequenceUtils.limit(limitTime, limitCount);
			System.out.println("tid:" + Thread.currentThread().getId() + ", i=" + i);
		}

		@Override
		public void run() {
			for(int i = 0; i < 100; i++) {
				try {
					method(i);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值