日志信息收集好了之后,下面就轮到kafka消息队列上场了,先别急,在项目中,并不是拦截到一个日志,就直接发送到kafka的,本来计划是先存在cache里面,然后在发给kafka的,后来老司机又让用了LinkedBlockingQueue这个阻塞队列,队列大小暂时固定为50000,后期不知道会不会改。
/** * 日志数据发送接口实现 */ public class LogSenderImpl implements ILogSender { private final static Lock lock = new ReentrantLock(); private static Thread thread = null; private static Logger logger = LoggerFactory.getLogger(LogSenderImpl.class); private static BlockingQueue<LogInfoDto> blockingQueue = new LinkedBlockingQueue<LogInfoDto>(50000); //添加锁机制,避免开启多个线程 static { try{ lock.lock(); if(thread == null){ thread = new Thread(new Runnable() { @Override public void run() { LogSenderFactory.getLogSender().removeLogInfo(); } }); thread.start(); } }finally { lock.unlock(); } } /** * 把logInfoDto放入到队列中 * @param logInfoDto */ @Override public void send(LogInfoDto logInfoDto) { //非空校验 if (logInfoDto != null){ //offer(E e) : 成功返回 true,如果此队列已满,则返回 false blockingQueue.offer(logInfoDto); } } /** * 取走排在队列中首位的对象,并发送到日志客户端 */ @Override public void removeLogInfo() { LogInfoDto lid= null; while (true) { try{ if(lid == null){ //take():获取并移除此队列头元素,若没有元素则一直阻塞。 lid = blockingQueue.take(); } LogClientFactory.getLogClient().send(lid); lid = null; }catch (Exception e){ logger.error("日志系统调用MQ客户端异常信息:",e.toString()); } } } }
关于这个阻塞队列,找到了个不错的文章,下面给下链接(不知道这算不算转载,算的话请博主通知我):
https://blog.csdn.net/javazejian/article/details/77410889?locationNum=1&fps=1