如何实时监测数据库变化?
发布于 2年前 作者 42thcoder 4824 次浏览

在用node.js做一个推送信息的模块,有个问题想请教下各位。

模块要推送的信息是存在MySQL中的。如何实现数据库中有新的信息插入的时候,就通知node.js进行推送呢?

我目前有两个想法: 1、nodejs对数据库进行轮询。 2、在MySQL中设置触发器,当有新数据插入时,触发器被触发,MySQL调用nodejs进行消息的推送,推送完再关掉nodejs。

这两种想法都不太好,各位Node.jser有什么好的思路么?

最理想的是新增信息模块(基于J2EE),新增信息之后给nodejs发一条信息,但是这样如何实现呢

谢谢!

25 回复

如果不用数据库自身提供通知功能,其他什么方法效率和实时性都不高,因为摆脱不了用轮询。与Nodejs、j2ee什么的没有任何关系。

Oracle有DCN机制,可以实现实时、精确的数据变化通知。

保存数据以后做消息广播?然后各种处理器各取所需?

你的推送对象是谁?是所有在线用户,还是所有用户!还是其他?

所有用户,不管是否在线。不在线的用户会收到一个提示

问题是java如何做消息广播,而nodejs又如何接收消息呢?有相应的事件么

@42thcoder 1、广播消息给所有在线用户; 2、标记未在线收到广播的用户; 3、未收到广播消息的用户登录时,触发事件,获取(未收到广播的)消息;

@huangdh3 我是想讨论下如何实现当数据库中有新的条目插入时,能自动调用我的信息推送模块。

至于如何进行信息的推送,你给的思路还蛮不错的,谢谢~

首先是用户同时和原来的java与nodejs服务器建立连接,由nodejs服务保持连接。 然后在新增信息模块将消息存入一个队列,每隔固定时间(如500ms)向nodejs服务发送一次请求,比如http的post或UDP协议,并清空队列。 每隔固定时间发送是为了减少发送次数,根据服务的实时性可以取消或者增加。 hu.js上朋友网用nodejs做的就是这样的事情。 另一个,不理解“不在线的用户会收到一个提示”,怎么提示?提示可以拆成另一个服务,在推信息的时候可以根据用户状态判断是调用哪个服务。

多谢指点。

不在线的用户 上线之后 会收到一个新消息的提示,我可能没有表达清楚。

为什么用户需要同时和java与nodejs服务器建立连接呢?java需要做用户的验证么

hu.js是啥啊?朋友网是QQ那个?能否给个链接?

@42thcoder 你原系统不是java的吗?“新增信息模块(基于J2EE)”,通信的连接是不可以共享的啊。链接论坛里应该有,我找找。

看了一下mysql相关的资料,意外发现有个大牛的东西叫mysql-udf-http,估计很适合你的需求。可以参考这篇文章: http://blog.s135.com/mysql-udf-http/

确实很不错,多谢!

@rekey 看了几个thrift的例子,好复杂的样子

最近也打算做类似的功能.
node.js + Socket.IO 做实时推送 Java 做主要实现 Java & node.js 之间使用 mq(ActiveMQ) 进行通讯

关于插入数据/数据改动的时候通知到bowser端. 这个在java模块提供支持. 对 pojo 做改动, 或者 dao 层做 insert/update 操作的时候, boardcast 到 mq 服务器, node.js(stomp模块) 接收到消息后, push 到bowser.

这篇文章不错: node.js 通过 zeromq, redis 和其他语言交互: http://www.gridshore.nl/2011/07/28/combining-java-and-node-js-through-redis-pubsub-and-a-json-remote-interface/

@wity_lv 朋友网的好像是走内部udp协议的。

数据库有操作时候,往消息队列塞个值,去轮询这个队列。

轮询的话,效率还是有问题的

@wity_lv 呵呵,我现在做的项目中就用到了activeMQ让java与php通信,正准备用nodejs+socket.io+express+redis做实时消息,通过redis让php与nodejs通信

@42thcoder 不会啊,速度相当快了。

轮询是不科学的。 就像你说的。 1.在你保存数据到数据库的时候,同时调用nodejs推送接口 2.缓存,如redis,同样是在写数据库的同时往redis写消息队列,nodejs轮询redis消息队列。这个速度比轮询数据库要快。

最合理的方式用memcached,当PHP或者Java跟新数据库后,将需要传递给nodejs的数据同时插入memcached。nodejs用setTimeout(fn,msec),设定每秒轮询,这样效率就最高了。

其实上面大家都说了很多方案了,我补充一下吧, 用一种代理的设计模式就可以解决这个问题,统一控制插入接口入口,当有数据进行插入操作的时候,把要插入的接口加上一个中间键进行代理,而你只要控制代理实现推送就可以了。这样的话只要触发了插入就可以调用你自定义的推送方法,如果你不希望马上进行推送,需要定时推送也是没有问题的,把需要推送的数据插入到队列中,然后用nodejs默认的插件cron进行定时推送,当然也可以是py,rb,sh等,当你定时推送的时候还可以进行数据分析处理,这样可以在线和离线操作就可以分开

同意这个方案

存放推送消息队列这个功能,我个人建议还是放在内存里比较好,一条消息进入队列后很快就会被读到并且删掉,放在数据库里面磁盘io频率太高,用redis之类的服务存放会更好一些

回到顶部