Overview
基于dubbo的filter机制,实现的对Rpc调用的consumer端、provider端监控
code
package com.qunar.flight.pangolin.pay.filter;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.Filter;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.dubbo.rpc.RpcException;
import com.qunar.flight.qmonitor.QMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* dubbo相关 aop监控
* order = Integer.MIN_VALUE,使之最贴近真实逻辑,以免Context资源被释放
*
* @author guohang on 16-8-4
*/
@Activate(group = {Constants.CONSUMER, Constants.PROVIDER}, order = Integer.MIN_VALUE)
public class RpcMonitorFilter implements Filter {
private final Logger logger = LoggerFactory.getLogger(getClass());
private static final String ERROR_SUFFIX = "_Error";
private static final String RPC_PREFIX = "Rpc_";
private static final String PROVIDER_SUFFIX = "_Provider";
private static final String CONSUMER_SUFFIX = "_Consumer";
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
long start = System.currentTimeMillis();
RpcContext context = RpcContext.getContext();
String key = buildMonitorKey(invoker, invocation, context);
Result result;
try {
result = invoker.invoke(invocation);
QMonitor.recordOne(key, System.currentTimeMillis() - start);
} catch (Throwable e) {
throwableAction(e, key, start);
throw e;
}
return result;
}
@SuppressWarnings("all")
private String buildMonitorKey(Invoker<?> invoker, Invocation invocation, RpcContext context) {
return new StringBuilder(64).append(RPC_PREFIX).append(invoker.getInterface().getSimpleName())
.append("_").append(invocation.getMethodName())
.append(context.isProviderSide() ? PROVIDER_SUFFIX : CONSUMER_SUFFIX).toString();
}
private void timeoutAction(RpcException exception, String key, long start) {
final String TIMEOUT_SUFFIX = "_Timeout";
String realKey;
if (exception.isTimeout()) {
realKey = key.concat(TIMEOUT_SUFFIX);
} else {
realKey = key.concat(ERROR_SUFFIX);
}
logger.error(realKey, exception);
QMonitor.recordOne(realKey, System.currentTimeMillis() - start);
throw exception;
}
private void throwableAction(Throwable e, String key, long start) {
if (e instanceof RpcException) {
timeoutAction((RpcException) e, key, start);
} else {
String realKey = key.concat(ERROR_SUFFIX);
logger.error(realKey, e);
QMonitor.recordOne(realKey, System.currentTimeMillis() - start);
}
}
}