Skip to content

Commit

Permalink
feat: ✨ 增加dubbo模块
Browse files Browse the repository at this point in the history
  • Loading branch information
fxbin committed Nov 27, 2023
1 parent 86c736e commit 6211929
Show file tree
Hide file tree
Showing 8 changed files with 271 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?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>bubble-spring-boot-starters</artifactId>
<groupId>cn.fxbin.bubble</groupId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>bubble-spring-boot-starter-dubbo</artifactId>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>cn.fxbin.bubble</groupId>
<artifactId>bubble-spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-observability-starter</artifactId>
</dependency>

<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>

<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-native</artifactId>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package cn.fxbin.bubble.dubbo.constant;

/**
* DubboConst
*
* @author fxbin
* @version v1.0
* @since 2023/11/8 11:27
*/
public interface DubboConst {

/**
* code
*/
String CODE = "code";

/**
* 信息
*/
String MSG = "msg";

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package cn.fxbin.bubble.dubbo.filter;

import cn.fxbin.bubble.core.exception.ServiceException;
import cn.fxbin.bubble.core.util.StringUtils;
import cn.fxbin.bubble.dubbo.constant.DubboConst;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import java.util.Map;

/**
* DubboConsumerExceptionFilter
*
* @author fxbin
* @version v1.0
* @since 2023/11/8 11:27
*/
@Slf4j
@Activate(group = {CommonConstants.CONSUMER})
public class DubboConsumerExceptionFilter implements Filter, Filter.Listener {

@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
return invoker.invoke(invocation);
}

@Override
public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
Map<String, String> attach = appResponse.getAttachments();
String code = attach.get(DubboConst.CODE);
String msg = attach.get(DubboConst.MSG);
if (StringUtils.isNotEmpty(code)) {
appResponse.setException(new ServiceException(Integer.parseInt(code), msg));
}
}

@Override
public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {
log.error("Got unchecked and undeclared exception which called by " + RpcContext.getServiceContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + t.getClass().getName() + ": " + t.getMessage(), t);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package cn.fxbin.bubble.dubbo.filter;

import cn.fxbin.bubble.core.dataobject.GlobalErrorCode;
import cn.fxbin.bubble.core.exception.ServiceException;
import cn.fxbin.bubble.core.util.ExceptionUtils;
import cn.fxbin.bubble.dubbo.constant.DubboConst;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.service.GenericService;

import java.lang.reflect.Type;
import java.util.Map;

/**
* DubboProviderExceptionFilter
*
* @author fxbin
* @version v1.0
* @since 2023/11/9 15:09
*/
@Slf4j
@Activate(group = CommonConstants.PROVIDER)
public class DubboProviderExceptionFilter implements Filter, BaseFilter.Listener {

@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
return invoker.invoke(invocation);
}

@Override
public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
if (appResponse.hasException() && GenericService.class != invoker.getInterface()) {
try {
// 1. 转换异常
Throwable exception = appResponse.getException();
// 1.1 参数校验异常
if (exception instanceof ConstraintViolationException) {
exception = this.constraintViolationExceptionHandler((ConstraintViolationException) exception);
// 1. ServiceException 业务异常,因为不会有序列化问题,所以无需处理
} else {
exception = this.defaultExceptionHandler(exception, invocation);
Map<String, String> attachments = appResponse.getAttachments();
attachments.put(DubboConst.CODE, String.valueOf(((ServiceException) exception).getErrcode()));
attachments.put(DubboConst.MSG, ((ServiceException) exception).getErrmsg());
}

// 2. 根据不同的方法 schema 返回结果
// 2.1 如果是 ServiceException 异常,并且返回参数类型是 Result 的情况,则将转换成 Result 返回
if (isReturnCommonResult(invocation) && exception instanceof ServiceException) {
// 一定要清空异常
appResponse.setException(null);
appResponse.setValue(cn.fxbin.bubble.core.dataobject.Result.failure((ServiceException) exception));
// 2.2 如果是 GlobalException 全局异常,则直接抛出
} else {
appResponse.setException(exception);
appResponse.getAttachments();
}
} catch (Throwable e) {
log.warn("Fail to ExceptionFilter when called by " + RpcContext.getServiceContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
}
}
}

@Override
public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {
log.error("Got unchecked and undeclared exception which called by " + RpcContext.getServiceContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + t.getClass().getName() + ": " + t.getMessage(), t);
}

private boolean isReturnCommonResult(Invocation invocation) {
if (!(invocation instanceof RpcInvocation)) {
return false;
}
RpcInvocation rpcInvocation = (RpcInvocation) invocation;
Type[] returnTypes = rpcInvocation.getReturnTypes();
if (returnTypes.length == 0) {
return false;
}
Type returnType = returnTypes[0];
if (!(returnType instanceof Class)) {
return false;
}
Class returnClass = (Class) returnType;
return returnClass == Result.class;
}

/**
* 处理 Validator 校验不通过产生的异常
*/
private ServiceException constraintViolationExceptionHandler(ConstraintViolationException ex) {
log.warn("[constraintViolationExceptionHandler]", ex);
ConstraintViolation<?> constraintViolation = ex.getConstraintViolations().iterator().next();
return new ServiceException(GlobalErrorCode.BAD_REQUEST.value(),
String.format("请求参数不正确:%s", constraintViolation.getMessage()));
}

/**
* 处理系统异常,兜底处理所有的一切
*/
private ServiceException defaultExceptionHandler(Throwable exception, Invocation invocation) {
log.error("[defaultExceptionHandler][service({}) method({}) params({}) 执行异常] ===> {}",
invocation.getTargetServiceUniqueName(), invocation.getMethodName(), invocation.getArguments(), ExceptionUtils.getStackTrace(exception));
// 如果已经是 ServiceException 全局异常,直接返回即可
if (exception instanceof ServiceException) {
return (ServiceException) exception;
}
return new ServiceException(GlobalErrorCode.INTERNAL_SERVER_ERROR);
}

private String buildDetailMessage(Throwable exception, Invocation invocation) {
return String.format("Service(%s) Method(%s) 发生异常(%s)",
invocation.getTargetServiceUniqueName(), invocation.getMethodName(), ExceptionUtils.getStackTrace(exception));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package cn.fxbin.bubble.dubbo;
1 change: 1 addition & 0 deletions bubble-spring-boot-starters/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<module>bubble-spring-boot-starter-dynamic-threadpool</module>
<module>bubble-spring-boot-starter-i18n</module>
<module>bubble-spring-boot-starter-mail</module>
<module>bubble-spring-boot-starter-dubbo</module>
</modules>


Expand Down

0 comments on commit 6211929

Please sign in to comment.