面试官,谈谈动态代理与RPC?我...

2023-03-07 09:47:07 浏览数 (2)

背景

RPC大家有一定了解后,在Java开发生态下,动态代理和它有着紧密联系。

如果单拎出动态代理,你一定会有一大堆八股文,它和RPC是什么关系?

一、使用场景

在使用RPC的时候,需要服务方提供interface,在调用方编写业务逻辑时,调用接口的方法,拿到结果。为什么?

RPC会为接口生成一个代理类,调用方在使用过程中,实际运行时该接口被调用会被代理类给拦截到,在代理类中具体实现远程调用逻辑。

这里其实就使用到了动态代理技术,场景描述如下,

通过这种hack手法,用户就不会感知远程调用的细节,实际就和调用本地方法一样。

二、Java动态代理

代码运行环境要求:open Jdk11

代码语言:javascript复制
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * interface
 */
interface HelloWorld {
    String speak();
}

/**
 * real object
 */
class RealHello {
    public String say() {
        return "i'm RealHello";
    }
}

/**
 * proxy
 */
class JdkProxy implements InvocationHandler {
    private final Object target;

    JdkProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] paramValues) {
        return ((RealHello) target).say();
    }
}

/**
 * TestProxy
 */
public class TestProxy {
    public static void main(String[] args) {
        JdkProxy jdkProxy = new JdkProxy(new RealHello());
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        // save proxy class
        System.setProperty("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true");
        // generate proxy object
        HelloWorld test = (HelloWorld) Proxy.newProxyInstance(classLoader, new Class[] {HelloWorld.class}, jdkProxy);
        // invoke proxy
        System.out.println(test.speak());
    }
}

本段代码的含义:HelloWorld接口生成一个代理类,并调用它的speak方法,返回的数据是RealHello的say方法返回值。

三、额外思考

如果没有动态代理那么如何完成方法调用拦截,实现RPC?

显而易见动态不行,就静态。但是静态有一个不好的地方,那就是需要针对性的为每个实现类创建一个代理类,并且需要写序列化、负载均衡、失败重试等等,上线一个 RPC调用的特性从一天可能就变成一周了。

对于RPC增加或修改接口的情况,动态代理无需修改,自适应协议的变化,而静态代理需要重新生成代码覆盖调用方和服务方。

如果是跨语言的类似GRPC的这种要怎么弄呢?对于动态代理,要么是各种reflect逻辑从服务提供方动态获取解析类型和数据,要么就构建一堆的硬编码,可以理解为通过模板动态生成支持适配协议的相关代码,这两个的代表在GRPC中是envoy和grpc-gateway。

小结

动态代理作为在RPC里面的一种应用,虽然只是具体实现技术,但理解了它才能更好的理解RPC里面是如何做到面向接口编程,帮助用户屏蔽RPC调用细节,达到远程调用。

动态代理本身是一种技术框架,在使用时,我们就需要有一个合理的选型,一般从框架生成代理类的速度、代理类字节码的大小、代理类的执行效率、框架的生态是否繁荣等去选择。

号外

平时小面周边很少能遇到持续日更的公众号作者,前两天在跟朋友吃饭的时候有幸结识了一位大佬,他叫少峰;

一个纯分享型大佬,互联网创业史15年,公司员工二百多人,公众号500多篇原创,写的都是关于创业的感悟和心得,从未收割过一个粉丝,真是佩服!

0 人点赞