V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
arnoldFu
V2EX  ›  Java

关于消息队列的实现

  •  
  •   arnoldFu · 2017-12-13 10:44:03 +08:00 · 5165 次点击
    这是一个创建于 2528 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在需要实现一个功能,每当有消息发送过来时,把消息存到队列中(假设队列最大长度为 10 ),当队列存满时将队列中的消息存入数据库中,以此来减轻数据库压力。

    目前代码实现(java)

    private BlockingQueue<Map<String, Object>> queue = new ArrayBlockingQueue<>(10);
    
    public void receiveMessage(Map item) {
    
    	synchronized(queue) {
            //入队
            queue.offer(item);
    
            //判断队列是否已满
            if (queue.size() == 10) {
                //遍历队列,插入数据库
                insert(queue);
    
                //清空队列
                queue.clear();
            }
        }
        
    }
    

    在高并发的情况下,这样写有没有问题?或者代码有没有可以优化的地方?或者使用第三方框架代替?

    第 1 条附言  ·  2017-12-13 13:54:46 +08:00
    不应该叫 消息队列,应该叫 消息缓冲队列,
    描述有问题,见谅
    18 条回复    2018-01-12 13:50:20 +08:00
    paragon
        1
    paragon  
       2017-12-13 10:57:17 +08:00
    这个不叫做消息队列~
    misaka19000
        2
    misaka19000  
       2017-12-13 10:59:54 +08:00
    楼上+1 ...

    这个同步块可能在数据量很大的情况下导致处理速度变慢
    xingwing
        3
    xingwing  
       2017-12-13 11:03:43 +08:00
    RabbitMQ
    arnoldFu
        4
    arnoldFu  
    OP
       2017-12-13 11:05:06 +08:00
    @paragon 是的,不能算作消息队列,更像是一个类似缓存的东西
    Starry
        5
    Starry  
       2017-12-13 11:07:01 +08:00
    用 MQ 或者 REDIS 队列
    holyghost
        6
    holyghost  
       2017-12-13 11:07:19 +08:00
    你这个叫 buffer 更合适吧
    arnoldFu
        7
    arnoldFu  
    OP
       2017-12-13 11:07:31 +08:00
    @misaka19000 有可以优化的方法吗?加同步是怕在插入数据库时有新的消息需要入队导致入队失败
    arnoldFu
        8
    arnoldFu  
    OP
       2017-12-13 11:08:13 +08:00
    @xingwing 感谢,我去了解一下
    arnoldFu
        9
    arnoldFu  
    OP
       2017-12-13 11:08:26 +08:00
    @Starry 感谢,我去了解一下
    jimzhong
        10
    jimzhong  
       2017-12-13 11:09:35 +08:00
    这种做法未必会有性能提升。
    arnoldFu
        11
    arnoldFu  
    OP
       2017-12-13 11:09:42 +08:00
    @holyghost 是的,叫 buffer 确实更合适
    mazyi
        12
    mazyi  
       2017-12-13 12:06:42 +08:00 via iPhone
    用个 redis 就好了
    wizardoz
        13
    wizardoz  
       2017-12-13 12:36:32 +08:00
    消息队列是一个特指的词,你这个叫做“把消息缓存到队列”可能更好一些,避免误会。
    moka20477
        14
    moka20477  
       2017-12-13 14:08:59 +08:00
    有同步代码块在高并发的时候就已经可能有性能问题了,另外不太明白这么做的意义,本身可以分散的流量,反倒让他集中 insert,而且还是遍历 insert
    mooncakejs
        15
    mooncakejs  
       2017-12-13 14:21:24 +08:00
    这个只是缓存,没有 重试 机制的队列不叫队列。
    toono
        16
    toono  
       2017-12-13 16:13:40 +08:00
    用现有的消息队列工具很好实现这个缓冲
    jowuIM
        17
    jowuIM  
       2017-12-17 23:04:32 +08:00
    。。。个人作品加个线程池就够了,队列比较复杂
    crossoverJie
        18
    crossoverJie  
       2018-01-12 13:50:20 +08:00
    synchronized 效率较低,如果是为了做同步可以用 ConcurrentLinkedQueue,我记得是基于 CAS 效率比 synchronized 要高。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5670 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 03:21 · PVG 11:21 · LAX 19:21 · JFK 22:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.