阿里面试官:给我说说Netty是如何在Dubbo中应用的?
点击上方“方志朋”,选择“设为星标”
回复”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中应用的?相关推荐
- eureka自我保护时间_阿里面试官问我:到底知不知道什么是Eureka,这次,我没沉默...
文章首发:阿里面试官问我:到底知不知道什么是Eureka,这次,我没沉默 什么是服务注册? 首先我们来了解下,服务注册.服务发现和服务注册中心的之间的关系. 举个形象的例子,三者之间的关系就好像是供货 ...
- mysql查询前段时间_没想到!我在简历上写了“精通MySQL”,阿里面试官跟我死磕后就给我发了高薪offer...
事情是这样的 前段时间面试了阿里,大家也都清楚,如果你在简历上面写着你精通XX技术,那面试官就会跟你死磕到底. 我就是在自己的简历上写了精通MySQL,然后就开启了和阿里面试官的死磕之路,结果就是拿到 ...
- 阿里面试官:“你有高并发经验吗?”
"高并发经验你有吗?" 阿里面试官一句话问倒了我. 实际上,不在BAT这样的大厂工作,是很难接触到千万级别的高并发的. 但也正是这种难得,让各个大厂都抢着要这样的人才! 下面这六道 ...
- 阿里面试官内部题库,阿里发布2022年Java岗(正式版)面试题
阿里巴巴2022年Java架构师岗面试题(正式版) 这不马上就是金三银四的面试跳槽季了嘛,小编也是通过一些小手段为大家拿到了一份阿里巴巴2022年Java架构师岗面试题(正式版)现在分享给大家,这份资 ...
- java阿里面试官直接告诉你录取答案,你还在犹豫那就晚了
java阿里面试官直接告诉你录取答案,你还在犹豫那就晚了 2022-03-11 16:49·LBL-埃文斯 前言 阿里巴巴面试规则 1.第一轮面试: 第一轮面试通常是电话面试,面试官会提前打电话约定面 ...
- 阿里面试官对面试者的忠告
文章转载自:http://www.testtao.com/thread-40822-1-1.html 钱重要还是梦想重要?知识重要还是思考重要?经验重要还是激情重要?是单纯还是圆滑世故?是大公司还是小 ...
- 面试阿里!妹子终面,阿里面试官问:有没有男朋友? 结果...
点击"开发者技术前线",选择"星标????" 在看|星标|留言, 真爱 作者: 前线小熙 | 责编: 可可 来源 :开发者技术前线 刚好要到端午节前 ...
- 【阿里面试官的抨击】大厂面试竟该这么答?| 面试竟有这些坑?| 面试该如何准备?| 如何学习知识点?
前段时间,在和程序猿们闲聊的时候,碰巧聊到了一些面试题.于是乎,各路大神就开始大显身手(虽然没我啥事-) 当然重点还是,那位阿里的大神,无意间透露出来的面试要点: 事情是这样的: 在阿里,他们部门的面 ...
- 啃完这些 Spring 知识点,我竟吊打了阿里面试官(附面经 + 笔记)
前言 又逢"金九银十",年轻的毕业生们满怀希望与忐忑,去寻找.竞争一个工作机会.已经在职的开发同学,也想通过社会招聘或者内推的时机争取到更好的待遇.更大的平台. 然而,面试人群众多 ...
最新文章
- vue论坛网站的文章自动排版_基于 VuePress 定制个人博客网站
- P1726 上白泽慧音
- 如何使用AHAS故障演练,实现具备韧性的系统架构?
- 恢复Ext3下被删除的文件
- 建造者模式什么时候使用?
- solor mysql_solr 同步 mysql
- ubuntu vscode 配置字体_第五章 Ubuntu搭建ESP32开发环境(vscode)
- js设置body高度、宽度为浏览器窗口高度、宽度
- WORD如何将标题编号设置为汉字编号?
- 2020 工业机器人行业研究报告
- C/C++函数库 之 ctype.h
- PHP消息队列的实现方式
- HTML超链接实现页面内跳转
- UVa Problem 10310 Dog and Gopher (狗拿地鼠)
- 单例模式——解决MDI子窗体实例化的问题
- 10.MATLAB方差分析
- Java设计模式之《装饰器模式》
- ORM框架的简单介绍
- 程序员的英语学习!对于像进一步提升自己的人来说,很重要哟!
- leetcode刷题之旅(5) Longest Palindromic Substring