RabbitMq笔记(2)

今天收获不少,记个笔记。

 1 namespace RabbitMQTest
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             Consumer();
 8             //Console.WriteLine("方法————{0}",Thread.CurrentThread.ManagedThreadId);
 9 
10             //Thread thread = new Thread(Consumer);
11             //thread.Start();
12             //Console.WriteLine("线程1————{0}", Thread.CurrentThread.ManagedThreadId);
13             //Thread tt = new Thread(
14             //    () => {
15             //        Consumer();
16             //    }
17             //    );
18             //tt.Start();
19 
20             Task task = new Task(Consumer);
21             task.Start();
22 
23             TaskFactory tf = new TaskFactory();
24             Task t =  tf.StartNew(Consumer);
25             //Console.WriteLine("线程2————{0}", Thread.CurrentThread.ManagedThreadId);
26             Console.ReadLine();
27         }
28 
29         private static void Consumer()
30         {
31             Console.WriteLine("线程开始,ID:" + Thread.CurrentThread.ManagedThreadId);
32             var factory = new ConnectionFactory() { HostName = "localhost" };
33             using (var connection = factory.CreateConnection())
34             using (var channel = connection.CreateModel())
35             {
36                 //声明queue
37                 channel.QueueDeclare(queue: "hellos",//队列名
38                                      durable: false,//是否持久化
39                                      exclusive: false,//true:排他性,该队列仅对首次申明它的连接可见,并在连接断开时自动删除
40                                      autoDelete: false,//true:如果该队列没有任何订阅的消费者的话,该队列会被自动删除
41                                      arguments: null);//如果安装了队列优先级插件则可以设置优先级
42 
43                 string message = "Hello World!";//待发送的消息
44                 var body = Encoding.UTF8.GetBytes(message);
45                 for (int i = 0; i < 5; i++)
46                 {
47                     channel.BasicPublish(exchange: "",//exchange名称
48                                          routingKey: "hellos",//如果存在exchange,则消息被发送到名称为hello的queue的客户端
49                                          basicProperties: null,
50                                          body: body);//消息体
51                     Console.WriteLine(" [x] Sent {0}", message);
52                 }
53             }
54         }
55     }
56 }
生产者
 1 namespace RabbitXiaoFei
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             //var factory = new ConnectionFactory() { HostName = "localhost", UserName = "ty2017", Password = "123456", VirtualHost = "log" };
 8             var factory = new ConnectionFactory() { HostName = "localhost" };
 9             using (var connection = factory.CreateConnection())
10             using (var channel = connection.CreateModel())
11             {
12                 channel.QueueDeclare(queue: "hellos",//指定发送消息的queue,和生产者的queue匹配
13                                      durable: false,//耐用的,持久的
14                                      exclusive: false,//独有的;排外的;专一的
15                                      autoDelete: false,//
16                                      arguments: null);
17 
18                 //设置预取消息的数量为1个,消费完当前的消息后再去获取下一个消息
19                 //就是有多个消费者去请求队列的时候,序号为奇数的会给第一个,为偶数的会给第二个
20                 //但是如果第一个要耗费很长时间,那么第二个就得等,那就很消耗资源了
21                 //要是每个Consumer处理完一个消息后再去获取下一个消息,这是多么理想呀!
22                 channel.BasicQos(0,  //设置0
23                                  1, //设置当前Consumer的预取数量为1个就行啦!
24                                  false); //设置false  
25 
26                 var consumer = new EventingBasicConsumer(channel);
27                 //注册接收事件,一旦创建连接就去拉取消息
28                 consumer.Received += (obj, sss) =>
29                 {
30                     var body = sss.Body;
31                     var message = Encoding.UTF8.GetString(body);
32                     Console.WriteLine(" [x] Received {0}", message);
33                 };
34                 channel.BasicConsume(queue: "hellos",
35                                      autoAck:true,//Ack :确认
36                                                   //和tcp协议的ack一样,为false则服务端必须在收到客户端的回执(ack)后才能删除本条消息
37                                      consumer: consumer);
38                 Console.WriteLine(" Press [enter] to exit.");
39                 Console.ReadLine();
40             }
41         }
42     }
43 }
消费者

 New 生产者

            ConnectionFactory factory = new ConnectionFactory
            {
                UserName = "guest",//用户名
                Password = "guest",//密码
                HostName = "127.0.0.1",//rabbitmq ip
                //VirtualHost = "/"
            };

            //创建连接
            var connection = factory.CreateConnection();
            //创建通道
            var channel = connection.CreateModel();
            //声明一个队列    (队列名字,是否持久化,是否自动删除队列,是否排外的,是否等待服务器返回)
            channel.QueueDeclare("queuename_zkb", false, false, false, null);           
            Guid guid = new Guid();           
            var sendBytes = Encoding.UTF8.GetBytes(guid.ToString());
            //发布消息         (交换器名称,路由键,是否为强制性,
            channel.BasicPublish("", "queuename_zkb", null, sendBytes);
            channel.Close();
            connection.Close();

