十次方项目总结-5消息通知改进

1.RabbitMQ

什么是MQ

MQ全称为Message Queue,即消息队列。“消息队列”是在消息的传输过程中保存消息的容器。它是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦。

RabbitMQ介绍

1 每个消息都有一个称为路由键(routing key)的属性 (相当于前面介绍的地址)
2 交换机根据 [路由表]  和  [消息的 路由键] , 匹配他们, 将消息 放入一些队列里面
3 消息在队列里面, 等待被消费

RabbitMQ的优势和劣势

优势

  1. 应用解耦
  2. 异步提速
  3. 削峰填谷

劣势

  1. 系统可用性降低
  2. 系统复杂度提高
  3. 一致性问题

2.利用RabbitMQ改进文章订阅功能

controller

    //根据文章id和用户id建立订阅关系
    //http://127.0.0.1:9004/article/subscribe
    @RequestMapping(value = "/subscribe", method = RequestMethod.POST)
    public Result subscribe(@RequestBody Map map) {
        Boolean flag = articleService.subscribe(map.get("articleId").toString(),
                map.get("userId").toString());
        if (flag == true) {
            //订阅成功
            return new Result(StatusCode.OK, true, "订阅成功");
        } else {
            return new Result(StatusCode.OK, false, "取消订阅成功");
        }
    }

service 

public Boolean subscribe(String articleId, String userId) {
        //根据文章id查询作者id
        String authorId = articleDao.selectById(articleId).getUserid();
        //1.创建rabbit管理器
        RabbitAdmin rabbitAdmin = new RabbitAdmin(rabbitTemplate.getConnectionFactory());
        //2.声明Direct类型交换机,处理新增文章消息
        DirectExchange exchange = new DirectExchange("article_subscribe");
        rabbitAdmin.declareExchange(exchange);
        //3.创建队列,每个用户都有自己的队列,通过用户id区分
        Queue queue = new Queue("article_subscribe_" + userId);
        //4.声明交换机和队列的绑定关系,确保队列只能收到对应的作者消息
        //通过路由键绑定坐着,队列只能收到绑定作者的消息
        //参数分别为队列、交换机、作者id路由键
        Binding binding = BindingBuilder.bind(queue).to(exchange).with(authorId);

        //redis中用户key
        String userKey = "article_subscribe_" + userId;
        //redis中作者key
        String authorKey = "article_author_" + authorId;
        //设置redis中数据按照String类型进行序列化
        RedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setValueSerializer(stringSerializer);
        //通过用户key查询是否订阅该作者
        Boolean flag = redisTemplate.boundSetOps(userKey).isMember(authorId);
        if (flag == true) {
            //true则取消订阅
            //移除池中数据
            redisTemplate.boundSetOps(userKey).remove(authorId);
            redisTemplate.boundSetOps(authorKey).remove(userId);
            //取消订阅则取消绑定关系
            rabbitAdmin.removeBinding(binding);
            return false;
        } else {
            //false则订阅
            redisTemplate.boundSetOps(userKey).add(authorId);
            redisTemplate.boundSetOps(authorKey).add(userId);
            //订阅则声明要绑定的队列
            rabbitAdmin.declareQueue(queue);
            //添加绑定关系
            rabbitAdmin.declareBinding(binding);
            return true;
        }
    }

掌握rabbitmq的使用方法 

3.IO编程与NIO编程

IO编程:

每个客户端连接过来后,服务端都会启动一个线程去处理该客户端的请求。阻塞 I/O 的通信模型示意图如下:

这种模型每个连接都对应一个线程,当访问量大的时候存在以下问题:

  • 客户端越多就会建立越多的线程,线程是非常宝贵的资源,同一时刻有大量线程处于阻塞状态是严重的资源浪费。
  • 因为是阻塞式通信,线程爆炸后系统进行频繁的线程切换,应用性能急剧下降
  • io编程中数据读取是以字节流为单位,效率不高

NIO编程

1.NIO介绍

NIO ,也叫做 new-IO 或者 non-blocking-IO ,可理解为非阻塞 IO NIO 编程模型 中,新来一个连接不再创建一个新的线程,而是可以把这条连接直接绑定到某个固定的线程,然后这条连接所有的读写都由这个线程来负责。
NIO 模型中,可以把这么多的 while 死循环变成一个死循环,这个死循环由一 个线程控制。这就是NIO 模型中选择器( Selector )的作用,一条连接来了之后,现在不创建一个while 死循环去监听是否有数据可读了,而是直接把这条连接注册到 择器 上,通过检查这个 选择器 ,就可以批量监测(批量轮询)出有数据可读的连接,进而读取数据。
 

2.NIO组件

通道( Channel
  • 是传统 IO 中的 Stream( ) 的升级版。 Stream 是单向的、读写分离 (inputstream outputstream ), Channel 是双向的,可以进行读写操作
缓冲( Buffffer
  • Buffffer可以理解为一块内存区域,可以写入数据,并且在之后读取它
选择器( Selector
  • 选择器( Selector )可以实现一个单独的线程来监控多个注册在她上面的信道(Channel ),通过一定的选择机制,实现多路复用的效果。

3.NIO相比IO的优势所在

  • IO面向流,读写效率低下。NIO面向缓冲区,读写效率高
  • IO是阻塞式,NIO为非阻塞式,可以在等待过程中做别的事,执行效率大大提高
  • NIO引入多路复用选择器,线程数量大量减少,线程切换效率大幅度提高

4.Netty

1.概念介绍

官方术语: Netty 是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能服务器和客户端。
简单来说netty封装了底层jdk的NIO,简化了我们使用NIO编程的步骤

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值