点击上方“方志朋”,选择“设为星标”

回复”666“获取新整理的面试资料

作者:莫那 鲁道

来源:cnblogs.com/stateis0/p/9062171.html

# 目录

  • dubbo 的 Consumer 消费者如何使用 Netty

  • dubbo 的 Provider 提供者如何使用 Netty

  • 总结

# 前言

众所周知,国内知名框架 Dubbo 底层使用的是 Netty 作为网络通信,那么内部到底是如何使用的呢?今天我们就来一探究竟。

1. dubbo 的 Consumer 消费者如何使用 Netty

注意:此次代码使用了从 github 上 clone 的 dubbo 源码中的 dubbo-demo 例子。

代码如下:

    System.setProperty("java.net.preferIPv4Stack", "true");ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-consumer.xml"});context.start();// @1DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxyint a = 0;while (true) {try {Thread.sleep(1000);System.err.println( ++ a + " ");String hello = demoService.sayHello("world"); // call remote methodSystem.out.println(hello); // get result} catch (Throwable throwable) {throwable.printStackTrace();}}

当代码执行到 @1 的时候,会调用 Spring 容器的 getBean 方法,而 dubbo 扩展了 FactoryBean,所以,会调用 getObject 方法,该方法会创建代理对象。

这个过程中会调用 DubboProtocol 实例的 getClients(URL url) 方法,当这个给定的 URL 的 client 没有初始化则创建,然后放入缓存,代码如下:

这个 initClient 方法就是创建 Netty 的 client 的。

最终调用的就是抽象父类 AbstractClient 的构造方法,构造方法中包含了创建 Socket 客户端,连接客户端等行为。

public AbstractClient(URL url, ChannelHandler handler) throws RemotingException {doOpen();connect();
}

doOpent 方法用来创建 Netty 的 bootstrap :

protected void doOpen() throws Throwable {NettyHelper.setNettyLoggerFactory();bootstrap = new ClientBootstrap(channelFactory);bootstrap.setOption("keepAlive", true);bootstrap.setOption("tcpNoDelay", true);bootstrap.setOption("connectTimeoutMillis", getTimeout());final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);bootstrap.setPipelineFactory(new ChannelPipelineFactory() {public ChannelPipeline getPipeline() {NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyClient.this);ChannelPipeline pipeline = Channels.pipeline();pipeline.addLast("decoder", adapter.getDecoder());pipeline.addLast("encoder", adapter.getEncoder());pipeline.addLast("handler", nettyHandler);return pipeline;}});
}

connect 方法用来连接提供者:

protected void doConnect() throws Throwable {long start = System.currentTimeMillis();ChannelFuture future = bootstrap.connect(getConnectAddress());boolean ret = future.awaitUninterruptibly(getConnectTimeout(), TimeUnit.MILLISECONDS);if (ret && future.isSuccess()) {Channel newChannel = future.getChannel();newChannel.setInterestOps(Channel.OP_READ_WRITE);}
}

上面的代码中,调用了 bootstrap 的 connect 方法,熟悉的 Netty 连接操作。当然这里使用的是 jboss 的 netty3,稍微有点区别。当连接成功后,注册写事件,准备开始向提供者传递数据。

当 main 方法中调用 demoService.sayHello("world") 的时候,最终会调用 HeaderExchangeChannel 的 request 方法,通过 channel 进行请求。

public ResponseFuture request(Object request, int timeout) throws RemotingException {Request req = new Request();req.setVersion("2.0.0");req.setTwoWay(true);req.setData(request);DefaultFuture future = new DefaultFuture(channel, req, timeout);channel.send(req);return future;
}

send 方法中最后调用 jboss Netty 中继承了 NioSocketChannel 的 NioClientSocketChannel 的 write 方法。完成了一次数据的传输。

2. dubbo 的 Provider 提供者如何使用 Netty

Provider demo 代码:

System.setProperty("java.net.preferIPv4Stack", "true");
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-provider.xml"});
context.start();
System.in.read(); // press any key to exit

Provider 作为被访问方,肯定是一个 Server 模式的 Socket。如何启动的呢?

