GVKun编程网logo

channel is already closed due to channel error;

8

在本文中,我们将详细介绍channelisalreadyclosedduetochannelerror;的各个方面,同时,我们也将为您带来关于c#–ChannelFactory.CreateChann

在本文中,我们将详细介绍channel is already closed due to channel error;的各个方面,同时,我们也将为您带来关于c# – ChannelFactory.CreateChannel如何工作?、Cannot send, channel has already failed:、ChannelHandler,ChannelHandlerContext,ChannelPipeline、ChannelNets: channel-wise卷积,在channel维度进行卷积滑动 | NeurIPS 2018的有用知识。

本文目录一览:

channel is already closed due to channel error;

channel is already closed due to channel error;

 com.rabbitmq.client.AlreadyClosedException: channel is already closed due to channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg ''durable'' for queue ''test_data'' in vhost ''/'': received ''true'' but current is ''false'', class-id=50, method-id=10

翻译过来就是 exchange 的 durable 已经 true 了不能改为 false。所以使用的时候要注意如果 exchange 和 queue 的 durable 已经定义好了是不能更改的。除非客户端删掉 exchange,queue 然后重新启动。

c# – ChannelFactory.CreateChannel如何工作?

c# – ChannelFactory.CreateChannel如何工作?

如果我有一个界面:

public interface ISomething
{
    void DoAThing();
}

然后我用ChannelFactory实例化它:

var channel = new ChannelFactory<ISomething>().CreateChannel

我得到了一个我可以使用的实例.

现在,关闭它我需要施放:

((IClientChannel)channel).Close

要么

((IChannel)channel).Close

要么

((ICommunicationObject)channel).Close

我的ISomething接口不会继承任何这些接口.

那么CreateChannel方法返回的是什么类型的对象?它是如何构造一个动态对象的,它能够实现一个它直到运行时才知道的接口?

解决方法

ChannelFactory.CreateChannel()返回 RealProxy的实现,它是一组工具的一部分,通常称为TransparentProxy或“Remoting”,这是一个稍微过时的pre-wcf技术.为了创建实现接口的实际类,它归结为一个名为 RemotingServices.CreateTransparentProxy(…)的内部框架级方法,我没有看过,但很可能是某些类的类构建器/发射器.

正如你所问,你可能想要自己做这样的事情.要在运行时实现接口,我建议Castle Dynamic Proxy实现接口或抽象类而不需要太多努力.

Cannot send, channel has already failed:

Cannot send, channel has already failed:

<div id="content_views"> <!-- flowchart 箭头图标 勿删 --> <svg xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block"></path></svg> <p><img src="https://img-blog.csdnimg.cn/2018112309302616.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTAwNTAxNzQ=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br> 背景:</p> <pre><code>一个同事往这个队列发数据,另一个同事从这个队列取数据,进行解析。 这是昨天同事昨天消费者 消费<a href="https://www.baidu.com/s?wd=activemq&amp;tn=24004469_oem_dg&amp;rsv_dl=gh_pl_sl_csd" target="_blank">activemq</a> 队列,一开始有正常,运行了一段时间后,发现突然消费者变为零了。因为有监控。之后怎么也连不上。然后报了这个错。 javax.jms.JMSException: Cannot send, channel has already failed: tcp://IP:61616 at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:62) at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1409) at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:1496) at org.apache.activemq.ActiveMQConnection.start(ActiveMQConnection.java:524) </code></pre> <p><strong>分析:</strong><br> 本以为是同事写的程序有问题,就用本地写了一个最简单的取数据程序,依旧是报这个错。</p> <p>为了不让队列监控一直报警,就让发送数据的同事A 停止 生产者程序。<br> 突然之后就可以正常取程序了。</p> <p><strong>问题锁定:</strong><br> 这才怀疑是生产者出现的问题。<strong>是因为他每次发送消息都new 一个连接</strong>。<strong>导致超出默认最大连接数1000 。所以无法再有连接队列,导致队列无法连接</strong></p> <p>发生这个错误,去检查下自己代码,是否是每次都创建一个连接,而没有关闭连接。</p> <p>一般分为两种连接<br> 一种是长连接,适用于处于一值发送数据,<br> 一种短连接,就是连接了,发送完数据,就关闭连接</p>

        </div>

ChannelHandler,ChannelHandlerContext,ChannelPipeline

ChannelHandler,ChannelHandlerContext,ChannelPipeline

