利用dubbo的Filter记录入参、出参及规范返回参数

需求场景: 基于服务治理的原则,公司重构了很多项目,其中使用了dubbo作为服务框架。作为底层的服务存在,由上层的业务系统进行服务的编排。一是为了系统之间的解耦,同时系统之间也能更好的交互。


其他依赖:springboot,JDK8

目前的需求是,上层业务系统在调用底层的服务的时候,底层系统需要记录全部的入参、出参和处理耗时。第二是统一返回格式,不向上抛出异常。最开始打算使用Spring aop 进行切面处理。发现 dubbo 和 aop有冲突,网上的解决方案有两种,一种是更改dubbo底层的源码,二是调整切入逻辑。两种方案都不满意,查询资料,发现dubbo 提供filter 拦截。



代码。。。。。。

返回类

public class ResponseMessage<T> implements Serializable {

	public ResponseMessage() {

	}

	public ResponseMessage(boolean status, String statusCode, String message, T result) {
		this.status = status;
		this.statusCode = statusCode;
		this.message = message;
		this.result = result;
	}

	private boolean status;
	
	private String statusCode;
	
	private String message;
	
	private T result;

	public boolean isStatus() {
		return status;
	}

	public void setStatus(boolean status) {
		this.status = status;
	}

	public String getStatusCode() {
		return statusCode;
	}

	public void setStatusCode(String statusCode) {
		this.statusCode = statusCode;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public T getResult() {
		return result;
	}

	public void setResult(T result) {
		this.result = result;
	}

}
业务层返回

public class UserCenterResponse<T> extends ResponseMessage<T>
{

    /**
     * 意义,目的和功能,以及被用到的地方<br>
     */
    private static final long serialVersionUID = -1490267187174046793L;

    

}

代理类

public interface IUserCenterOperation
{
    UserCenterResponse<BaseUser> findUserByid(Long userId);
}

实现

import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Service;
import com.zto.webUserCenter_userOpera.dto.UserCenterResponse;
import com.zto.webUserCenter_userOpera.dto.BaseUser;
import com.zto.webUserCenter_userOpera.manager.FindUserById;
import com.zto.webUserCenter_userOpera.service.IUserCenterOperation;


@Service(group = "userCenterOperation", timeout = 1000, version = "1.0",filter="dubboServiceFilter")
public class UserCenterOperation implements IUserCenterOperation
{

    @Autowired
    private FindUserById findUserById;

    @Override
    public UserCenterResponse<BaseUser> findUserByid(Long userId)
    {
        UserCenterResponse<BaseUser> res = null;
        res = findUserById.exce(userId);
	// 业务实现,可替换
        return res;
    }
}


filter

@Activate
public class DubboServiceFilter implements Filter
{

    private final static Logger logger = LoggerFactory.getLogger(DubboServiceFilter.class);

    public Result invoke(Invoker<?> invoker, Invocation invocation)
    {
        Result result = null;
        Long takeTime = 0L;
        try
        {
            Long startTime = System.currentTimeMillis();
            result = invoker.invoke(invocation);
            if (result.getException() instanceof Exception)
            {
                throw new Exception(result.getException());
            }
            takeTime = System.currentTimeMillis() - startTime;
        }
        catch (Exception e)
        {
            logger.error("Exception:{},request{},curr error:{},msg:{}", invocation.getClass(),
                invocation.getArguments(), e.toString(), ExceptionUtils.getRootCause(e));
            result = new RpcResult(ServiceUtils.getResponse(e));
            return result;
        }
        finally
        {
            logger.info("method:[{}],request:{},response:{},takeTime:{} ms",
                invocation.getMethodName(), invocation.getArguments(), JsonUtil.toJSON(result),
                takeTime);
        }
        return result;
    }
}

返回值处理类

public class ServiceUtils
{
    public static <T> UserCenterResponse<T> getResponse(T t)
    {

        UserCenterResponse<T> response = new UserCenterResponse<T>();
        // 处理自定义异常返回
        if (t instanceof UserCenterException)
        {
            response.setMessage(((UserCenterException)t).getExceptionEnums().getMessage());
            response.setStatusCode(((UserCenterException)t).getExceptionEnums().getCode());
            response.setStatus(false);
        }
        // 处理未知异常
        else if (t instanceof Exception)
        {
            response.setMessage(DBExceptionEnums.UNKNOWN_ERROR.getMessage());
            response.setStatusCode(DBExceptionEnums.UNKNOWN_ERROR.getCode());
            response.setStatus(false);
        }
        // 正常返回
        else
        {
            response.setStatusCode("200");
            response.setStatus(true);
            response.setResult(t);
        }

        return response;
    }
}



dubbo 配置文件参考  :https://www.cnblogs.com/Alandre/p/6490142.html

详细 阐述下 关于filter 配置。

在resources中创建文件

  1. META-INF/dubbo/com.alibaba.dubbo.rpc.Filter  




内容:dubboServiceFilter=com.zto.webUserCenter_userOpera.aop.DubboServiceFilter


application.properties 配置 添加
dubbo.provider.filter =dubboServiceFilter 


参考资料:

Springboot 整合 Dubbo/ZooKeeper 详解 SOA 案例

dubbo中文文档

被事务代理的spring service 不能使用注解方式发布dubbo服务的问题解决

修复dubbo注解与spring aop冲突的问题

Dubbo之——Dubbo Filter实战

----------------------------------------------------------------------------------------------------------

代码 还有点乱,有还有优化的空间


dubboServiceFilter 
相关文章

相关标签/搜索