优化dubbo filter

This commit is contained in:
六如
2025-03-12 01:13:48 +08:00
parent 5acf4f85b0
commit c5f4e06df1
7 changed files with 135 additions and 39 deletions

View File

@@ -18,5 +18,6 @@ public final class SopConstants {
public static final String OPEN_CONTEXT = "sop.open-context"; public static final String OPEN_CONTEXT = "sop.open-context";
public static final String WEB_CONTEXT = "sop.web-context"; public static final String WEB_CONTEXT = "sop.web-context";
public static final String DEFAULT_VERSION = "1.0"; public static final String DEFAULT_VERSION = "1.0";
public static final String SPRING_APPLICATION_NAME = "spring.application.name";
} }

View File

@@ -57,4 +57,8 @@ public class DefaultOpenContext extends OpenContext implements Serializable {
public void initContext() { public void initContext() {
this.setContext(this); this.setContext(this);
} }
public void remove() {
this.clear();
}
} }

View File

@@ -64,4 +64,8 @@ public class DefaultWebContext extends WebContext implements Serializable {
public void initContext() { public void initContext() {
this.setContext(this); this.setContext(this);
} }
public void remove() {
this.clear();
}
} }

View File

@@ -63,4 +63,9 @@ public abstract class OpenContext {
public static OpenContext current() { public static OpenContext current() {
return THREAD_LOCAL.get(); return THREAD_LOCAL.get();
} }
protected void clear() {
THREAD_LOCAL.remove();
}
} }

View File

@@ -75,4 +75,8 @@ public abstract class WebContext {
public static WebContext current() { public static WebContext current() {
return THREAD_LOCAL.get(); return THREAD_LOCAL.get();
} }
protected void clear() {
THREAD_LOCAL.remove();
}
} }

View File