本小节一起学习一下 ChannelHandler,ChannelHandlerContext,ChannelPipeline 这三个 Netty 常用的组件,不探究它们的底层源码,我们就简单的分析一下用法

 

首先先分析一下 ChannelHandler,ChannelHandler 是我们日常开发中使用最多的组件了,大概我们平时写的最多的组件就是 Handler 了,继承图如下

 

我们平时继承的最多的就是 ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapter, 这两个不是接口也不是抽象类,所以我们可以仅仅重写我们需要的方法,没有必须要实现的方法,当然我们也会使用 SimpleChannelInboundHandler,这个类我们上个小节也稍微讲了它的优缺点,这里不赘述

 

ChannelHandler,ChannelHandlerContext,ChannelPipeline 这三者的关系很特别,相辅相成,一个 ChannelPipeline 中可以有多个 ChannelHandler 实例,而每一个 ChannelHandler 实例与 ChannelPipeline 之间的桥梁就是 ChannelHandlerContext 实例,如图所示:

看图就知道,ChannelHandlerContext 的重要性了,如果你获取到了 ChannelHandlerContext 的实例的话,你可以获取到你想要的一切,你可以根据 ChannelHandlerContext 执行 ChannelHandler 中的方法,我们举个例子来说,我们可以看下 ChannelHandlerContext 部分 API:

这几个 API 都是使用比较频繁的,都是调用当前 handler 之后同一类型的 channel 中的某个方法,这里的同一类型指的是同一个方向,比如 inbound 调用 inbound,outbound 调用 outbound 类型的 channel,一般来说,都是一个 channel 的 ChannnelActive 方法中调用 fireChannelActive 来触发调用下一个 handler 中的 ChannelActive 方法

 

我们举例来说,我们修改 Helloworld 版中的部分代码,在客户端中的 channel 中修改一下代码

首先我们修改一下 bootstrap 的启动类代码:

 

[html]  view plain  copy
 
  1. try {  
  2.             Bootstrap b = new Bootstrap();  
  3.             b.group(group)  
  4.              .channel(NioSocketChannel.class)  
  5.              .option(ChannelOption.TCP_NODELAY, true)  
  6.              .handler(new ChannelInitializer<SocketChannel>() {  
  7.                  @Override  
  8.                  public void initChannel(SocketChannel ch) throws Exception {  
  9.                      ChannelPipeline p = ch.pipeline();  
  10.                      p.addLast("decoder", new StringDecoder());  
  11.                      p.addLast("encoder", new StringEncoder());  
  12.                      p.addLast(new BaseClient1Handler());  
  13.                      p.addLast(new BaseClient2Handler());  
  14.                  }  
  15.              });  
  16.   
  17.             ChannelFuture future = b.connect(HOST, PORT).sync();  
  18.             future.channel().writeAndFlush("Hello Netty Server ,I am a common client");  
  19.             future.channel().closeFuture().sync();  
  20.         } finally {  
  21.             group.shutdownGracefully();  
  22.         }  

我们在 channelhandler 链中加了两个自定义的 BaseClient1Handler 和 BaseClient2Handler 的处理器

 

BaseClient1Handler 的方法也很简单:

BaseClient1Handler.java

 

[java]  view plain  copy
 
  1. package com.lyncc.netty.component.channelhandler;  
  2.   
  3. import io.netty.channel.ChannelHandlerContext;  
  4. import io.netty.channel.ChannelInboundHandlerAdapter;  
  5.   
  6. /** 
  7.  *  
  8.  * @author bazingaLyncc 
  9.  * 描述:客户端的第一个自定义的 inbound 处理器 
  10.  * 时间  2016 年 5 月 3 日 
  11.  */  
  12. public class BaseClient1Handler extends ChannelInboundHandlerAdapter{  
  13.       
  14.     @Override  
  15.     public void channelActive(ChannelHandlerContext ctx) throws Exception {  
  16.         System.out.println("BaseClient1Handler channelActive");  
  17. //        ctx.fireChannelActive();  
  18.     }  
  19.       
  20.     @Override  
  21.     public void channelInactive(ChannelHandlerContext ctx) throws Exception {  
  22.         System.out.println("BaseClient1Handler channelInactive");  
  23.     }  
  24.   
  25. }  

BaseClient2Handler.java

 

 

