第一个rabbitmq应用

应用场景:由于考虑到QuestionsLibraryAndSort表中的数据经常使用,每次都要从sqlserver数据库读取,从sqlserver读取,要占用磁盘io,若网站访问量大的话,会影响网页的访问速度。而如果把整表数据放到内存中,则不会有此问题。在内存中对数据的操作,我使用的是redis内存数据库。对QuestionsLibraryAndSort做添加,更新,删除操作的时候都需要更新redis的相应值。而表中数据比较大,服务器上有10000多条数据,若直接更新,出现过超时错误的情况。因此考虑用rabbitmq来开一个线程,延迟实现。

在添加数据的时候实现向消息队列发送一条添加消息:

 //向消息队列发送消息
 var mi = new LMSoft.Web.Hubs.MessageInfo();
 mi.Content = "Add";
 mi.QuestionsLibraryAndSort = model1;
 LMSoft.Web.Hubs.RabbitMQInstance.SendEventMessageByQuestionsLibraryAndSort(mi);

messageinfo类的实现:

public class MessageInfo
    {
        public string Content { get; set; }
        public QuestionsLibraryAndSort QuestionsLibraryAndSort { get; set; }
    }

SendEventMessageByQuestionsLibraryAndSort方法实现:
 
 /// <summary>
        /// 向消息队列发送有关QuestionsLibraryAndSort添加或删除的消息
        /// </summary>
        /// <param name="mi"></param>
        public static void SendEventMessageByQuestionsLibraryAndSort(MessageInfo mi)
        {

            var sendMessage =
                EventMessageFactory.CreateEventMessageInstance<MessageInfo>(mi, MessageType.Markcode);

            RabbitMqClient.Instance.TriggerEventMessage(sendMessage, "", RabbitMQDefault);

            //EventLog.Log("添加消息:" + mi.Content, "mq");
        }

既然有发送消息处理,自然有监控消息的处理,global.asax中application_start新建一个线程:

Thread th = new Thread(() => { LMSoft.Web.Hubs.RabbitMQInstance.Listening(); });
            th.Start();

listening方法实现代码:

/// <summary>
        /// 接收信息监听并处理
        /// </summary>
        public static void Listening()
        {
            //EventLog.Log("Listening", "mq");
            RabbitMqClient.Instance.ActionEventMessage += mqClient_ActionEventMessage;
            RabbitMqClient.Instance.OnListening();
        }

