一、RPC基础介绍
- RPC是实现跨服务之间的远程调用的过程,通过客户端发出请求访问服务端,服务端接收到请求返回给客户端的整个过程实现称为RPC,这一整个过程是通过RPC协议来实现的
- RPC是基于socket协议进行数据通讯的协议框架
- http协议是基于应用层的协议,而RPC是基于tcp/ip下三层的协议,所以RPC协议的传输会快于http协议的传输
二、RPC底层实现步骤
服务端:
1.首先创建服务端的接口及接口实现类(例:接口和类)
2.创建注册中心的接口及接口实现(Server,ServerImpl)
public interface Server {
//服务启动
void start();
//服务关闭
void stop();
//注册接口和接口实现
void register(Class service,Class serviceImpl);
}
public class ServerImpl implements Server {
private static HashMap<String,Class> serverRegister = new HashMap<String, Class>();
@Override
public void start() throws IOException {
//服务启动实现socket数据通讯
}
@Override
public void stop() {
//服务关闭
}
@Override
public void register(Class service,Class serviceImpl) {
//将接口及实现存入hashmap中
serverRegister.put(service.getName(),serviceImpl);
}
}
3.在ServerImpl类中引入线程池概念,将start()方法数据通讯通过多线程来实现
@Override
public void start() throws IOException {
//设置一个socket并绑定网络端口
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress(port));
System.out.println("开启服务。。。。");
while (true) {
try {
//接收客户端请求
Socket socket = serverSocket.accept();
//执行多线程,socket通讯内容将通过ThreadTask来实现
executor.execute(new ThreadTask(socket, serverRegister));
}catch (Exception e){
e.printStackTrace();
}
}
}
客户端:
1.定义client的类,来实现动态代理
public class Client{
/**
* 1.创建一个动态代理对象
* 2.传入接口,ip地址,端口
* 3.利用反射技术new MyInvocation()来实现socket数据通讯
*/
@SuppressWarnings("unchecked")
public static <T> T getRemoteProxyObj(Class serviceInterface, InetSocketAddress address){
return (T) Proxy.newProxyInstance(serviceInterface.getClassLoader(),new Class<?>[]{serviceInterface},
new MyInvocation(address,serviceInterface));
}
}
启动RPC服务端程序
public class RPCServerTest {
public static void main(String[] args) {
//创建服务中心实例
Server server = new ServerImpl(9999);
//将接口及接口实现添加到注册中心
server.register(Person.class,SayHello.class);
//启动注册中心服务
try {
server.start();
}catch (Exception e){
e.printStackTrace();
}
}
}
启动客户端程序实现RPC调用
public class RPCClientTest {
public static void main(String[] args) throws ClassNotFoundException {
Person say = Client.getRemoteProxyObj(Class.forName("com.yushi.rpcserver.Person"),new InetSocketAddress("127.0.0.1",9999));
System.out.println(say.getClass());
System.out.println(say.sayHello("henry"));
}
}
三、PRC调用逻辑及涉及知识点
逻辑:
1.服务端的接口及接口实现全部存入注册中心的hashmap
2.客户端通过动态代理来获取到服务端对应的接口实现类
3.客户端通过调用接口实现类方法来调用远程服务端方法获取到返回内容
知识点
1.动态代理、2.反射技术、3.socket协议通讯、4.序列化反序列化、5.多线程
四、代码实现地址
git@github.com:HenryXiaoPY/test.git