[java]  view plain  copy
 
  1. package com.lyncc.netty.component.channelhandler;  
  2.   
  3. import io.netty.channel.ChannelHandlerContext;  
  4. import io.netty.channel.ChannelInboundHandlerAdapter;  
  5.   
  6. /** 
  7.  *  
  8.  * @author bazingaLyncc 
  9.  * 描述:客户端的第二个自定义的 inbound 处理器 
  10.  * 时间  2016 年 5 月 3 日 
  11.  */  
  12. public class BaseClient2Handler extends ChannelInboundHandlerAdapter{  
  13.       
  14.     @Override  
  15.     public void channelActive(ChannelHandlerContext ctx) throws Exception {  
  16.         System.out.println("BaseClient2Handler Active");  
  17.     }  
  18.       
  19.      
  20.   
  21. }  

其他的代码不修改的,我们先启动服务器端,然后启动客户端,你会发现控制台打印了:

 

不会打印 BaseClient2Handler 类中 channelActive 方法中的输出语句,如果你想要打印,你可以将 BaseClient1Handler 中的 channelActive 的 ctx.fireChannelActive () 注释去掉。重新运行:

也就是说如果一个 channelPipeline 中有多个 channelHandler 时,且这些 channelHandler 中有同样的方法时,例如这里的 channelActive 方法,只会调用处在第一个的 channelHandler 中的 channelActive 方法,如果你想要调用后续的 channelHandler 的同名的方法就需要调用以 “fire” 为开头的方法了,这样做很灵活

 

目前来说这样做的好处:

1)每一个 handler 只需要关注自己要处理的方法,如果你不关注 channelActive 方法时,你自定义的 channelhandler 就不需要重写 channelActive 方法

2)异常处理,如果 exceptionCaught 方法每个 handler 都重写了,只需有一个类捕捉到然后做处理就可以了,不需要每个 handler 都处理一遍

3)灵活性。例如如下图所示:

如图所示在业务逻辑处理中,也许左侧第一个 ChannelHandler 根本不需要管理某个业务逻辑,但是从第二个 ChannelHandler 就需要关注处理某个业务需求了,那么就可以很灵活地从第二个 ChannelHandler 开始处理业务,不需要从 channel 中的第一个 ChannelHandler 开始处理,这样会使代码显得让人看不懂~

 

初步看懂的 ChannelHandler,ChannelHandlerContext,ChannelPipeline 之间的关系就是如上总结的

 

以上三点是我自己总结的,没看源码,有些也可能不对,欢迎拍砖,一起学习的过程,不保证全部对~

ChannelNets: channel-wise卷积,在channel维度进行卷积滑动 | NeurIPS 2018

ChannelNets: channel-wise卷积,在channel维度进行卷积滑动 | NeurIPS 2018

Channel-wise卷积在channel维度上进行滑动,巧妙地解决卷积操作中输入输出的复杂全连接特性,但又不会像分组卷积那样死板,是个很不错的想法

来源:晓飞的算法工程笔记 公众号

论文: ChannelNets: Compact and Efficient Convolutional Neural Networks via Channel-Wise Convolutions

  • 论文地址:https://arxiv.org/abs/1809.01330
  • 论文代码:https://github.com/HongyangGao/ChannelNets

Introduction


  深度可分离卷积能够减少网络的计算量和参数量,其中point-wise卷积占据了大部分参数量,论文认为网络轻量化的下一个核心在于改变输入到输出的稠密连接方式。为此,论文提出channel-wise卷积的概念,将输入输出的维度连接进行稀疏化而非全连接,区别于分组卷积的严格分组,让卷积在channel维度上进行滑动,能够更好地保留channel间的信息交流。基于channel-wise卷积的思想,论文进一步提出了channel-wise深度可分离卷积,并基于该结构替换网络最后的全连接层+全局池化的操作,搭建了ChannelNets。

Channel-Wise Convolutions and ChannelNets


  图a为深度可分离卷积结构,而图b为加入分组后的深度可分离卷积的结构,其中每个点代表一维特征。

Channel-Wise Convolutions

  Channel-wise卷积的核心在于输入和输出连接的稀疏化,每个输出仅与部分输入相连,概念上区别于分组卷积,没有对输入进行严格的区分,而是以一定的stride去采样多个相关输入进行输出(在channel维度滑动),能够降少参数量以及保证channel间一定程度的信息流。假设卷积核大小为$d_k$,输出大小维度为$n$,输入特征图大小为$d_f\times d_f$,普通卷积的参数量为$m\times d_k\times d_k\times n$,计算量为$m\times d_k\times d_k\times d_f\times d_f\times d_f\times n$,而channel-wise卷积的参数量为$d_c\times d_k\times d_k$,$d_c$一般为远小于$m$的数,代表一次采样的输入维度,计算量为$d_c\times d_k\times d_k\times d_f\times d_f\times n$,参数量和计算量都脱离于输入特征的维度$m$。