private static void mqClient_ActionEventMessage(EventMessageResult result)
        {
            //EventLog.Log("mqClient_ActionEventMessage", "mq");
            if (result.EventMessageBytes.EventMessageMarkcode == MessageType.Markcode)
            {
                //EventLog.Log("mqClient_ActionEventMessage-->markcode", "mq");
                var message =
                    MessageSerializerFactory.CreateMessageSerializerInstance()
                        .Deserialize<MessageInfo>(result.MessageBytes);

                //若不存在,则创建
                if (RedisKey.RedisQuestionsLibraryAndSort == null || RedisKey.RedisQuestionsLibraryAndSort.Count <= 0)
                {
                    long count = RedisKey.QuestionsLibraryAndSortListRightPush();
                    EventLog.Log("mqClient_ActionEventMessage-->count:" + count, "mq");
                    RedisKey.RedisQuestionsLibraryAndSort = RedisHelper.ListRange<QuestionsLibraryAndSort>(RedisKey.RedisQuestionsLibraryAndSortList);
                }
                var list1 = RedisHelper.ListRange<QuestionsLibraryAndSort>(RedisKey.RedisQuestionsLibraryAndSortList);
                if (list1 == null || list1.Count <= 0)
                {
                    long count = RedisKey.QuestionsLibraryAndSortListRightPush();
                    EventLog.Log("mqClient_ActionEventMessage-->count1:" + count, "mq");
                }
                //EventLog.Log("mqClient_ActionEventMessage-->help:" + RedisHelper.ListRange<QuestionsLibraryAndSort>(RedisKey.RedisQuestionsLibraryAndSortList).Count, "mq");
                if (message.Content == "Add")
                {
                    EventLog.Log("mqClient_ActionEventMessage-->add", "mq");
                    //redis操作   
                    //在原位置出插入新行 
                    RedisKey.RedisQuestionsLibraryAndSort.Add(message.QuestionsLibraryAndSort);
                    //更改相应的redis值
                    RedisHelper.ListRightPush(RedisKey.RedisQuestionsLibraryAndSortList, message.QuestionsLibraryAndSort);

                }
                else if (message.Content == "Delete")
                {
                    EventLog.Log("mqClient_ActionEventMessage-->delete", "mq");
                    //redis操作                
                    //删除旧行
                    int success = RedisKey.RedisQuestionsLibraryAndSort.RemoveAll(m => m.GID == message.QuestionsLibraryAndSort.GID);
                    //删除相应的redis值                 
                    RedisHelper.ListRemove(RedisKey.RedisQuestionsLibraryAndSortList, message.QuestionsLibraryAndSort);

                }
                else if (message.Content == "Update")
                {
                    //EventLog.Log("mqClient_ActionEventMessage-->Update", "mq");
                    int index = RedisKey.RedisQuestionsLibraryAndSort.FindIndex(m => m.GID == message.QuestionsLibraryAndSort.GID);
                    EventLog.Log("mqClient_ActionEventMessage-->Update=>index:" + index, "mq");
                    //redis操作                
                    //删除旧行
                    int success = RedisKey.RedisQuestionsLibraryAndSort.RemoveAll(m => m.GID == message.QuestionsLibraryAndSort.GID);
                    //在原位置插入新行
                    RedisKey.RedisQuestionsLibraryAndSort.Insert(index, message.QuestionsLibraryAndSort);

                    var list = RedisHelper.ListRange<QuestionsLibraryAndSort>(RedisKey.RedisQuestionsLibraryAndSortList);

                    //EventLog.Log("mqClient_ActionEventMessage-->Update=>gid:" + message.QuestionsLibraryAndSort.GID, "mq");
                    int listIndex = list.FindIndex(m => m.GID == message.QuestionsLibraryAndSort.GID);
                    //EventLog.Log("mqClient_ActionEventMessage-->Update=>listindex:" + listIndex, "mq");
                    var model = RedisHelper.ListGetByIndex<QuestionsLibraryAndSort>(RedisKey.RedisQuestionsLibraryAndSortList, listIndex);
                    if (model != null)
                    {
                        EventLog.Log("mqClient_ActionEventMessage-->Update=>model!=null", "mq");
                        RedisHelper.ListSetByIndex(RedisKey.RedisQuestionsLibraryAndSortList, listIndex, message.QuestionsLibraryAndSort);
                    }

                }
                result.IsOperationOk = true; //处理成功

            }

这里还牵涉到RedisHelper类的实现,及对RabbitMQ操作的一个项目,由于代码较多,就不一一列出。rabbitmq的操作实现,我参考了https://github.com/Plen-wang/rabbitmqclient,做了一些修改,以便适应我的项目。有兴趣的可以看下

SimpleMessageListenerContainer 是 RabbitMQ 客户端提供的一个用于消息监听的容器,它可以实现对消息的自动监听、自动连接和重连等功能。SimpleMessageListenerContainer 的使用对于 RabbitMQ 的消息监听非常方便。 下面我们来看一下 SimpleMessageListenerContainer 的使用方法: 首先,我们需要添加 RabbitMQ 的依赖: ```xml <dependency> <groupId>org.springframework.amqp</groupId> <artifactId>spring-rabbit</artifactId> <version>2.2.11.RELEASE</version> </dependency> ``` 然后,我们需要在 Spring 配置文件中配置相关的 Bean: ```xml <!-- 创建一个 ConnectionFactory --> <bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory"> <property name="addresses" value="localhost:5672" /> <property name="username" value="guest" /> <property name="password" value="guest" /> <property name="virtualHost" value="/" /> </bean> <!-- 配置 RabbitAdmin --> <bean id="rabbitAdmin" class="org.springframework.amqp.rabbit.core.RabbitAdmin"> <constructor-arg ref="connectionFactory" /> </bean> <!-- 配置 SimpleMessageListenerContainer --> <bean id="simpleMessageListenerContainer" class="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory" /> <property name="queueNames" value="test.queue" /> <property name="messageListener" ref="messageListener" /> </bean> <!-- 配置 MessageListener --> <bean id="messageListener" class="com.example.MessageListener" /> ``` 其中,ConnectionFactory 为连接 RabbitMQ 的工厂类,RabbitAdmin 为 RabbitMQ 的管理器,SimpleMessageListenerContainer 为消息监听容器,queueNames 表示需要监听的队列名称,messageListener 表示消息的监听器类。 最后,我们需要编写一个消息监听器类 MessageListener: ```java public class MessageListener implements ChannelAwareMessageListener { @Override public void onMessage(Message message, Channel channel) throws Exception { System.out.println("接收到消息:" + new String(message.getBody())); channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); } } ``` 在这个类中,我们实现了 ChannelAwareMessageListener 接口,它是 Spring AMQP 提供的一个用于消息监听的接口,其中 onMessage 方法为消息监听回调方法。 至此,我们就可以使用 SimpleMessageListenerContainer 来实现 RabbitMQ 的消息监听了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值