简单的rpc实现

1.什么是rpc?

RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。

                               

client functions:客户端,请求发送端

client stub:客户端句柄,主要是获取请求的相关数据信息,比如调用的接口名,参数名,参数类型,以及对信息进行序列化,通过socket发送到服务端;

server stub:服务端句柄,主要将client发来的请求信息进行读取并反序列化,然后通过这些信息调用具体的实现类,并将结果序列化后通过sock发送到client。


2.rpc用到什么技术?

(1)JAVA 动态代理(cglib或jdk的proxy类)

(2)socket通信,涉及到IO(io,NIO)

  (3) JAVA序列化

3 rpc架构

RPC架构分为三部分:

(1)服务提供者,运行在服务器端,提供服务接口定义与服务实现类。

(2)服务中心,运行在服务器端,负责将本地服务发布成远程服务,管理远程服务,提供给服务消费者使用。

(3)服务消费者,运行在客户端,通过远程代理对象调用远程服务。


4简单rpc实现代码

====================================================================

                                                                服务端

====================================================================

服务端业务处理类:

package com.axj.server;

import java.io.*;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.HashMap;

/**
 * \* Created with IntelliJ IDEA.
 * \* User: axj
 * \* Date: 2018/6/14
 * \* Time: 14:46
 * \* Description:
 * \
 */
public class ServerTask implements Runnable {
    private Socket socket = null;
    private  HashMap<String,Class> serviceRegistry;

    public ServerTask(Socket socket, HashMap<String, Class> serviceRegistry) {
        this.socket=socket;
        this.serviceRegistry=serviceRegistry;
    }

    @Override
    public void run() {
        ObjectOutputStream outputStream =null;
        ObjectInputStream  inputStream=null;
        try {
            inputStream = new ObjectInputStream(socket.getInputStream());
            String serviceName=inputStream.readUTF();
            String serviceMethod=inputStream.readUTF();
            Class<?>[] parameterTypes = (Class<?>[]) inputStream.readObject();
            Object[] arguments = (Object[]) inputStream.readObject();

            Class serviceClass=serviceRegistry.get(serviceName);
            if (serviceClass == null) {
                throw new ClassNotFoundException(serviceName + " not found");
            }
            Method method=serviceClass.getMethod(serviceMethod,parameterTypes);
            Object object=method.invoke(serviceClass.newInstance(),arguments);
            //
            // 3.将执行结果反序列化,通过socket发送给客户端
            outputStream = new ObjectOutputStream(socket.getOutputStream());
            outputStream.writeObject(object);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

服务端类ServerSocket:

package com.axj.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * \* Created with IntelliJ IDEA.
 * \* User: xxx
 * \* Date: 2018/6/14
 * \* Time: 14:40
 * \* Description:
 * \
 */
public  class RpcServer {
    private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
    private  int port;
    private  String ip;
    public  RpcServer(String ip,int port){
         this.port=port;
         this.ip=ip;
    }

    private static final HashMap<String, Class> serviceRegistry = new HashMap<String, Class>();

    public void register(Class serviceInterface, Class impl) {
        serviceRegistry.put(serviceInterface.getName(), impl);
    }
    //
    public void start() throws IOException {
        ServerSocket serverSocket= new ServerSocket();

        serverSocket.bind(new InetSocketAddress(ip,port));
        
        // 1.监听客户端的TCP连接,接到TCP连接后将其封装成task,由线程池执行
        while (true){
            Socket socket=serverSocket.accept();
            executor.execute(new ServerTask(socket,serviceRegistry));
        }
    }
}

服务端启动类:

public class RpcServerTest {
    public static void main(String[] args) {
        try {
            RpcServer rpcServer=new RpcServer("localhost",8088);
            rpcServer.register(HelloService.class, HelloServiceImpl.class);
            rpcServer.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

=====================================================================

                                                                客户端

=====================================================================

客户端动态代理类:

package com.axj.client;

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

/**
 * \* Created with IntelliJ IDEA.
 * \* User: axj
 * \* Date: 2018/6/14
 * \* Time: 14:28
 * \* Description:
 * \
 */
public class RpcClientPoxy {

    public static Object getRemoteProxyObj(final Class<?> serviceInterface,final  InetSocketAddress addr) {
        return Proxy.newProxyInstance(serviceInterface.getClassLoader(), new Class[]{serviceInterface}, new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] args) throws Throwable {
                Socket socket=null;
                ObjectOutputStream outputStream=null;
                ObjectInputStream inputStream=null;
                Object object=null;
                try {
                     socket=new Socket();
                     socket.connect(addr);

                     outputStream=new ObjectOutputStream(socket.getOutputStream());
                     outputStream.writeUTF(serviceInterface.getName());
                     outputStream.writeUTF(method.getName());
                     outputStream.writeObject(method.getParameterTypes());
                     outputStream.writeObject(args);

                     inputStream=new ObjectInputStream(socket.getInputStream());
                     object=inputStream.readObject();
                }catch (Exception e){
                     e.printStackTrace();
                } finally {
                    if (socket != null) socket.close();
                    if (outputStream != null) outputStream.close();
                    if (inputStream != null) inputStream.close();
                }
                return  object;
            }
        });
    }
}

客户端Socket

package com.axj;

import com.axj.client.RpcClientPoxy;
import com.axj.service.HelloService;

import java.net.InetSocketAddress;

/**
 * \* Created with IntelliJ IDEA.
 * \* User: axj
 * \* Date: 2018/6/14
 * \* Time: 15:38
 * \* Description:
 * \
 */
public class RpcClientTest {
    public static void main(String[] args) {
        HelloService helloService= (HelloService) RpcClientPoxy.getRemoteProxyObj(HelloService.class, new InetSocketAddress("localhost",8088));
        System.out.println(helloService.sayHeelo("xxxxxxx"));

        System.out.println(helloService.sayBye());
    }
}

远程service接口

public interface HelloService {
    String  sayHeelo(String string);

    String  sayBye();
}

远程service接口实现类

public class HelloServiceImpl implements  HelloService {
    @Override
    public String sayHeelo(String string) {
        System.out.println(string);
        return string;
    }

    @Override
    public String sayBye() {
        System.out.println("bye bye");
        return "bye bye" ;
    }
}

展开阅读全文

没有更多推荐了,返回首页