2017-01-16 1 views
0

우리는 RabbitMQ Server에 메시지를 게시하는 ASP.Net WebAPI 2.0 응용 프로그램이 있습니다. 99 %의 케이스에서 모두 정상입니다 ... 그러나 무작위로 응용 프로그램이 명백한 이유없이 System.AccessViolationException으로 종료됩니다.RabbiMQ C# 드라이버로 인해 System.AccessViolationException이 발생합니다.

이 오류를 어떻게 방지 할 수 있습니까? 최근의 3.6.6 C# 드라이버 업그레이드와 관련이 있습니까? (업그레이드 전에는 잘 돌아 갔습니까?)

상황이 이미 제거했다 :

이 새로운 IModel 각에 사용되는
  1. 게시 호출 각 호출에 대해 CreateConnection로 구성되어
  2. 뿐만 아니라 (I (나는 IModel 안전 스레드 아니라는 것을 알고) 연결을 다시 사용할 수 있음을 알고 있지만 현재 연결하지는 않습니다.) 연결 채널은 사용하는 블록에서 사용 AutoClose = true;
  3. 이다 .. 그래서 각 시간 여기

그것은 폭발 여기서의 샘플 스택 트레이스이다 배치되어

예외 정보

에게 System.AccessViolationException

는 읽거나 01 쓰기 방지 시도메모리. 이것은 종종 다른 메모리가 손상되었다는 표시입니다. System.Net.Dns.TryGetAddrInfo (문자열 이름, AddressInfoHints 플래그에는 IPHostEntry & hostinfo는에서

System.Net.UnsafeNclNativeMethods.SafeNetHandlesXPOrLater.GetAddrInfoW에서

(문자열 노드 이름, 문자열 서비스 이름, AddressInfo & 힌트, SafeFreeAddrInfo & 핸들) ) RabbitMQ.Client.TcpClientAdapter.BeginConnect에서 System.Net.Dns.GetHostAddresses에서 System.Net.Dns.InternalGetHostByName (문자열 호스트 이름, 부울 includeIPv6) (문자열 hostNameOrAddress) (문자열 호스트, INT32 포트, AsyncCallback requestCallback 개체에서 상태) at RabbitMQ.Client.Impl.SocketFrameHandler.Connect (ITcpClient 소켓 AmqpTcpEndpoint 끝점 INT32 타임 아웃) (AmqpTcpEndpoint 끝점 Func`2의 SocketFactory, INT32은 ConnectionTimeout, INT32 readTimeout, INT32 writeTimeout) RabbitMQ.Client.Impl.SocketFrameHandler..ctor에서 RabbitMQ.Client.Framing.Impl에서 .ProtocolBase.CreateFrameHandler (AmqpTcpEndpoint 엔드 포인트, Func'2의 SocketFactory, INT32은 ConnectionTimeout, INT32 readTimeout, INT32 writeTimeout) RabbitMQ.Client.ConnectionFactory.CreateConnection에서 (IList'1 엔드 포인트, 문자열 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 (시스템.String, Boolean) RabbitMQ.Client.TypeClientAdapter.BeginConnect (System.String, Int32, (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

나는 당신의 오류가 나는 그것을 위해 코드의 일부를 볼 필요가 발생하는 이유를 정확하게 모르겠어요,하지만 난 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 년 만에이 문제에 대해 한 가지 문제가 발생하지 않았으므로 차이를 찾기 위해 코드와 대조 할 수 있습니다.

+0

입력 해 주셔서 감사합니다.
우리의 구현은 매번 새로운 "Sender"클래스를 생성하지는 않지만, Channel을 using으로 래핑했습니다.
기록을 위해, 저의 구현은 3 년 동안 아무런 문제없이 잘 진행되어 왔습니다. 최근에 실패하기 시작했습니다. 아마도 방금 업그레이드 한 버전의 버그입니다 (3.6.6)

+0

실행중인 RabbitMQ의 버전은 무엇입니까? 우리는 3.6.4에 몇 가지 문제점을 발견했습니다. 주요한 것은 심장 박동이 클라이언트에서 결점을 유발하고 연결을 끊을 것입니다. (패치 노트에 따르면 3.3.6에서 수정 됨) 오류 처리에 따라 이것이 될 수도 있습니다. "heartbeats"가 문제 인 .NET rabbitmq 클라이언트에서 발생한 오류를 나열한 Windows 이벤트 로그를 통해서만 알 수 있습니다. – Kelly

+0

우리의 드라이버는 3.6.6입니다 .... 서버에 대해 잘 모르겠습니다 만, 확인할 수 있습니다. –

0

RabbitMQ 사용자 그룹에서이 문제를 부분적으로 처리하도록 관리합니다. 여기

세부 사항 : Rabbit MQ Users Group

기본 아이디어는 열 무겁고 가까이로 IConnection 객체가 공유해야한다는 것입니다. 각 스레드에 대해 IModel 만 새로 열어야합니다.

관련 문제