接口调用频率限制代码

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

 

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

 

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

 

 

分享一下基于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;

/**
 * 

* Frequence Utils *

* *

#ThreadSafe#

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

* Limit call count in split time *

* * @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 threadLocal = new ThreadLocal(){ 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;

/**
 * 

* Frequence Utils Test *

* *

JUnit4 Test

* * @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(); } } } } }

你可能感兴趣的:(java)