当 Spring 容器启动的时候,会调用一些扩展类的初始化方法,比如继承了 InitializingBean,ApplicationContextAware,ApplicationListener 。而 dubbo 创建了 ServiceBean 继承了一个监听器。Spring 会调用他的 onApplicationEvent 方法,该类有一个 export 方法,用于打开 ServerSocket 。

然后执行了 DubboProtocol 的 createServer 方法,然后创建了一个 NettyServer 对象。NettyServer 对象的

构造方法同样是 doOpen 方法和。代码如下:

protected void doOpen() throws Throwable {NettyHelper.setNettyLoggerFactory();ExecutorService boss = Executors.newCachedThreadPool(new NamedThreadFactory("NettyServerBoss", true));ExecutorService worker = Executors.newCachedThreadPool(new NamedThreadFactory("NettyServerWorker", true));ChannelFactory channelFactory = new NioServerSocketChannelFactory(boss, worker, getUrl().getPositiveParameter(Constants.IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS));bootstrap = new ServerBootstrap(channelFactory);final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);channels = nettyHandler.getChannels();bootstrap.setPipelineFactory(new ChannelPipelineFactory() {public ChannelPipeline getPipeline() {NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyServer.this);ChannelPipeline pipeline = Channels.pipeline();pipeline.addLast("decoder", adapter.getDecoder());pipeline.addLast("encoder", adapter.getEncoder());pipeline.addLast("handler", nettyHandler);return pipeline;}});channel = bootstrap.bind(getBindAddress());
}

该方法中,看到了熟悉的 boss 线程,worker 线程,和 ServerBootstrap,在添加了编解码 handler 之后,添加一个 NettyHandler,最后调用 bind 方法,完成绑定端口的工作。和我们使用 Netty 是一摸一样。

3. 总结

可以看到,dubbo 使用 Netty 还是挺简单的,消费者使用 NettyClient,提供者使用 NettyServer,Provider 启动的时候,会开启端口监听,使用我们平时启动 Netty 一样的方式。而 Client 在 Spring getBean 的时候,会创建 Client,当调用远程方法的时候,将数据通过 dubbo 协议编码发送到 NettyServer,然后 NettServer 收到数据后解码,并调用本地方法,并返回数据,完成一次完美的 RPC 调用。

好,关于 dubbo 如何使用 Netty 就简短的介绍到这里。

good luck!!!!

热门内容:

  • 消灭 Java 代码的“坏味道”

  • 代码生成器:IDEA 强大的 Live Templates

  • 2020 年,给你 8 个程序员接私活的网站

  • Vert.x!这是目前最快的 Java 框架

  • SpringBoot线程池的创建、@Async配置步骤及注意事项

  • 看看,这些细节上的坑,你犯了多少?

  • 老大说,网上这种获取真实IP地址的方法不对,我不信...

  • AJAX 请求真的不安全么?

  • 你知道为什么Java的main方法必须是public static void?

  • 谈谈中间件开发,给想从事中间件开发的同学

  • 大年夜排查bug:竟然是同事把Redis用成这鬼样子,坑了我

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

明天见(。・ω・。)ノ♡

