rpc介绍
首先说下为什么需要rpc:【RPC】为什么需要RPC,而不是简单的HTTP接口_小鱼菜鸟的博客-CSDN博客
rpc的出现:随着项目越来越大,访问量越来越大,为了突破性能瓶颈,需要将项目拆分成多个部分,这样比起传统的项目都是本地内存调用,分布式的项目之间需要在网络间进行通信
服务之间的远程调用通常有两种方式,即基于TCP的远程调用和基于Http的远程调用
基于TCP的RPC实现
主要是服务提供方定义socket端口和提供的方法名称已经需要的参数结构,服务调用方通过连接服务方的socket端口,进而调用相关方法,并且将需要通信的数据作为参数传递,需要值得注意的是参数在传递的时候需要在服务调用端进行序列化然后在服务提供端进行反序列化,是netty之间的通信方式,基于tcp的远程调用
基于HTTP的RPC实现
对于RPC的HTTP实现,与现在的restful风格很类似,主要是在服务调用方通过标识请求,GET,POST然后通过url来定位到服务提供方提供的服务,数据通过xml或者json来传输,省去了TCP的序列化和反序列化
区别
基于socket通信的RPC,在协议层面处于较底层,优点是传输效率高,但是开发难度相对较高,而HTTP在应用层处于较高层面,开发难度相对较小,不用维护socket端口和数据序列化相关问题,但是传输效率比起TCP来说低了一些
通常说的rpc是通过用的
TCP,有socket和netty两种实现方式
手写带注册中心的rpc框架(Netty版和Socket版)
手写带注册中心的rpc框架(Netty版和Socket版)_dearfulan的博客-CSDN博客_netty 注册中心
通信核心实现代码
客户端核心类,实现了InvocationHandler接口,用于把创建代理类,invoke方法里就是创建netty客户端并发送请求给从注册中心获取到的服务端
public class RpcInvocationHandler implements InvocationHandler {
private String serviceName;
private IServiceDiscovery serviceDiscovery;
public RpcInvocationHandler(String serviceName, IServiceDiscovery serviceDiscovery) {
this.serviceName = serviceName;
this.serviceDiscovery = serviceDiscovery;
}
/**
* 增强的InvocationHandler,接口调用方法的时候实际是调用socket进行传输
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//将远程调用需要的接口类、方法名、参数信息封装成RPCRequest
RpcRequest rpcRequest = new RpcRequest();
rpcRequest.setArgs(args);
rpcRequest.setClassName(method.getDeclaringClass().getName());
rpcRequest.setMethodName(method.getName());
return handleNetty(rpcRequest);
//return handleSocket(rpcRequest);
}
private Object handleNetty(RpcRequest rpcRequest){
//创建客户端线程池
EventLoopGroup group = null;
final RpcClientHandler handler = new RpcClientHandler();
try{
group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class);