Netty实战 -- 使用Netty实现分布式框架Dubbo RPC

本文详细介绍了RPC的概念,以及Java中的静态代理和动态代理模式(包括JDK和CGLIB),并通过Netty实现了一个简单的DubboRPC框架,展示了服务提供者与消费者如何通过接口进行通信。
摘要由CSDN通过智能技术生成
  1. server stub 收到消息后进行解码

  2. server stub 根据解码结果调用本地API

  3. 本地服务 执行并返回结果给 server stub

  4. server stub 将返回结果导入进行编码并发送至消费方

  5. client stub 接收到数据进行解码

  6. 服务消费方得到结果

RPC的目标就是将2~8的步骤封装起来,用户无需关注这些细节,可以像调用本地方法一样即可完成远程服务调用

图解

在这里插入图片描述

二、什么是代理模式?

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

代理模式的定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。

Java中代理模式分为静态代理动态代理模式

2.1 案例实现


中午到了,小明很饿,于是在美团外卖上点了一份烤鸭,过了半个小时,外卖到了,小明下去拿外卖,顺利的吃上了烤鸭~

2.2 静态代理方式


由程序员手动创建代理类或工具对象,从而实现调用服务

Subject类

package com.wanshi.netty.dubborpc.netty;

public interface Subject {

String buy(String msg);

}

SubjectImpl类

package com.wanshi.netty.dubborpc.netty;

public class SubjectImpl implements Subject{

@Override

public String buy(String msg) {

return “买了” + msg;

}

}

ProxySubject类

package com.wanshi.netty.dubborpc.netty;

public class ProxySubject {

private Subject subject;

{

subject = new SubjectImpl();

}

public void buy(String msg) {

System.out.println(“美团外卖,使命必达,跑腿代买!”);

String buy = subject.buy(msg);

System.out.println(buy);

}

}

测试类

public static void main(String[] args) {

ProxySubject subject = new ProxySubject();

subject.buy(“北京烤鸭”);

}

效果

在这里插入图片描述

⛽静态代理的优缺点

缺点: 不利于扩展,调用一次就要创建一次对象,从而造成不必要的内存空间浪费

优点: 可读性好,逻辑简单,清晰明了

2.3 动态代理方式


动态代理又分为:JDK动态代理CGLIB动态代理

在程序运行时,运用反射机制动态创建而成,达到调用服务

使用以上的Subject类和实现类

SubjectInvocationHandler处理器类

package com.wanshi.netty.dubborpc.netty;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

public class SubjectInvocationHandler implements InvocationHandler {

private Object obj;

public SubjectInvocationHandler(Object obj) {

this.obj = obj;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

Object res = method.invoke(obj, args);

return res;

}

}

ProxyFactry工厂类

package com.wanshi.netty.dubborpc.netty;

import java.lang.reflect.Proxy;

public class ProxyFactry {

public static Subject getInstance() {

SubjectImpl subject = new SubjectImpl();

System.out.println(“美团外卖,使命必达,跑腿代买!”);

SubjectInvocationHandler subjectInvocationHandler = new SubjectInvocationHandler(subject);

Subject proxy = (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(),

subject.getClass().getInterfaces(), subjectInvocationHandler);

return proxy;

}

}

测试类

public static void main(String[] args) {

Subject subject = ProxyFactry.getInstance();

String buy = subject.buy(“饮料”);

System.out.println(buy);

}

效果

在这里插入图片描述

⛽动态代理的优缺点

两种动态代理对照表

| | JDK原生动态代理 | CGLIB动态代理 |

| — | — | — |

| 核心原理 | 基于 ”接口实现“方式 | 基于类集成方式 |

| 优点 | Java原生支持的,不需要任何依赖 | 对与代理的目标对象无限制,无需实现接口 |

| 不足之处 | 只能基于接口实现 | 无法处理final方法 |

| 实现方式 | Java原生支持 | 需要引入Jar文件依赖 |

三、Netty实现DubboRPC

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

3.1 需求说明


  1. dubbo 底层使用了Netty作为网络通讯框架,要求用Netty实现一个简单的RPC框架

  2. 模仿dubbo,消费者和提供者约定接口和协议,消费者远程调用提供者的服务,提供者返回一个字符串,消费者打印提供者返回的数据,底层使用Netty框架

3.2 剖析需求


  1. 创建接口,定义抽象方法,用于服务消费者与服务提供者之间的约定

  2. 创建一个提供者,该类需要监听消费者的请求,并按照约定返回数据

  3. 创建一个消费者,该类需要 透明的调用自己不存在的方法,内部使用Netty 请求提供者返回数据

在这里插入图片描述

3.3 效果图


在这里插入图片描述

3.4 核心源码


♻️共用接口API

HelloService

package com.wanshi.netty.dubborpc.publicinterface;

/**

  • 公共接口,提供服务

*/

public interface HelloService {

String hello(String msg);

}

♻️服务提供者

ServerBootstrap启动类

package com.wanshi.netty.dubborpc.provider;

import com.wanshi.netty.dubborpc.netty.NettyServer;

/**

  • 服务提供者启动类,监听消费者,并绑定端口8888

*/

public class ServerBootstrap {

public static void main(String[] args) {

NettyServer.startServer(“127.0.0.1”, 8888);

}

}

NettyServer

package com.wanshi.netty.dubborpc.netty;

import io.netty.bootstrap.ServerBootstrap;

import io.netty.channel.ChannelFuture;

import io.netty.channel.ChannelInitializer;

import io.netty.channel.ChannelPipeline;

import io.netty.channel.EventLoopGroup;

import io.netty.channel.nio.NioEventLoopGroup;

import io.netty.channel.socket.SocketChannel;

import io.netty.channel.socket.nio.NioServerSocketChannel;

import io.netty.handler.codec.string.StringDecoder;

import io.netty.handler.codec.string.StringEncoder;

/**

  • Netty服务器类,启动服务

*/

public class NettyServer {

/**

  • 开启服务方法,调用内部私有启动服务方法,此类写法很常用,进一层的封装了API
    先自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以扫码领取!

img

读者福利

由于篇幅过长,就不展示所有面试题了,感兴趣的小伙伴

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」

更多笔记分享

35K成功入职:蚂蚁金服面试Java后端经历!「含面试题+答案」
mg-4ZSEcCLJ-1711438074030)]

[外链图片转存中…(img-6XzcCjQr-1711438074031)]

[外链图片转存中…(img-6V88ZVOH-1711438074031)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以扫码领取!

img

读者福利

由于篇幅过长,就不展示所有面试题了,感兴趣的小伙伴

[外链图片转存中…(img-UbpRlxtI-1711438074032)]

[外链图片转存中…(img-xlWAXqaq-1711438074032)]

[外链图片转存中…(img-7wd2RDhW-1711438074032)]

更多笔记分享

[外链图片转存中…(img-X8H3Fs5u-1711438074032)]
需要更多Java资料的小伙伴可以帮忙点赞+关注,点击传送门,即可免费领取!

  • 28
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值