基于TCP的RPC

来源:互联网 发布:申请淘宝商家披露信息 编辑:程序博客网 时间:2024/05/22 21:49

《大型分布式网站架构设计与实践》

RPC名词解释

RPC即远程过程调用,单台服务器的处理能力受到硬件成本的限制,不可能无限制的提升。RPC就将原来的本地调用转变为调用远端服务器的方法,给系统的处理能力和吞吐量带来了近似于无限提升的可能。

RPC的实现包括客户端和服务端,即服务调用方、服务提供方。

随着业务的增加,不同的服务之间需要进行分组以隔离不同的业务,避免相互影响,这样,服务器的路由和负载均衡则成为必须要考虑的问题。


对象序列化

数据在网络上进行传输就要转化为二进制流。(这里使用java api)

import java.io.Serializable;/** * Created by yangenneng on 2017-02-17. * 功能说明: */public class Person implements Serializable {    private String name;    private String password;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public Person(){        this.name="zhangsan";        this.password="123456";    }}import java.io.*;/** * Created by yangenneng on 2017-02-17. * 功能说明: */public class ByteDemo {    public static void main(String[] args) throws IOException, ClassNotFoundException {        Person zhansan=new Person();        //字节数组输出流        ByteArrayOutputStream os=new ByteArrayOutputStream();        ObjectOutputStream out=new ObjectOutputStream(os);//对象输出流        out.writeObject(zhansan);//将对象写入字节数组输出,进行序列化        byte[] zhansanByte=os.toByteArray();        System.out.println("-------------------"+zhansanByte+"----------------------------");        //字节数组输入流        ByteArrayInputStream is=new ByteArrayInputStream(zhansanByte);        //执行反序列化,从流中读取对象        ObjectInputStream in=new ObjectInputStream(is);        Person lisi= (Person) in.readObject();        System.out.println("-------------------"+lisi.getName()+" "+lisi.getPassword()+"----------------------------");    }}

这里写图片描述


基于TCP协议实现RPC

客户端想去的接口的名称、需要调用的方法和需要传递的参数,并通过Socket将其发送到服务提供方,等待服务相应结果。
服务提供端事先将实例化好后放在serviers这个Map中,通过while循环,并不断的接受收到的消息,得到所需要的方法,执行后将结果返回给服务的消费者。

package rpc;/** * Created by yangenneng on 2017-02-17. * 功能说明:问好的接口 */public interface SayHelloService {    public String sayHello(String str);}package rpc;/** * Created by yangenneng on 2017-02-17. * 功能说明: */public class SayHelloServiceImpl implements SayHelloService {    @Override    public String sayHello(String str) {        return str.equals("hello") ? "Hello" : "Bye";    }}package rpc;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.lang.reflect.Method;import java.net.Socket;/** * Created by yangenneng on 2017-02-17. * 功能说明:服务请求者 */public class Consumer {    public static void main(String[] args) throws NoSuchMethodException, IOException, ClassNotFoundException {        //接口名称        String interfacename=SayHelloService.class.getName();        //需要远程执行的方法        Method method=SayHelloService.class.getMethod("sayHello",java.lang.String.class);        //需要传递到服务端的参数        Object[] arguments={"hello"};        Socket socket=new Socket("127.0.0.1",10001);        //将方法名称和参数传递到远端        ObjectOutputStream output=new ObjectOutputStream(socket.getOutputStream());        output.writeUTF(interfacename);//接口名称        output.writeUTF(method.getName());//方法名称        output.writeObject(method.getParameterTypes());        output.writeObject(arguments);        //从远端读取方法执行结果        ObjectInputStream input=new ObjectInputStream(socket.getInputStream());        Object result=input.readObject();    }}package rpc;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.net.ServerSocket;import java.net.Socket;import java.util.HashMap;import java.util.Map;/** * Created by yangenneng on 2017-02-17. * 功能说明:服务提供者 */public class Provider {    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {        ServerSocket server=new ServerSocket(10001);        Map services=new HashMap();        services.put(SayHelloService.class.getName(),new SayHelloServiceImpl());        while (true){            Socket socket=server.accept();            //读取服务信息            ObjectInputStream input=new ObjectInputStream(socket.getInputStream());            String interfacename=input.readUTF();//接口名称            String methodName=input.readUTF();//方法名称            Class<?>[] parameterTypes=(Class<?>[])input.readObject();//参数类型            Object[] arguments= (Object[]) input.readObject();//参数对象            //执行调用            Class serviceinterfaceclass=Class.forName(interfacename);//得到接口的class            Object service=services.get(interfacename);//取得服务实现的对象            Method method=serviceinterfaceclass.getMethod(methodName,parameterTypes);            Object result=method.invoke(service,arguments);            ObjectOutputStream output=new ObjectOutputStream(socket.getOutputStream());            output.writeObject(result);        }    }}

在生产环境中,常常是多个客户端同时发送多个请求到服务端,服务端
则需要同时接收和处理多个客户端请求,涉及并发处理、服务路由、负载均衡等问题。

0 0