- 在产品的开发中遇到一个业务场景,产品客户端需要记录对客户端的每条请求并上报到产品后台中心端。原来的代码逻辑是获取到请求流量直接发送给中心端,简单粗暴。经过测试,如果客户端在检测高并发系统时效率大大降低,鉴于此处是一个典型的生产者消费者模式,考虑用阻塞队列做缓存,下面贴代码:
**
流量缓存阻塞队列(选用LinkedBlockingQueque,设定大小为1000)
private static BlockingQueue<Mirror> cacheQueue = new LinkedBlockingQueue<Mirror> (1000);
消费者:
/**
* 客户端初始化时调用
*/
public static void initMirrorSender() throws Exception {
//此处也可使用线程池,因为是常驻线程,所以区别不大
Thread senderThread = new Thread(new Runnable() {
List<Mirror> mirrorList;
Mirror mirror;
@Override
public void run() {
while (true) {
//每次取流量时如果当前队列里无元素,则block
mirror = cacheQueue.take();
mirrorList.add(mirror);
//保证每次发送最大不超过200条
while(mirrorList.size<200 && (mirror = cacheQueue.poll()) != null ){
mirrorList.add(mirror);
}
try{
//向中心端发送流量
HttpUtil.sendPost(url, mirrorList);
}catch(Throwable t){
LOGGER.error(t);
}
try {
//默认200毫秒从队列里取一次
Thread.sleep(200);
} catch (InterruptedException e) {
LOGGER.error(e);
}
continue;
}
}
});
thread.start();
}
生产者
public static void mirrorGenerator(Mirror mirror){
//此处省略对mirror的参数校验
。。。。
if(cacheQueue.offer(mirror)){
Logger.info("Cache successfully!")
}else{
Logger.info("Cache Failed!");
}
}
通过优化,大大 减少了http请求交互,挺高了性能