提交 cdd48334 编写于 作者: L lingxiao 提交者: youyong205

apache-dubbo

上级 ce1e28b9
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-plus</artifactId>
<groupId>net.dubboclub</groupId>
<version>0.0.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>net.dubboclub</groupId>
<artifactId>cat-monitor</artifactId>
<dependencies>
<dependency>
<groupId>com.dianping.cat</groupId>
<artifactId>cat-client</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.4.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
# DUBBO和cat整合插件
主要目的是能够监控当前系统dubbo调用执行情况,比如耗时以及异常统计
## Getting start
引入插件包
```xml
<dependency>
<groupId>net.dubboclub</groupId>
<artifactId>cat-monitor</artifactId>
<version>0.0.6</version>
</dependency>
```
# That's All!
项目添加以上依赖将会在cat里面出现cross报表,dependency,服务端的matrix以及调用链路的trace信息(1.0.8以后(包含1.0.8))
## 手动开启/关闭cat监控
```java
DubboCat.disable();
//开启
DubboCat.enable();
```
package net.dubboclub.catmonitor;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
/**
* Created by bieber on 2015/11/12.
*/
@Activate(group = {CommonConstants.CONSUMER})
public class AppNameAppendFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
RpcContext.getContext().setAttachment(CommonConstants.APPLICATION_KEY,invoker.getUrl().getParameter(CommonConstants.APPLICATION_KEY));
return invoker.invoke(invocation);
}
}
package net.dubboclub.catmonitor;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.remoting.TimeoutException;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.support.RpcUtils;
import com.dianping.cat.Cat;
import com.dianping.cat.log.CatLogger;
import com.dianping.cat.message.Event;
import com.dianping.cat.message.Message;
import com.dianping.cat.message.Transaction;
import net.dubboclub.catmonitor.constants.CatConstants;
import org.apache.commons.lang.StringUtils;
import java.util.HashMap;
import java.util.Map;
/**
* Created by bieber on 2015/11/4.
*/
@Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER},order = -9000)
public class CatTransaction implements Filter {
private final static String DUBBO_BIZ_ERROR="DUBBO_BIZ_ERROR";
private final static String DUBBO_TIMEOUT_ERROR="DUBBO_TIMEOUT_ERROR";
private final static String DUBBO_REMOTING_ERROR="DUBBO_REMOTING_ERROR";
private static final ThreadLocal<Cat.Context> CAT_CONTEXT = new ThreadLocal<Cat.Context>();
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
if(!DubboCat.isEnable()){
Result result = invoker.invoke(invocation);
return result;
}
URL url = invoker.getUrl();
String sideKey = url.getParameter(CommonConstants.SIDE_KEY);
String loggerName = invoker.getInterface().getSimpleName()+"."+invocation.getMethodName();
String type = CatConstants.CROSS_CONSUMER;
if(CommonConstants.PROVIDER_SIDE.equals(sideKey)){
type= CatConstants.CROSS_SERVER;
}
boolean init = false;
Transaction transaction = null;
try{
transaction = Cat.newTransaction(type, loggerName);
Cat.Context context = getContext();
if(CommonConstants.CONSUMER_SIDE.equals(sideKey)){
createConsumerCross(url,transaction);
Cat.logRemoteCallClient(context);
}else{
createProviderCross(url,transaction);
Cat.logRemoteCallServer(context);
}
setAttachment(context);
init = true;
} catch (Exception e) {
CatLogger.getInstance().error("[DUBBO] DubboCat init error.", e);
}
Result result=null;
try{
result = invoker.invoke(invocation);
if (!init) {
return result;
}
boolean isAsync = RpcUtils.isAsync(invoker.getUrl(), invocation);
//异步的不能判断是否有异常,这样会阻塞住接口(<AsyncRpcResult>hasException->getRpcResult->resultFuture.get()
if (isAsync) {
transaction.setStatus(Message.SUCCESS);
return result;
}
if(result.hasException()){
//给调用接口出现异常进行打点
Throwable throwable = result.getException();
Event event = null;
if(RpcException.class==throwable.getClass()){
Throwable caseBy = throwable.getCause();
if(caseBy!=null&&caseBy.getClass()==TimeoutException.class){
event = Cat.newEvent(DUBBO_TIMEOUT_ERROR,loggerName);
}else{
event = Cat.newEvent(DUBBO_REMOTING_ERROR,loggerName);
}
}else if(RemotingException.class.isAssignableFrom(throwable.getClass())){
event = Cat.newEvent(DUBBO_REMOTING_ERROR,loggerName);
}else{
event = Cat.newEvent(DUBBO_BIZ_ERROR,loggerName);
}
event.setStatus(result.getException());
completeEvent(event);
transaction.addChild(event);
transaction.setStatus(result.getException().getClass().getSimpleName());
}else{
transaction.setStatus(Message.SUCCESS);
}
return result;
}catch (RuntimeException e){
if (init) {
Cat.logError(e);
Event event;
if (RpcException.class == e.getClass()) {
Throwable caseBy = e.getCause();
if (caseBy != null && caseBy.getClass() == TimeoutException.class) {
event = Cat.newEvent(DUBBO_TIMEOUT_ERROR, loggerName);
} else {
event = Cat.newEvent(DUBBO_REMOTING_ERROR, loggerName);
}
} else {
event = Cat.newEvent(DUBBO_BIZ_ERROR, loggerName);
}
event.setStatus(e);
completeEvent(event);
transaction.addChild(event);
transaction.setStatus(e.getClass().getSimpleName());
}
if(result==null){
throw e;
}else{
return result;
}
}finally {
if (transaction != null) {
transaction.complete();
}
CAT_CONTEXT.remove();
}
}
static class DubboCatContext implements Cat.Context{
private Map<String,String> properties = new HashMap<String, String>();
@Override
public void addProperty(String key, String value) {
properties.put(key,value);
}
@Override
public String getProperty(String key) {
return properties.get(key);
}
}
private String getProviderAppName(URL url){
String appName = url.getParameter(CatConstants.PROVIDER_APPLICATION_NAME);
if(StringUtils.isEmpty(appName)){
String interfaceName = url.getParameter(CommonConstants.INTERFACE_KEY);
appName = interfaceName.substring(0,interfaceName.lastIndexOf('.'));
}
return appName;
}
private void setAttachment(Cat.Context context){
RpcContext.getContext().setAttachment(Cat.Context.ROOT,context.getProperty(Cat.Context.ROOT));
RpcContext.getContext().setAttachment(Cat.Context.CHILD,context.getProperty(Cat.Context.CHILD));
RpcContext.getContext().setAttachment(Cat.Context.PARENT,context.getProperty(Cat.Context.PARENT));
}
private Cat.Context getContext(){
Cat.Context context = CAT_CONTEXT.get();
if(context==null){
context = initContext();
CAT_CONTEXT.set(context);
}
return context;
}
private Cat.Context initContext(){
Cat.Context context = new DubboCatContext();
Map<String,String> attachments = RpcContext.getContext().getAttachments();
if(attachments!=null&&attachments.size()>0){
for(Map.Entry<String,String> entry:attachments.entrySet()){
if(Cat.Context.CHILD.equals(entry.getKey())||Cat.Context.ROOT.equals(entry.getKey())||Cat.Context.PARENT.equals(entry.getKey())){
context.addProperty(entry.getKey(),entry.getValue());
}
}
}
return context;
}
private void createConsumerCross(URL url,Transaction transaction){
Event crossAppEvent = Cat.newEvent(CatConstants.CONSUMER_CALL_APP,getProviderAppName(url));
Event crossServerEvent = Cat.newEvent(CatConstants.CONSUMER_CALL_SERVER,url.getHost());
Event crossPortEvent = Cat.newEvent(CatConstants.CONSUMER_CALL_PORT,url.getPort()+"");
crossAppEvent.setStatus(Event.SUCCESS);
crossServerEvent.setStatus(Event.SUCCESS);
crossPortEvent.setStatus(Event.SUCCESS);
completeEvent(crossAppEvent);
completeEvent(crossPortEvent);
completeEvent(crossServerEvent);
transaction.addChild(crossAppEvent);
transaction.addChild(crossPortEvent);
transaction.addChild(crossServerEvent);
}
private void completeEvent(Event event){
event.complete();
}
private void createProviderCross(URL url,Transaction transaction){
String consumerAppName = RpcContext.getContext().getAttachment(CommonConstants.APPLICATION_KEY);
if(StringUtils.isEmpty(consumerAppName)){
consumerAppName= RpcContext.getContext().getRemoteHost()+":"+ RpcContext.getContext().getRemotePort();
}
Event crossAppEvent = Cat.newEvent(CatConstants.PROVIDER_CALL_APP,consumerAppName);
Event crossServerEvent = Cat.newEvent(CatConstants.PROVIDER_CALL_SERVER, RpcContext.getContext().getRemoteHost());
crossAppEvent.setStatus(Event.SUCCESS);
crossServerEvent.setStatus(Event.SUCCESS);
completeEvent(crossAppEvent);
completeEvent(crossServerEvent);
transaction.addChild(crossAppEvent);
transaction.addChild(crossServerEvent);
}
}
package net.dubboclub.catmonitor;
import com.dianping.cat.Cat;
import com.dianping.cat.log.CatLogger;
/**
* Created by bieber on 2015/11/16.
*/
public class DubboCat {
private static boolean isEnable=true;
/**
* 禁用dubbo cat
*/
public static void disable(){
isEnable=false;
}
/**
* 启用dubbo cat
*/
public static void enable(){
isEnable=true;
}
/**
* 是否有效
* @return
*/
public static boolean isEnable(){
boolean isCatEnabled = false;
try {
isCatEnabled = Cat.getManager().isCatEnabled();
} catch (Throwable e) {
CatLogger.getInstance().error("[DUBBO] Cat init error.", e);
}
return isCatEnabled && isEnable;
}
}
package net.dubboclub.catmonitor.constants;
/**
* Created by bieber on 2015/11/12.
*/
public class CatConstants {
public static final String CROSS_CONSUMER ="PigeonCall";
public static final String CROSS_SERVER = "PigeonService";
public static final String PROVIDER_APPLICATION_NAME="serverApplicationName";
public static final String CONSUMER_CALL_SERVER="PigeonCall.server";
public static final String CONSUMER_CALL_APP="PigeonCall.app";
public static final String CONSUMER_CALL_PORT="PigeonCall.port";
public static final String PROVIDER_CALL_SERVER="PigeonService.client";
public static final String PROVIDER_CALL_APP="PigeonService.app";
public static final String FORK_MESSAGE_ID="m_forkedMessageId";
public static final String FORK_ROOT_MESSAGE_ID="m_rootMessageId";
public static final String FORK_PARENT_MESSAGE_ID="m_parentMessageId";
}
package net.dubboclub.catmonitor.registry;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.RegistryFactory;
import net.dubboclub.catmonitor.constants.CatConstants;
import java.util.List;
/**
* Created by bieber on 2015/11/12.
*/
public class CatRegistryFactoryWrapper implements RegistryFactory {
private RegistryFactory registryFactory;
public CatRegistryFactoryWrapper(RegistryFactory registryFactory) {
this.registryFactory = registryFactory;
}
@Override
public Registry getRegistry(URL url) {
return new RegistryWrapper(registryFactory.getRegistry(url));
}
class RegistryWrapper implements Registry {
private Registry originRegistry;
private URL appendProviderAppName(URL url){
String side = url.getParameter(CommonConstants.SIDE_KEY);
if(CommonConstants.PROVIDER_SIDE.equals(side)){
url=url.addParameter(CatConstants.PROVIDER_APPLICATION_NAME,url.getParameter(CommonConstants.APPLICATION_KEY));
}
return url;
}
public RegistryWrapper(Registry originRegistry) {
this.originRegistry = originRegistry;
}
@Override
public URL getUrl() {
return originRegistry.getUrl();
}
@Override
public boolean isAvailable() {
return originRegistry.isAvailable();
}
@Override
public void destroy() {
originRegistry.destroy();
}
@Override
public void register(URL url) {
originRegistry.register(appendProviderAppName(url));
}
@Override
public void unregister(URL url) {
originRegistry.unregister(appendProviderAppName(url));
}
@Override
public void subscribe(URL url, NotifyListener listener) {
originRegistry.subscribe(url,listener);
}
@Override
public void unsubscribe(URL url, NotifyListener listener) {
originRegistry.unsubscribe(url,listener);
}
@Override
public List<URL> lookup(URL url) {
return originRegistry.lookup(appendProviderAppName(url));
}
}
}
catRegistryFactoryWrapper=net.dubboclub.catmonitor.registry.CatRegistryFactoryWrapper
\ No newline at end of file
catTransaction=net.dubboclub.catmonitor.CatTransaction
appnameAppend=net.dubboclub.catmonitor.AppNameAppendFilter
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册