Corda是什么?
- Corda is an open-source blockchain platform.
- 节点与节点之间通过RPC调用,最终完成一个分布式账本。
Corda使用Netty概况
-
总览
说明1,采用主从模式。
2,使用NioServerSocketChannel::class.java反射方式创建channel实例。创建channel实例过程理解
3,为workerGroup添加handler,也就是添加业务handler。
4,绑定ip和port,启动服务。
-
pipeline
说明
1, 继承Netty的ChannelInitializer < SocketChannel>()
2, 重写initChannel()这个方法,这是一个中介,当它把handler添加到pipeline中,会把自己给移除掉。这里添加Netty自带的SslHandler到pipeline中。
3,添加AMQPChannelHandler()到pipeline中。
sslHandler说明
A:TLS的版本(TLSV1.2)
B: 签名套件
C:SslHandler是Netty提供的Handler,开箱即用。
AMQPChannelHandler说明
重写userEventTriggered方法
createAMQPEngine(ctx)
A:EventProcessor类继承了开源工具proton-j提供的BashHandler类。并重写相应的核心方法。gradle构建:compile “org.apache.qpid:proton-j:0.21.0”
B:先传播,然后异步处理事件(这里处理的方式是交给proton-j去处理执行的,线程池是channel.eventLoop(),也就是workerGroup那个线程池执行业务逻辑的)
channelRead()
A: 交给proton-j处理消息,比如粘包和拆包问题的解决。
B: 防止Netty的内存泄漏。
C:使用Netty的workerGroup提供的线程池执行业务逻辑handler()
-
线程模型
主从模式,bossGroup一个线程,workerGroup程序写死4个线程。
Corda使用Netty的一些技巧
- 使用Proton-j开源工具。
在Proton-j中,它是通过判断事件类型来执行相应的逻辑的。如下是它处理的事件类型:
@Override
public void handle(Event e) {
switch (e.getType()) {
case CONNECTION_INIT:
onConnectionInit(e);
break;
case CONNECTION_LOCAL_OPEN:
onConnectionLocalOpen(e);
break;
case CONNECTION_REMOTE_OPEN:
onConnectionRemoteOpen(e);
break;
case CONNECTION_LOCAL_CLOSE:
onConnectionLocalClose(e);
break;
case CONNECTION_REMOTE_CLOSE:
onConnectionRemoteClose(e);
break;
case CONNECTION_BOUND:
onConnectionBound(e);
break;
case CONNECTION_UNBOUND:
onConnectionUnbound(e);
break;
case CONNECTION_FINAL:
onConnectionFinal(e);
break;
case SESSION_INIT:
onSessionInit(e);
break;
case SESSION_LOCAL_OPEN:
onSessionLocalOpen(e);
break;
case SESSION_REMOTE_OPEN:
onSessionRemoteOpen(e);
break;
case SESSION_LOCAL_CLOSE:
onSessionLocalClose(e);
break;
case SESSION_REMOTE_CLOSE:
onSessionRemoteClose(e);
break;
case SESSION_FINAL:
onSessionFinal(e);
break;
case LINK_INIT:
onLinkInit(e);
break;
case LINK_LOCAL_OPEN:
onLinkLocalOpen(e);
break;
case LINK_REMOTE_OPEN:
onLinkRemoteOpen(e);
break;
case LINK_LOCAL_DETACH:
onLinkLocalDetach(e);
break;
case LINK_REMOTE_DETACH:
onLinkRemoteDetach(e);
break;
case LINK_LOCAL_CLOSE:
onLinkLocalClose(e);
break;
case LINK_REMOTE_CLOSE:
onLinkRemoteClose(e);
break;
case LINK_FLOW:
onLinkFlow(e);
break;
case LINK_FINAL:
onLinkFinal(e);
break;
case DELIVERY:
onDelivery(e);
break;
case TRANSPORT:
onTransport(e);
break;
case TRANSPORT_ERROR:
onTransportError(e);
break;
case TRANSPORT_HEAD_CLOSED:
onTransportHeadClosed(e);
break;
case TRANSPORT_TAIL_CLOSED:
onTransportTailClosed(e);
break;
case TRANSPORT_CLOSED:
onTransportClosed(e);
break;
case REACTOR_FINAL:
onReactorFinal(e);
break;
case REACTOR_QUIESCED:
onReactorQuiesced(e);
break;
case REACTOR_INIT:
onReactorInit(e);
break;
case SELECTABLE_ERROR:
onSelectableError(e);
break;
case SELECTABLE_EXPIRED:
onSelectableExpired(e);
break;
case SELECTABLE_FINAL:
onSelectableFinal(e);
break;
case SELECTABLE_INIT:
onSelectableInit(e);
break;
case SELECTABLE_READABLE:
onSelectableReadable(e);
break;
case SELECTABLE_UPDATED:
onSelectableWritable(e);
break;
case SELECTABLE_WRITABLE:
onSelectableWritable(e);
break;
case TIMER_TASK:
onTimerTask(e);
break;
case NON_CORE_EVENT:
onUnhandled(e);
break;
}
}
proton-j对通信过程进行了更加细致的控制,对各种事件的发生写了应对的处理逻辑。
- Proton-j的事件是线性表结构(单链表)。
- 如何解决TCP的粘包和拆包问题?
在pipeline中,我们没有看见Corda添加一次编解码和二次编解码的handler,那Corda又是怎么处理这些问题的呢?
Proton-j本质上来说是一个序列化工具。所以序列化逻辑完全交给Proton-j来完成。
处理输入数据
处理输出数据
- Proton-j的sasl(),在传输层套上用户名和密码自定义权限
Corda使用Netty可以优化的地方
- 执行Corda业务逻辑的线程池,是workerGroup中的线程池。这里完全可以使用一个新的线程池来执行业务逻辑。
- Corda的最大等待连接数是100。 可以设置得更大,比如1024。