New 消费者

  IConnectionFactory connFactory = new ConnectionFactory//创建连接工厂对象
            {
                HostName = "127.0.0.1",//IP地址
                //Port = 5672,//端口号
                UserName = "guest",//用户账号
                Password = "guest"//用户密码
            };
            using (IConnection conn = connFactory.CreateConnection())
            {
                using (IModel channel = conn.CreateModel())
                {
                    String queueName = String.Empty;
                    queueName = "queuename_zkb";
                    //声明一个队列
                    channel.QueueDeclare(
                      queue: queueName,//消息队列名称
                      durable: false,//是否缓存
                      exclusive: false,
                      autoDelete: false,
                      arguments: null
                       );
                    //创建消费者对象
                    var consumer = new EventingBasicConsumer(channel);
                    consumer.Received += (model, ea) =>
                    {
                        byte[] message = ea.Body;//接收到的消息
                        Console.WriteLine("接收到信息为:" + Encoding.UTF8.GetString(message));

                        ViewData["1212"] = Encoding.UTF8.GetString(message);
                        //_logger.LogError("我是错误显示")
                    };
                    //消费者开启监听
                    channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer);
                   
                }
            }

 

 

 这个是在多个消费者的时候用到的,假如发给A消费,那就发一条给他,然后收到A的确认消息时候,在发给n消费者。一定是收到A的确认消息

下面的这张图,这样就变成了:公平分发⭐⭐⭐⭐(不加这些code的是轮询分发)

 

 假如来了一批活需要1和2处理,2的能力比1强,那么这两个消费者就都是每次只取一条信息,但是2的能力强,2就做的多,这也叫能者多劳

 

 

 

关于ConnectionFactory

看了几个用到ConnectionFactory这个类的项目,和在网上看的几个博客,都是与队列这样的需要提供HostUrl,username,pwd等等因素。

所以应该就是将这些打包进行链接而已。

 

public class RabbitBasic
    {    
        public ConnectionFactory Factory;     public RabbitBasic()
        {
            string host = System.Configuration.ConfigurationManager.AppSettings.Get("RabbitMQHost");
            string pwd = System.Configuration.ConfigurationManager.AppSettings.Get("RabbitMQPwd");
            string username = System.Configuration.ConfigurationManager.AppSettings.Get("RabbitMQUserName");
            string vhost = System.Configuration.ConfigurationManager.AppSettings.Get("RabbitMQVirtualHost");

            //实例化连接工厂
            Factory = new ConnectionFactory()
            {
                HostName = host,
                Password = pwd,
                UserName = username,
                VirtualHost = vhost,
            };
        }
    }
public class RabbitReceiver : RabbitBasic
    {
        public void Start()
        {
            var connection = Factory.CreateConnection();//这里就是已经链接上了RabbitMQ
            var channel = connection.CreateModel();
            channel.QueueDeclare(queue: PickRelease, durable: true, exclusive: false, autoDelete: false, arguments: null);
            channel.BasicQos(0, 1, false);
}
}

这个RabbitReceiver就是继承了RabbitBasic这个类,就是可以使用父类中的Factory这个类。
拿来就可以用,这样这里就不用再写链接Rabbit的那一套操作了。
说白了,就是一个多个参数的链接对象进行下封装。
被继承的拿来用就好了。

注:一般链接数据库的那种字符串,一般就是直接一个字符串直接干。



 

 

RabbitMQ消息超时时间、队列消息超时时间、队列超时时间

 

 

 

 

 

 

 

 

 

 

posted @ 2018-07-19 22:15  ProZkb  阅读(153)  评论(0编辑  收藏  举报