dubbo source parsing remote call -- rmi protocol

Remote call rmi protocol

Objective: to introduce the design and implementation of rmi protocol and the source code of Dubbo RPC rmi.

Preface

dubbo supports RMI protocol, which is mainly implemented based on the org.springframework.remoting.rmi package encapsulated by spring. Of course, the most primitive is the java.rmi. * package that relies on the JDK standard, which adopts blocking short connection and JDK standard serialization. For the introduction of RMI protocol, please refer to the official documents of dubbo.

Address: http://dubbo.apache.org/zh-cn...

Source code analysis

(I) RmiRemoteInvocation

This class inherits RemoteInvocation, mainly adding the additional values required by dubbo itself on the basis of RemoteInvocation to avoid these additional values not being passed, in order to do some validation processing.

public class RmiRemoteInvocation extends RemoteInvocation {
    private static final long serialVersionUID = 1L;
    private static final String dubboAttachmentsAttrName = "dubbo.attachments";

    /**
     * executed on consumer side
     */
    public RmiRemoteInvocation(MethodInvocation methodInvocation) {
        super(methodInvocation);
        // Add dubbo added value attribute
        addAttribute(dubboAttachmentsAttrName, new HashMap<String, String>(RpcContext.getContext().getAttachments()));
    }

    /**
     * Need to restore context on provider side (Though context will be overridden by Invocation's attachment
     * when ContextFilter gets executed, we will restore the attachment when Invocation is constructed, check more
     * The context needs to be recovered on the provider side (although the context will be overwritten by the attachment of the Invocation
     * When ContextFilter executes, we will restore the attachment when constructing the Invocation, and check more
     * from {@link com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler}
     */
    @SuppressWarnings("unchecked")
    @Override
    public Object invoke(Object targetObject) throws NoSuchMethodException, IllegalAccessException,
            InvocationTargetException {
        // Get context
        RpcContext context = RpcContext.getContext();
        // Setting parameters
        context.setAttachments((Map<String, String>) getAttribute(dubboAttachmentsAttrName));
        try {
            return super.invoke(targetObject);
        } finally {
            // Empty parameters
            context.setAttachments(null);
        }
    }
}

(II) RmiProtocol

This class inherits the AbstractProxyProtocol class and is the core of rmi protocol implementation. Like other protocols, it also implements its own service exposure and service reference methods.

1.doExport

@Override
protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException {
    // rmi exposures
    final RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
    // Set port
    rmiServiceExporter.setRegistryPort(url.getPort());
    // Set service name
    rmiServiceExporter.setServiceName(url.getPath());
    // Setting up interfaces
    rmiServiceExporter.setServiceInterface(type);
    // Set up service implementation
    rmiServiceExporter.setService(impl);
    try {
        // Execute when initializing bean
        rmiServiceExporter.afterPropertiesSet();
    } catch (RemoteException e) {
        throw new RpcException(e.getMessage(), e);
    }
    return new Runnable() {
        @Override
        public void run() {
            try {
                // Destruction
                rmiServiceExporter.destroy();
            } catch (Throwable e) {
                logger.warn(e.getMessage(), e);
            }
        }
    };
}

This method is a logical implementation of service exposure.

2.doRefer

@Override
@SuppressWarnings("unchecked")
protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException {
    // FactoryBean for RMI proxy, supports traditional RMI service and RMI caller to create RmiProxyFactoryBean object
    final RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
    // RMI needs extra parameter since it uses customized remote invocation object
    // Testing version
    if (url.getParameter(Constants.DUBBO_VERSION_KEY, Version.getProtocolVersion()).equals(Version.getProtocolVersion())) {
        // Check dubbo version on provider, this feature only support
        // Set RemoteInvocationFactory for this accessor
        rmiProxyFactoryBean.setRemoteInvocationFactory(new RemoteInvocationFactory() {
            @Override
            public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
                // Custom call factories can add more context information to calls
                return new RmiRemoteInvocation(methodInvocation);
            }
        });
    }
    // Set the URL of the target service for this remote visitor. The URL must be compatible with the rules of a specific remoting provider.
    rmiProxyFactoryBean.setServiceUrl(url.toIdentityString());
    // Set the interface of the service to be accessed. The interface must be suitable for specific services and remoting strategies
    rmiProxyFactoryBean.setServiceInterface(serviceType);
    // Set whether to cache the RMI stub after it is found
    rmiProxyFactoryBean.setCacheStub(true);
    // Set whether to find RMI stubs at startup
    rmiProxyFactoryBean.setLookupStubOnStartup(true);
    // Set whether to refresh the RMI stub when the connection fails
    rmiProxyFactoryBean.setRefreshStubOnConnectFailure(true);
    // //Execute when initializing bean
    rmiProxyFactoryBean.afterPropertiesSet();
    return (T) rmiProxyFactoryBean.getObject();
}

This method is a logical implementation of the service reference.

Epilogue

Related source resolution address of this part: https://github.com/CrazyHZM/i...

This article explains the part about rmi protocol implementation in remote call, and the logic is relatively simple. Next, I will start to explain the section about thrift protocol of rpc module.

Keywords: Java Dubbo JDK Spring

Added by Riddick on Tue, 03 Dec 2019 17:55:55 +0200