阿里面试官:给我说说Netty是如何在Dubbo中应用的?相关推荐

  1. eureka自我保护时间_阿里面试官问我:到底知不知道什么是Eureka,这次,我没沉默...

    文章首发:阿里面试官问我:到底知不知道什么是Eureka,这次,我没沉默 什么是服务注册? 首先我们来了解下,服务注册.服务发现和服务注册中心的之间的关系. 举个形象的例子,三者之间的关系就好像是供货 ...

  2. mysql查询前段时间_没想到!我在简历上写了“精通MySQL”,阿里面试官跟我死磕后就给我发了高薪offer...

    事情是这样的 前段时间面试了阿里,大家也都清楚,如果你在简历上面写着你精通XX技术,那面试官就会跟你死磕到底. 我就是在自己的简历上写了精通MySQL,然后就开启了和阿里面试官的死磕之路,结果就是拿到 ...

  3. 阿里面试官:“你有高并发经验吗?”

    "高并发经验你有吗?" 阿里面试官一句话问倒了我. 实际上,不在BAT这样的大厂工作,是很难接触到千万级别的高并发的. 但也正是这种难得,让各个大厂都抢着要这样的人才! 下面这六道 ...

  4. 阿里面试官内部题库,阿里发布2022年Java岗(正式版)面试题

    阿里巴巴2022年Java架构师岗面试题(正式版) 这不马上就是金三银四的面试跳槽季了嘛,小编也是通过一些小手段为大家拿到了一份阿里巴巴2022年Java架构师岗面试题(正式版)现在分享给大家,这份资 ...

  5. java阿里面试官直接告诉你录取答案,你还在犹豫那就晚了

    java阿里面试官直接告诉你录取答案,你还在犹豫那就晚了 2022-03-11 16:49·LBL-埃文斯 前言 阿里巴巴面试规则 1.第一轮面试: 第一轮面试通常是电话面试,面试官会提前打电话约定面 ...

  6. 阿里面试官对面试者的忠告

    文章转载自:http://www.testtao.com/thread-40822-1-1.html 钱重要还是梦想重要?知识重要还是思考重要?经验重要还是激情重要?是单纯还是圆滑世故?是大公司还是小 ...

  7. 面试阿里!妹子终面,阿里面试官问:有没有男朋友? 结果...

    点击"开发者技术前线",选择"星标????" 在看|星标|留言,  真爱 作者:  前线小熙  | 责编: 可可   来源 :开发者技术前线  刚好要到端午节前 ...

  8. 【阿里面试官的抨击】大厂面试竟该这么答?| 面试竟有这些坑?| 面试该如何准备?| 如何学习知识点?

    前段时间,在和程序猿们闲聊的时候,碰巧聊到了一些面试题.于是乎,各路大神就开始大显身手(虽然没我啥事-) 当然重点还是,那位阿里的大神,无意间透露出来的面试要点: 事情是这样的: 在阿里,他们部门的面 ...

  9. 啃完这些 Spring 知识点,我竟吊打了阿里面试官(附面经 + 笔记)

    前言 又逢"金九银十",年轻的毕业生们满怀希望与忐忑,去寻找.竞争一个工作机会.已经在职的开发同学,也想通过社会招聘或者内推的时机争取到更好的待遇.更大的平台. 然而,面试人群众多 ...

最新文章

  1. vue论坛网站的文章自动排版_基于 VuePress 定制个人博客网站
  2. P1726 上白泽慧音
  3. 如何使用AHAS故障演练,实现具备韧性的系统架构?
  4. 恢复Ext3下被删除的文件
  5. 建造者模式什么时候使用?
  6. solor mysql_solr 同步 mysql
  7. ubuntu vscode 配置字体_第五章 Ubuntu搭建ESP32开发环境(vscode)
  8. js设置body高度、宽度为浏览器窗口高度、宽度
  9. WORD如何将标题编号设置为汉字编号?
  10. 2020 工业机器人行业研究报告
  11. C/C++函数库 之 ctype.h
  12. PHP消息队列的实现方式
  13. HTML超链接实现页面内跳转
  14. UVa Problem 10310 Dog and Gopher (狗拿地鼠)
  15. 单例模式——解决MDI子窗体实例化的问题
  16. 10.MATLAB方差分析
  17. Java设计模式之《装饰器模式》
  18. ORM框架的简单介绍
  19. 程序员的英语学习!对于像进一步提升自己的人来说,很重要哟!
  20. leetcode刷题之旅(5) Longest Palindromic Substring

热门文章

  1. 【杂项】SVN服务器的本地搭建和使用
  2. 第5次作业+105032014166+张珍珍
  3. php中类和对象的操作
  4. php学习之道:WSDL具体解释(三)
  5. 秦州:西瓜书 + 南瓜书 吃瓜系列 14. 降维与度量学习(下)
  6. Scratch等级考试(一级)模拟题
  7. 技术图文:如何在CSDN上写自己的技术Blog?
  8. moravec 角点检测
  9. 【ACM】杭电OJ 2023
  10. ​GPT-3好“搭档”:这种方法缓解模型退化,让输出更自然