我们有一个ASP.Net WebAPI 2.0应用程序,它将消息发布到我们的RabbitMQ服务器。在99%的情况下,一切都很好...但随机应用程序终止与System.AccessViolationException没有明显的原因。
如何防止此失败?它可能与我们最近升级到3.6.6 C#驱动程序有关(它在升级之前工作正常吗?)
我已经消除的事情:
IModel
(我知道IModel
不是线程
安全)CreateConnection
(I
知道我可以重用连接,但我们目前没有)。连接是AutoClose = true;
以下是它爆炸的示例堆栈跟踪:
例外详细信息
System.AccessViolationException
尝试读取或写入受保护的 记忆。这通常表明其他内存已损坏。
at System.Net.UnsafeNclNativeMethods.SafeNetHandlesXPOrLater.GetAddrInfoW(String nodename,String servicename,AddressInfo&提示,SafeFreeAddrInfo& 处理) 在System.Net.Dns.TryGetAddrInfo(String name,AddressInfoHints flags,IPHostEntry& hostinfo) 在System.Net.Dns.InternalGetHostByName(String hostName,Boolean includeIPv6) 在System.Net.Dns.GetHostAddresses(String hostNameOrAddress) 在RabbitMQ.Client.TcpClientAdapter.BeginConnect(String host,Int32 port,AsyncCallback requestCallback,Object state) 在RabbitMQ.Client.Impl.SocketFrameHandler.Connect(ITcpClient套接字,AmqpTcpEndpoint端点,Int32超时) 在RabbitMQ.Client.Impl.SocketFrameHandler..ctor(AmqpTcpEndpoint端点,Func`2 socketFactory,Int32 connectionTimeout,Int32 readTimeout,Int32 writeTimeout) 在RabbitMQ.Client.Framing.Impl.ProtocolBase.CreateFrameHandler(AmqpTcpEndpoint) endpoint,Func 2 socketFactory,Int32 connectionTimeout,Int32 readTimeout,Int32 writeTimeout) 在RabbitMQ.Client.ConnectionFactory.CreateConnection(IList' 1端点,String clientProvidedName)
另一个
System.Net.UnsafeNclNativeMethods + SafeNetHandlesXPOrLater.GetAddrInfoW(System.String, System.String,System.Net.AddressInfo ByRef, System.Net.SafeFreeAddrInfo ByRef) System.Net.Dns.TryGetAddrInfo(System.String,System.Net.AddressInfoHints,System.Net.IPHostEntry ByRef) System.Net.Dns.InternalGetHostByName(System.String,Boolean) System.Net.Dns.GetHostAddresses(System.String) RabbitMQ.Client.TcpClientAdapter.BeginConnect(System.String,Int32,System.AsyncCallback,System.Object) RabbitMQ.Client.Impl.SocketFrameHandler.Connect(RabbitMQ.Client.ITcpClient, RabbitMQ.Client.AmqpTcpEndpoint,Int32) RabbitMQ.Client.Impl.SocketFrameHandler..ctor(RabbitMQ.Client.AmqpTcpEndpoint, System.Func' 2, Int32,Int32,Int32) RabbitMQ.Client.Framing.Impl.ProtocolBase.CreateFrameHandler(RabbitMQ.Client.AmqpTcpEndpoint, System.Func' 2, Int32,Int32,Int32) RabbitMQ.Client.ConnectionFactory.CreateConnection(System.Collections.Generic.IList' 1, System.String)
答案 0 :(得分:0)
我不确定你的错误发生的确切原因我需要看一些你的代码,但是我使用RabbitMQ并且发布我使用类似的类:
(更改了一些部分,因为它们与您的情况无关,例如加密,压缩等。但这将是它的基本格式)
using System;
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Framing;
namespace Messaging
{
public class MessageSender : IDisposable
{
private const string EXCHANGE_NAME = "MY_EXCHANGE";
private readonly ConnectionFactory factory;
private readonly IConnection connection;
private readonly IModel channel;
public MessageSender(string address, string username, string password)
{
factory = new ConnectionFactory {UserName = username, Password = password, HostName = address};
connection = factory.CreateConnection();
channel = connection.CreateModel();
channel.ExchangeDeclare(EXCHANGE_NAME, "topic");
}
public void Send(string payload, string topic)
{
var prop = new BasicProperties();
var data = Encoding.ASCII.GetBytes(payload);
channel.BasicPublish(EXCHANGE_NAME, topic.ToUpper(), prop, data);
}
public void Dispose()
{
try
{
channel.Dispose();
connection.Dispose();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}
这个想法是让你发出多个电话或一个电话,并在你希望的时候处理这个课程。用using语句和你的集合包装它。
在使用它的大约3 - 4年内从来没有遇到任何问题,因此您可以将此与您的代码进行对比以找出差异。
答案 1 :(得分:0)
管理从RabbitMQ用户组获得(部分)解决方案。
基本思想是IConnection对象应该被共享,因为它很难打开和关闭。每个线程只应打开新的IModel