@@ -4,7 +4,7 @@ import com.alibaba.fastjson2.JSON;
import com.gitee.sop.support.constant.SopConstants; import com.gitee.sop.support.constant.SopConstants;
import com.gitee.sop.support.context.DefaultOpenContext; import com.gitee.sop.support.context.DefaultOpenContext;
import com.gitee.sop.support.context.DefaultWebContext; import com.gitee.sop.support.context.DefaultWebContext;
import com.gitee.sop.support.context.WebContext; import com.gitee.sop.support.util.NetUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.extension.Activate;
@@ -16,6 +16,9 @@ import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.RpcContextAttachment; import org.apache.dubbo.rpc.RpcContextAttachment;
import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.RpcServiceContext; import org.apache.dubbo.rpc.RpcServiceContext;
import org.springframework.core.env.Environment;
import java.net.SocketException;
/** /**
* @author 六如 * @author 六如
@@ -24,42 +27,24 @@ import org.apache.dubbo.rpc.RpcServiceContext;
@Activate(group = {CommonConstants.PROVIDER}) @Activate(group = {CommonConstants.PROVIDER})
public class DubboProviderTraceFilter implements Filter { public class DubboProviderTraceFilter implements Filter {
private Environment environment;
private String ip;
public void setEnvironment(Environment environment) {
this.environment = environment;
try {
this.ip = NetUtil.getIntranetIp();
} catch (SocketException e) {
throw new RuntimeException(e);
}
}
@Override @Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
initOpenContext(); DefaultOpenContext openContext = initOpenContext();
initWebContext(); DefaultWebContext webContext = initWebContext();
long startTime = System.currentTimeMillis();
long endTime = 0;
try {
Result result = invoker.invoke(invocation);
endTime = System.currentTimeMillis();
return result;
} finally {
trace(invocation, startTime, endTime);
}
}
private void initOpenContext() {
// 从 ServerAttachment 中读取的参数是从 Client 中传递过来的
RpcContextAttachment serverAttachment = RpcContext.getServerAttachment();
Object objectAttachment = serverAttachment.getObjectAttachment(SopConstants.OPEN_CONTEXT);
if (objectAttachment instanceof DefaultOpenContext) {
DefaultOpenContext openContext = (DefaultOpenContext) objectAttachment;
openContext.initContext();
}
}
private void initWebContext() {
RpcContextAttachment serverAttachment = RpcContext.getServerAttachment();
Object objectAttachment = serverAttachment.getObjectAttachment(SopConstants.WEB_CONTEXT);
if (objectAttachment instanceof DefaultWebContext) {
DefaultWebContext webContext = (DefaultWebContext) objectAttachment;
webContext.initContext();
}
}
private void trace(Invocation invocation, long startTime, long endTime) {
// 如果是服务提供端
RpcServiceContext serviceContext = RpcContext.getServiceContext(); RpcServiceContext serviceContext = RpcContext.getServiceContext();
// 获取客户端IP // 获取客户端IP
String fromIP = serviceContext.getRemoteHost(); String fromIP = serviceContext.getRemoteHost();
@@ -71,11 +56,54 @@ public class DubboProviderTraceFilter implements Filter {
String methodName = serviceContext.getMethodName(); String methodName = serviceContext.getMethodName();
// 调用参数值 // 调用参数值
String param = JSON.toJSONString(serviceContext.getArguments()); String param = JSON.toJSONString(serviceContext.getArguments());
// 超过500毫秒告警 String currentApp = environment.getProperty(SopConstants.SPRING_APPLICATION_NAME);
long spend = (endTime == 0 ? System.currentTimeMillis() : endTime) - startTime; String currentIp = this.ip;
if (log.isWarnEnabled() && spend > 500) { String traceId = openContext == null ? "" : openContext.getTraceId();
log.warn("[sop_trace][dubbo_server][time_warn] Dubbo 耗时告警({}ms), from={}({}), methodName={}.{}, param={}", if (log.isInfoEnabled()) {
spend, fromApp, fromIP, interfaceName, methodName, param); log.info("[dhf_trace][dubbo_server][{}] 收到请求, from={}({}) -> current={}({}), methodName={}.{}, param={}",
traceId, fromApp, fromIP, currentApp, currentIp, interfaceName, methodName, param);
}
long startTime = System.currentTimeMillis();
try {
return invoker.invoke(invocation);
} finally {
if (openContext != null) {
openContext.remove();
}
if (webContext != null) {
webContext.remove();
}
// 超过500毫秒告警
long spend = System.currentTimeMillis() - startTime;
if (log.isWarnEnabled() && spend > 500) {
log.warn("[dhf_trace][dubbo_server][time_warn][{}] Dubbo 耗时告警({}ms), from={}({}) -> current={}({}) , methodName={}.{}, param={}",
traceId, spend, fromApp, fromIP, currentApp, currentIp, interfaceName, methodName, param);
}
} }
} }
private DefaultOpenContext initOpenContext() {
// 从 ServerAttachment 中读取的参数是从 Client 中传递过来的
RpcContextAttachment serverAttachment = RpcContext.getServerAttachment();
Object objectAttachment = serverAttachment.getObjectAttachment(SopConstants.OPEN_CONTEXT);
if (objectAttachment instanceof DefaultOpenContext) {
DefaultOpenContext openContext = (DefaultOpenContext) objectAttachment;
openContext.initContext();
return openContext;
}
return null;
}
private DefaultWebContext initWebContext() {
RpcContextAttachment serverAttachment = RpcContext.getServerAttachment();
Object objectAttachment = serverAttachment.getObjectAttachment(SopConstants.WEB_CONTEXT);
if (objectAttachment instanceof DefaultWebContext) {
DefaultWebContext webContext = (DefaultWebContext) objectAttachment;
webContext.initContext();
return webContext;
}
return null;
}
} }

View File

@@ -0,0 +1,50 @@
package com.gitee.sop.support.util;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
/**
* @author 六如
*/
public class NetUtil {
/**
* 获取本机的内网ip地址
*
* @return 返回内网ip
* @throws SocketException 异常
*/
public static String getIntranetIp() throws SocketException {
String localip = null;// 本地IP如果没有配置外网IP则返回它
String netip = null;// 外网IP
Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
InetAddress ip = null;
boolean finded = false;// 是否找到外网IP
while (netInterfaces.hasMoreElements() && !finded) {
NetworkInterface ni = netInterfaces.nextElement();
Enumeration<InetAddress> address = ni.getInetAddresses();
while (address.hasMoreElements()) {
ip = address.nextElement();
if (!ip.isSiteLocalAddress()
&& !ip.isLoopbackAddress()
&& !ip.getHostAddress().contains(":")) {// 外网IP
netip = ip.getHostAddress();
finded = true;
break;
} else if (ip.isSiteLocalAddress()
&& !ip.isLoopbackAddress()
&& !ip.getHostAddress().contains(":")) {// 内网IP
localip = ip.getHostAddress();
}
}
}
if (netip != null && !"".equals(netip)) {
return netip;
} else {
return localip;
}
}
}