Netty 在 Dubbo 中是如何应用的?

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

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

代码如下:

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

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


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

image.png

image.png

image.png

image.png

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 就简短的介绍到这里。

目录
相关文章
|
8月前
|
缓存 负载均衡 Dubbo
Dubbo 第二节_ Dubbo的基本应用与高级应用
官⽹地址:http://dubbo.apache.org/zh/docs/v2.7/user/examples/loadbalance/ 如果在消费端和服务端都配置了负载均衡策略,以消费端为准。 这其中⽐较难理解的就是最少活跃调⽤数是如何进⾏统计的? 讲道理,最少活跃数应该是在服务提供者端进⾏统计的,服务提供者统计有多少个请求正在执⾏中。 但在Dubbo中,就是不讲道理,它是在消费端进⾏统计的,为什么能在消费端进⾏统计? 逻辑是这样的:官⽹地址:http://dubbo.apache.org/zh/docs
|
3月前
|
Dubbo 应用服务中间件 Apache
Dubbo 应用切换 ZooKeeper 注册中心实例,流量无损迁移
如果 Dubbo 应用使用 ZooKeeper 作为注册中心,现在需要切换到新的 ZooKeeper 实例,如何做到流量无损?
44 4
|
4月前
|
缓存 负载均衡 Dubbo
Dubbo技术深度解析及其在Java中的实战应用
Dubbo是一款由阿里巴巴开源的高性能、轻量级的Java分布式服务框架,它致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
124 6
|
6月前
|
Kubernetes Dubbo Cloud Native
如何将Dubbo应用接入服务网格
介绍使用传统Dubbo微服务体系的客户要如何将自己的服务接入到服务网格这一新一代云原生基础设施。
|
6月前
|
前端开发 Java 数据处理
使用Netty构建高性能的网络应用
使用Netty构建高性能的网络应用
|
6月前
|
前端开发 Java 数据处理
使用Netty构建高性能的网络应用
使用Netty构建高性能的网络应用
|
8月前
|
负载均衡 Dubbo Java
理解 Netty 和 Dubbo 之间的关系:相互作用与作用域
在现代分布式系统和微服务架构中,高性能、高可用的通信框架是成功的关键要素之一。Netty 和 Dubbo 是两个非常流行的开源项目,它们在分布式系统的构建中发挥着重要作用。
|
Dubbo Java 应用服务中间件
Netty入门到超神系列-手撸简单版RPC框架(仿Dubbo)
原理还是比较简单 : 代理 + 线程池 + Netty 下面做一些解释: 首先需要定义一个统一的API接口,例:UserApi , 服务端(provider)需要实现这个接口,提供相应的方法UserApiImpl#save,客户端通过远程来调用该接口。 然后需要约定一个协议,服务器如何才能识别到客户端要调用哪个接口?:我这里用 “接口权限定名#方法名#参数” ,的方式来,因为是一个简单版本的RPC。服务端解析该内容就能匹配对应的接口的实现类,然后调用该方法。并把方法的返回值通过Netty写回给客户端 使用的编解码器都是比价简单的String的编解码器
186 0
|
8月前
|
负载均衡 Dubbo Java
Dubbo 第一节_ Dubbo框架介绍与手写模拟Dubbo 第二节_ Dubbo的基本应用与高级应用
官⽹地址:http://dubbo.apache.org/zh/docs/v2.7/user/examples/generic-service/官⽹地址:http://dubbo.apache.org/zh/docs/v2.7/user/examples/local-mock/官⽹地址:http://dubbo.apache.org/zh/docs/v2.7/user/examples/async-call/
107 2
|
8月前
|
负载均衡 Dubbo Java
Dubbo 的心脏:理解和应用多种协议【十三】
Dubbo 的心脏:理解和应用多种协议【十三】
84 0