2013-07-22 2 views
1

제 생각에는 IModel 인스턴스를 만드는 것이 합리적으로 저렴하고 그게 내가 시작한 것입니다. 모든 응용 서비스 클래스는 각 Controller과 마찬가지로 IModel을 자체적으로 가져옵니다. 잘 작동했지만 30 개 이상의 채널을 열면 조금 걱정 스럽습니다.RabbitMQ : ASP.NET MVC 응용 프로그램에서 게시

lock(publisherLock) 
    publisherModel.BasicPublish(...); 

을하지만 지금은 이유없이 논쟁의 지점이있다 :

나는 공유 IModel에 대한 액세스를 직렬화에 대해 생각했다.

그래서 메시지를 ASP.NET MVC 애플리케이션의 RabbitMQ 교환에 게시하는 올바른 방법은 무엇입니까?

답변

3

당신이해서는 안되는 일은 하나 이상의 스레드가 채널을 사용할 수 있도록하는 것이므로 몇 가지 요청에 대해 채널을 열어 두는 것은 좋지 않습니다.

할 수있는 가장 안전한 것은 당신이 게시하고 닫습니다 할 때마다 채널을 생성하는 것입니다 :

IModel 해당 인스턴스는 방법 몇이있다, 그래서 당신이 취할 수있는, 무료로 만들 저렴하지만,하지 다시 곧장. 이런 식으로 뭔가가 :

using(var model = connection.CreateModel()) 
{ 
    var properties = model.CreateBasicProperties(); 
    model.BasicPublish(exchange, routingKey, properties, msg); 
} 

당신은 응용 프로그램의 수명에 대한 열린 연결을 유지하지만, 당신이 연결을 잃어 다시 연결하는 코드가있는 경우 감지 할 확신 할 수 있습니다.

이 방법의 단점은 게시 할 때마다 채널을 만들 때 오버 헤드가 있다는 것입니다.

다른 방법으로는 전용 게시 스레드에서 채널을 열어 놓은 다음 BlockingCollection 또는 이와 유사한 방법을 사용하여 모든 게시 호출을 해당 스레드로 마샬링하는 것입니다. 이것은 더 효율적이지만 구현하기가 더 복잡합니다. 여기

1

BrokerHelper.Publish("Aplan chaplam, chaliye aai mein :P"); 

사용할 수있는 뭔가가 아래 BrokerHelper 클래스의 해상력이다.

public static class BrokerHelper 
{ 
    public static string Username = "guest"; 
    public static string Password = "guest"; 
    public static string VirtualHost = "/"; 
    // "localhost" if rabbitMq is installed on the same server, 
    // else enter the ip address of the server where it is installed. 
    public static string HostName = "localhost"; 
    public static string ExchangeName = "test-exchange"; 
    public static string ExchangeTypeVal = ExchangeType.Direct; 
    public static string QueueName = "SomeQueue"; 
    public static bool QueueExclusive = false; 
    public static bool QueueDurable = false; 
    public static bool QueueDelete = false; 
    public static string RoutingKey = "yasser"; 

    public static IConnection Connection; 
    public static IModel Channel; 
    public static void Connect() 
    { 
     var factory = new ConnectionFactory(); 
     factory.UserName = Username; 
     factory.Password = Password; 
     factory.VirtualHost = VirtualHost; 
     factory.Protocol = Protocols.FromEnvironment(); 
     factory.HostName = HostName; 
     factory.Port = AmqpTcpEndpoint.UseDefaultPort; 
     Connection = factory.CreateConnection(); 
     Channel = Connection.CreateModel(); 
    } 

    public static void Disconnect() 
    { 
     Connection.Close(200, "Goodbye"); 
    } 

    public static bool IsBrokerDisconnected() 
    { 
     if(Connection == null) return true; 
     if(Connection.IsOpen) return false; 
     return true; 
    } 

    public static void Publish(string message) 
    { 
     if (IsBrokerDisconnected()) Connect(); 

     Channel.ExchangeDeclare(ExchangeName, ExchangeTypeVal.ToString()); 
     Channel.QueueDeclare(QueueName, QueueDurable, QueueExclusive, QueueDelete, null); 
     Channel.QueueBind(QueueName, ExchangeName, RoutingKey); 
     var encodedMessage = Encoding.ASCII.GetBytes(message); 
     Channel.BasicPublish(ExchangeName, RoutingKey, null, encodedMessage); 
     Disconnect(); 
    } 
} 

추가 읽기 : Introduction to RabbitMQ with C# .NET, ASP.NET and ASP.NET MVC with examples

관련 문제