zeus00456

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

dubbox 与 dubbo 兼容的改造

改造位置

不兼容是由 dubbox 与 dubbo 序列化方式不一致导致的,所以改造的也是重新适配序列化
这包括两个部分,encoding / decoding

改造方式

最先尝试最简单的思路:

  • 高低版本之间的 dubbo2 是兼容的
  • 低版本 Dubbo2 与dubbox 之间也是兼容的

那就把低版本的 dubbo2 的逻辑拿出来,加入到 dubbox 里,做一个版本识别

代码

序列化编码位置
com.alibaba.dubbo.rpc.protocol.dubbo.DubboCodec#encodeRequestData

    @Override
    protected void encodeRequestData(Channel channel, ObjectOutput out, Object data) throws IOException {
        RpcInvocation inv = (RpcInvocation) data;

        out.writeUTF(inv.getAttachment(Constants.DUBBO_VERSION_KEY, DUBBO_VERSION));
        out.writeUTF(inv.getAttachment(Constants.PATH_KEY));
        out.writeUTF(inv.getAttachment(Constants.VERSION_KEY));

        out.writeUTF(inv.getMethodName());

        if (inv.isDubbox()){
	        if (getSerialization(channel) instanceof OptimizedSerialization && !containComplexArguments(inv)) {
	            out.writeInt(inv.getParameterTypes().length);
	        } else {
	            out.writeInt(-1);
	            out.writeUTF(ReflectUtils.getDesc(inv.getParameterTypes()));
	        }
        }else {//低版本
            out.writeUTF(ReflectUtils.getDesc(inv.getParameterTypes()));
        }

        Object[] args = inv.getArguments();
        if (args != null)
            for (int i = 0; i < args.length; i++){
                out.writeObject(encodeInvocationArgument(channel, inv, i));
            }
        out.writeObject(inv.getAttachments());
    }

序列化解码位置
com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation#decode

    public Object decode(Channel channel, InputStream input) throws IOException {
        ObjectInput in = CodecSupport.getSerialization(channel.getUrl(), serializationType)
                .deserialize(channel.getUrl(), input);

        try {
            setAttachment(Constants.DUBBO_VERSION_KEY, in.readUTF());
            setAttachment(Constants.PATH_KEY, in.readUTF());
            setAttachment(Constants.VERSION_KEY, in.readUTF());

            setMethodName(in.readUTF());
            try {
                Object[] args;
                Class<?>[] pts;
                if (isDubbox()){
	                // NOTICE modified by lishen
	                int argNum = in.readInt();
	                if (argNum >= 0) {
	                    if (argNum == 0) {
	                        pts = DubboCodec.EMPTY_CLASS_ARRAY;
	                        args = DubboCodec.EMPTY_OBJECT_ARRAY;
	                    } else {
	                        args = new Object[argNum];
	                        pts = new Class[argNum];
	                        for (int i = 0; i < args.length; i++) {
	                            try {
	                                args[i] = in.readObject();
	                                pts[i] = args[i].getClass();
	                            } catch (Exception e) {
	                                if (log.isWarnEnabled()) {
	                                    log.warn("Decode argument failed: " + e.getMessage(), e);
	                                }
	                            }
	                        }
	                    }
	                } else {
	                    String desc = in.readUTF();
	                    if (desc.length() == 0) {
	                        pts = DubboCodec.EMPTY_CLASS_ARRAY;
	                        args = DubboCodec.EMPTY_OBJECT_ARRAY;
	                    } else {
	                        pts = ReflectUtils.desc2classArray(desc);
	                        args = new Object[pts.length];
	                        for (int i = 0; i < args.length; i++) {
	                            try {
	                                args[i] = in.readObject(pts[i]);
	                            } catch (Exception e) {
	                                if (log.isWarnEnabled()) {
	                                    log.warn("Decode argument failed: " + e.getMessage(), e);
	                                }
	                            }
	                        }
	                    }
	                }
                } else {//低版本
                    String desc = in.readUTF();
                    if (desc.length() == 0) {
                        pts = DubboCodec.EMPTY_CLASS_ARRAY;
                        args = DubboCodec.EMPTY_OBJECT_ARRAY;
                    } else {
                        pts = ReflectUtils.desc2classArray(desc);
                        args = new Object[pts.length];
                        for (int i = 0; i < args.length; i++) {
                            try {
                                args[i] = in.readObject(pts[i]);
                            } catch (Exception e) {
                                if (log.isWarnEnabled()) {
                                    log.warn("Decode argument failed: " + e.getMessage(), e);
                                }
                            }
                        }
                    }
                }
                setParameterTypes(pts);

                Map<String, String> map = (Map<String, String>) in.readObject(Map.class);
                if (map != null && map.size() > 0) {
                    Map<String, String> attachment = getAttachments();
                    if (attachment == null) {
                        attachment = new HashMap<String, String>();
                    }
                    attachment.putAll(map);
                    setAttachments(attachment);
                }
                //decode argument ,may be callback
                for (int i = 0; i < args.length; i++) {
                    args[i] = decodeInvocationArgument(channel, this, pts, i, args[i]);
                }

                setArguments(args);

            } catch (ClassNotFoundException e) {
                throw new IOException(StringUtils.toString("Read invocation data failed.", e));
            }
        } finally {
            // modified by lishen
            if (in instanceof Cleanable) {
                ((Cleanable) in).cleanup();
            }
        }
        return this;
    }

版本判断
com.alibaba.dubbo.rpc.RpcInvocation#isDubbox

    public boolean isDubbox(){
        return dubbox || DubboxJudgeUtils.judeByVersion(getAttachments().get(Constants.DUBBO_VERSION_KEY));
    }
posted on 2026-07-02 10:22  问仙长何方蓬莱  阅读(3)  评论(0)    收藏  举报