新增restful模式

This commit is contained in:
六如
2025-02-02 15:51:47 +08:00
parent 1f04edeaff
commit ddc709ede4
97 changed files with 1487 additions and 867 deletions

View File

@@ -28,7 +28,7 @@
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>3.2.10</version>
<version>3.2.16</version>
<optional>true</optional>
</dependency>
<dependency>

View File

@@ -1,6 +1,7 @@
package com.gitee.sop.support.context;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Locale;
@@ -8,8 +9,9 @@ import java.util.Locale;
/**
* @author 六如
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class DefaultOpenContext implements OpenContext, Serializable {
public class DefaultOpenContext extends OpenContext implements Serializable {
private static final long serialVersionUID = -3218354527911979685L;
/**
@@ -51,4 +53,8 @@ public class DefaultOpenContext implements OpenContext, Serializable {
* locale
*/
private Locale locale;
public void initContext() {
this.setContext(this);
}
}

View File

@@ -1,50 +1,61 @@
package com.gitee.sop.support.context;
import com.alibaba.ttl.TransmittableThreadLocal;
import java.util.Locale;
/**
* @author 六如
*/
public interface OpenContext {
public abstract class OpenContext {
private static final ThreadLocal<OpenContext> THREAD_LOCAL = new TransmittableThreadLocal<>();
/**
* 获取appId
*/
String getAppId();
public abstract String getAppId();
/**
* 获取apiName
*/
String getApiName();
public abstract String getApiName();
/**
* 获取version
*/
String getVersion();
public abstract String getVersion();
/**
* 获取token,没有返回null
*/
String getAppAuthToken();
public abstract String getAppAuthToken();
/**
* 获取客户端ip
*/
String getClientIp();
public abstract String getClientIp();
/**
* 获取回调地址
*/
String getNotifyUrl();
public abstract String getNotifyUrl();
/**
* 获取唯一请求id
*/
String getTraceId();
public abstract String getTraceId();
/**
* 获取locale
*/
Locale getLocale();
public abstract Locale getLocale();
protected void setContext(OpenContext openContext) {
THREAD_LOCAL.set(openContext);
}
public static OpenContext current() {
return THREAD_LOCAL.get();
}
}

View File

@@ -0,0 +1,70 @@
package com.gitee.sop.support.dubbo;
import com.alibaba.fastjson2.JSON;
import com.gitee.sop.support.context.DefaultOpenContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.RpcContextAttachment;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.RpcServiceContext;
/**
* @author 六如
*/
@Slf4j
@Activate(group = {CommonConstants.PROVIDER})
public class DubboProviderTraceFilter implements Filter {
private static final String OPEN_CONTEXT = "open.context";
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
initOpenContext();
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();
String attachment = serverAttachment.getAttachment(OPEN_CONTEXT);
if (attachment != null) {
DefaultOpenContext defaultOpenContext = JSON.parseObject(attachment, DefaultOpenContext.class);
defaultOpenContext.initContext();
}
}
private void trace(Invocation invocation, long startTime, long endTime) {
// 如果是服务提供端
RpcServiceContext serviceContext = RpcContext.getServiceContext();
// 获取客户端IP
String fromIP = serviceContext.getRemoteHost();
// 获取客户端应用名称
String fromApp = serviceContext.getRemoteApplicationName();
// 获取调用的接口
String interfaceName = invocation.getInvoker().getInterface().getName();
// 获取调用的方法
String methodName = serviceContext.getMethodName();
// 调用参数值
String param = JSON.toJSONString(serviceContext.getArguments());
// 超过500毫秒告警
long spend = (endTime == 0 ? System.currentTimeMillis() : endTime) - startTime;
if (log.isWarnEnabled() && spend > 500) {
log.warn("[sop_trace][dubbo_server][time_warn] Dubbo 耗时告警({}ms), from={}({}), methodName={}.{}, param={}",
spend, fromApp, fromIP, interfaceName, methodName, param);
}
}
}

View File

@@ -11,6 +11,8 @@ import lombok.Data;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.lang.reflect.Method;
@@ -34,6 +36,12 @@ public class ApiRegister {
private static final Log LOG = LogFactory.getLog(ApiRegister.class);
/**
* Spring自带的参数提取工具类
*/
private static final DefaultParameterNameDiscoverer DISCOVERER = new DefaultParameterNameDiscoverer();
private final ApiRegisterService apiRegisterService;
public ApiRegister(ApiRegisterService apiRegisterService) {
@@ -106,7 +114,7 @@ public class ApiRegister {
List<ParamInfo> paramInfos = buildParamInfo(method);
RegisterDTO registerDTO = new RegisterDTO();
registerDTO.setApplication(appName);
registerDTO.setApiName(open.value());
registerDTO.setApiName(getApiName(open));
registerDTO.setApiVersion(open.version());
registerDTO.setInterfaceClassName(interfaceClass.getName());
registerDTO.setMethodName(method.getName());
@@ -125,6 +133,10 @@ public class ApiRegister {
}
}
protected String getApiName(Open open) {
return StringUtils.trimLeadingCharacter(open.value(), '/');
}
private List<ParamInfo> buildParamInfo(Method method) {
Parameter[] parameters = method.getParameters();
if (parameters.length == 0) {

View File

@@ -0,0 +1 @@
dubboProviderTraceFilter=com.gitee.sop.support.dubbo.DubboProviderTraceFilter