Group Channel-Wise Convolutions

  分组卷积的分组思想会导致channel间的信息阻隔,为了增加分组间的channel信息交流,一般需要在后面添加一个融合层,继续保持分组的同时整合所有组的特征。论文使用分组channel-wise卷积层作为融合层,包含$g$个channel-wise卷积。定义输入特征维度$n$,分组数$g$,每个channel-wise卷积的stride为$g$(这里指channel上滑动的步幅),输出$n/g$特征图(滑动$n/g$次)。为了保证每个分组的输出涵盖了所有的输入,需要满足$d_c \ge g$,最后将所有的输出concate起来,结构如图c所示。

Depth-Wise Separable Channel-Wise Convolutions

  深度可分离channel-wise卷积在深度卷积后面接一个channel-wise卷积用以融合特征来降低参数量和计算量,结构如图d所示。图中的channel-wise卷积的stride为1,$d_c$为3,在进行特征融合的同时能够降低参数量。

Convolutional Classification Layer

  一般网络最后都使用全局池化和全连接层进行最后的分类,但是这样的组合的参数量十分巨大。全局池化+全连接层的组合实际可以转换成深度可分离卷积,使用固定权重的深度卷积代替全局池化,pointwise卷积代替全连接层。因此,可以进一步使用上述的深度可分离channel-wise卷积来进行优化,而这里由于池化和全连接之间没有使用激活函数或BN等操作,采用常规的三维卷积进行实现更高效。

  假设输入特征图为$m\times d_f\times d_f$,类别数为$n$,深度卷积或全局池化可以认为是卷积核大小为$d_f\times d_f\times 1$,权重固定为$1/d^2_f$的三维卷积,而channel-wise可认为是卷积核大小为$1\times 1\times d_c$的三维卷积,两者可以合并成一个卷积核大小为$d_f\times d_f\times d_c$的三维卷积。为了符合类别数量,$d_c=m-n+1$,即每个类别的预测仅需要使用$(m-n+1)$个输入特征图。

  论文可视化了全连接分类层的权重,蓝色是代表为0或接近0的权重,可以看到全连接分类层的权重实际非常稀疏,即本身也只使用到部分输入,所以这里使用部分输入特征也是合理的。

ChannelNets

  ChannelNet根据MobileNet的基础结构进行构建,设计了图3的分组模块(GM)和分组channel-wise模块(GCWM)。由于GM模块存在信息阻隔的问题,所以在GM模块前面使用GCWM来生成包含全局信息的分组特征。

  ChannelNet包含3个版本:

  • ChannelNet-v1替换了部分深度可分离卷积为GM和GCWM,分组数为2,共包含约370万参数。
  • ChannelNet-v2替换最后的深度可分离卷积为深度可分离channel-wise卷积,大约节省100万参数,占ChannelNet-v1的25%参数。
  • ChannelNet-v3替换最后的池化层加全连接层为上述的Convolutional Classification Layer,大约节省了100万(1024x1000-7x7x25)参数。

Experimental Studies


  在ILSVRC 2012进行网络性能对比。

  对比更轻量的网络性能,这里采用MobileNet的width multiplier思想缩放每层的维度。

  对比分组channel-wise卷积对ChannelNet的影响,替换GCWM为GM模块,考虑GCWM模块仅增加了32个参数,这样的性能提升是高效的。

Conclustion


  Channel-wise卷积在channel维度上进行滑动,巧妙地解决卷积操作中输入输出的复杂全连接特性,但又不会像分组卷积那样死板,是个很不错的想法。但感觉论文本身的性能还不够最优,论文对比的也只是MobileNetV1,跟MobileNetV2比差了点。



如果本文对你有帮助,麻烦点个赞或在看呗~
更多内容请关注 微信公众号【晓飞的算法工程笔记】

work-life balance.

今天关于channel is already closed due to channel error;的介绍到此结束,谢谢您的阅读,有关c# – ChannelFactory.CreateChannel如何工作?、Cannot send, channel has already failed:、ChannelHandler,ChannelHandlerContext,ChannelPipeline、ChannelNets: channel-wise卷积,在channel维度进行卷积滑动 | NeurIPS 2018等更多相关知识的信息可以在本站进行查询。

本文标签: