package com.yirendai.infra.cicada.transfer.disruptor; import com.lmax.disruptor.EventHandler; import com.yirendai.infra.cicada.entity.trace.Span; import com.yirendai.infra.cicada.transfer.DeliverService; import com.yirendai.infra.cicada.transfer.impl.HttpPostDeliverService; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; public class SpanEventHandler implements EventHandler<SpanEvent> { private static final Logger LOGGER = LoggerFactory.getLogger(SpanEventHandler.class); private final List<Span> spanList = new ArrayList<Span>(); private static final int DEFAULT_CONNECT_TIMEOUT = 5000; private static final int DEFAULT_SO_TIMEOUT = 5000; private static final int DEFAULT_BATCH_SIZE = 32; private static final int DEFAULT_TPS_LIMIT = 2048; private DeliverService transferService; private int batchSize = DEFAULT_BATCH_SIZE; private int tpsLimit = DEFAULT_TPS_LIMIT; private long lastRecordTime; private int spanNum; private int dropNum; public SpanEventHandler(final String url) { this(url, DEFAULT_CONNECT_TIMEOUT, DEFAULT_SO_TIMEOUT, DEFAULT_BATCH_SIZE, DEFAULT_TPS_LIMIT); lastRecordTime = System.currentTimeMillis() / 1000; } public SpanEventHandler(final String url, final int connectTimeout, final int soTimeout, final int batchSize, final int tpsLimit) { if (StringUtils.isBlank(url)) { LOGGER.error("url shoud not empty!"); throw new IllegalArgumentException("url shoud not empty!"); } int finConnectTimeout = connectTimeout; int finSoTimeout = soTimeout; if (finConnectTimeout <= 0) { finConnectTimeout = DEFAULT_CONNECT_TIMEOUT; } if (finSoTimeout <= 0) { finSoTimeout = DEFAULT_SO_TIMEOUT; } transferService = new HttpPostDeliverService(url, finConnectTimeout, finSoTimeout); if (batchSize > 0) { this.batchSize = batchSize; } else { this.batchSize = DEFAULT_BATCH_SIZE; } this.tpsLimit = tpsLimit; if (this.tpsLimit <= 0) { this.tpsLimit = DEFAULT_TPS_LIMIT; } } public void onEvent(final SpanEvent spanEvent, final long sequence, final boolean endOfBatch) throws Exception { // LOGGER.info("receiveMsg:" + JSON.toJSONString(spanEvent.get())); final long currentTime = System.currentTimeMillis() / 1000; if (currentTime != lastRecordTime) { lastRecordTime = currentTime; spanNum = 1; if (dropNum > 0) { LOGGER.warn("too fast,drop some message!{}", dropNum); dropNum = 0; } } else { spanNum++; if (spanNum > tpsLimit) { dropNum++; return; } } try { final Span span = spanEvent.get(); spanList.add(span); if (endOfBatch || spanList.size() >= batchSize) { transferService.deliver(spanList); spanList.clear(); } } catch (Exception ex) { LOGGER.error("CreateHttpConnection error", ex); } } }