实现最简单的RPC框架-《架构探险-从零开始写分布式服务框架》读书笔记

本文介绍了一种基于Java的远程过程调用(RPC)实现方案,通过客户端和服务端的交互,实现了跨进程的服务调用。具体包括客户端动态代理的创建、服务端方法反射调用的实现,以及网络通信细节。

整体结构:
这里写图片描述

代码如下:

public interface HelloService {
    public String sayHello(String content);
}
public class HelloServiceImpl implements HelloService {

    @Override
    public String sayHello(String content) {
        return "hello,"+content;
    }
}
package framework;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;

/**
 * 接口的代理类
 *
 * @author zhangna
 * @date 2018-03-22
 */
public class ConsumerProxy {
    public static <T> T consume(final Class<T> interfaceClass, final String host, final int port) throws Exception{
        //使用动态代理
        return (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //socket客户端
                        Socket socket = new Socket(host, port);
                        try{
                            //发送方法名和参数
                            ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
                            try{
                                output.writeUTF(method.getName());
                                output.writeObject(args);
                                //接收调用后返回的结果
                                ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
                                try{
                                    Object result = input.readObject();
                                    return result;
                                }finally {
                                    input.close();
                                }
                            }finally {
                                output.close();
                            }
                        }finally {
                            socket.close();
                        }
                    }
                });
    }
}

package framework;

import org.apache.commons.lang3.reflect.MethodUtils;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 提供接口调用的类
 *
 * @author zhangna
 * @date 2018-03-22
 */
public class ProviderReflect {
    private static final ExecutorService excutorService = Executors.newCachedThreadPool();
    public static void provider(final Object serviceImpl, int port) throws Exception{
        //socket服务端
        ServerSocket serverSocket = new ServerSocket(port);
        while(true){
            final Socket socket = serverSocket.accept();
            excutorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
                        try{
                            try{
                                //socket接收参数
                                String methodName = input.readUTF();
                                Object[] args = (Object[]) input.readObject();
                                ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
                                try{
                                    //使用java反射方法,根据方法名和参数调用实现类
                                    Object result = MethodUtils.invokeExactMethod(serviceImpl,methodName,args);
                                    //socket发送调用结果
                                    output.writeObject(result);
                                }catch (Throwable t){
                                    output.writeObject(t);
                                } finally {
                                    output.close();
                                }
                            }catch (Exception e){
                                e.printStackTrace();
                            }finally {
                                input.close();
                            }
                        }finally {
                            socket.close();
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}
public class RpcProvideMain {
    public static void main(String[] args) throws Exception{
        //实际调用的方法
        HelloService serviceImpl = new HelloServiceImpl();
        //启动服务端
        ProviderReflect.provider(serviceImpl,8083);
    }
}
public class RpcConsumerMain {
    public static void main(String[] args) throws Exception{
        //获得HelloService接口的代理类的实例
        HelloService serviceProxy = ConsumerProxy.consume(HelloService.class,"127.0.0.1",8083);
        //使用代理远程调用
        for (int i=0; i<100; i++){
            String hello = serviceProxy.sayHello("test_"+i);
            System.out.println(hello);
            Thread.sleep(1000);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值