zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

数据库进程间通信解决方案

2023-09-14 08:59:51 时间

$Id: MySQL-plugin.xml 587 2013-12-16 14:00:00Z netkiller $


摘要

你是否想过当数据库中的数据发生变化的时候出发某种操作?但因数据无法与其他进程通信(传递信号)让你放弃,而改用每隔一段时间查询一次数据变化的方法?下面的插件可以解决你的问题。

原文出处:http://netkiller.github.io/journal/mysql.plugin.fifo.html


你是否有这样的需求:

你需要监控访问网站的IP,当同一个IP地址访问次数过多需要做出处理,例如拉黑,直接丢进iptables 防火墙规则连中。你的做法只能每个一段时间查询一次数据库,并且判断是否满足拉黑需求?

你是否需要监控某些数据发生变化,并通知其他程序作出处理。例如新闻内容修改后,需要立即做新页面静态化处理,生成新的静态页面

你使用数据库做队列,例如发送邮件,短信等等。你要通知发送程序对那些手机或者短线发送数据

 


需要让数据库与其他进程通信,传递信号

例如,发送短信这个需求,你只要告诉发短信的机器人发送的手机号码即可,机器人永远守候那哪里,只要命令一下立即工作。

监控数据库变化的需求原理类似,我们需要有一个守护进程等待命令,一旦接到下达命令便立即生成需要的静态页面

这里所提的方案是采用fifo(First In First Out)方案,通过管道相互传递信号,使两个进程协同工作,这样的效率远比定时任务高许多。fifo是用于操作系统内部进程间通信,如果跨越操作系统需要使用Socket,还有一个新名词MQ(Message queue).

这里只做fifo演示, 将本程序改为Socket方案,或者直接集成成熟的MQ也是分分钟可以实现。


有了上面的function后你就可以在begin,commit,rollback 直接穿插使用,实现在事物处理期间做你爱做的事。也可以用在触发器与EVENT定时任务中。


https://github.com/netkiller/mysql-fifo-plugin

编译udf,最后将so文件复制到 /usr/lib/mysql/plugin/

git clone https://github.com/netkiller/mysql-image-plugin.git

cd mysql-image-plugin

gcc -O3 -g -I/usr/include/mysql -I/usr/include -fPIC -lm -lz -shared -o fifo.so fifo.c

sudo mv fifo.so /usr/lib/mysql/plugin/

 

装载

create function fifo_create returns string soname fifo.so;

create function fifo_remove returns string soname fifo.so;

create function fifo_read returns string soname fifo.so;

create function fifo_write returns string soname fifo.so;

 

卸载

drop function fifo_create;

drop function fifo_remove;

drop function fifo_read;

drop function fifo_write;

 

我们假设有一个demo这样的表,我使用shell写了一个守护进程用于处理数据库送过来的数据

 

#!/bin/bash

########################################

# Homepage: http://netkiller.github.io

# Author: neo netkiller@msn.com 

########################################

NAME=demo

PIPE=/tmp/myfifo

########################################

LOGFILE=/tmp/$NAME.log

PIDFILE=/tmp/${NAME}.pid

########################################

function start(){

 if [ -f "$PIDFILE" ]; then

 exit 2

 if [ ! -f "$LOGFILE" ]; then

 ${LOGFILE}

 for (( ; ; ))

 while read line

 NOW=$(date +%Y-%m-%d %H:%M:%S)

 echo "[${NOW}] [OK] ${line}" ${LOGFILE}

 done $PIPE

 done 

 echo $! $PIDFILE

function stop(){

 [ -f $PIDFILE ] kill `cat $PIDFILE` rm -rf $PIDFILE

case "$1" in

 start)

 start

 stop)

 stop

 status)

 ps ax | grep ${0} | grep -v grep | grep -v status

 restart)

 stop

 start

 echo $"Usage: $0 {start|stop|status|restart}"

 exit 2

exit $?

 

启动守护进程

$ ./sms.sh start

$ ./sms.sh status

 596 pts/5 S 0:00 /bin/bash ./sms.sh start

 

监控日志,因为守护进程没有输出,完成人户后写入日志。

$ tail -f /tmp/demo.log

 

开始推送任务

 

mysql select fifo_write(/tmp/myfifo,concat(mobile,\r\n)) from demo;

+-------------------------------------------------+

| fifo_write(/tmp/myfifo,concat(mobile,\r\n)) |

+-------------------------------------------------+

| true |

| true |

| true |

+-------------------------------------------------+

3 rows in set (0.00 sec)

 

现在看看日志的变化

$ tail -f /tmp/demo.log

[2013-12-16 14:55:48] [OK] 13113668891

[2013-12-16 14:55:48] [OK] 13113668892

[2013-12-16 14:55:48] [OK] 13113668893

 

我们再将上面的例子使用触发器进一步优化

 

CREATE TABLE `demo_sent` (

 `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,

 `mobile` VARCHAR(50) NOT NULL,

 `status` ENUM(true,false) NOT NULL DEFAULT false,

 `ctime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

 PRIMARY KEY (`id`)

COLLATE=utf8_general_ci

ENGINE=InnoDB

CREATE DEFINER=`dba`@`%` TRIGGER `demo_after_insert` AFTER INSERT ON `demo` FOR EACH ROW BEGIN

 insert into demo_sent(mobile,status) select new.mobile,fifo_write(/tmp/myfifo,concat(new.mobile,)) as status;

 

测试

 

mysql insert into demo(name,mobile) values(jerry,13322993040);

Query OK, 1 row affected (0.05 sec) 

 

日志变化

$ tail -f /tmp/demo.log 

[2013-12-16 14:55:48] [OK] 13113668891

[2013-12-16 14:55:48] [OK] 13113668892

[2013-12-16 14:55:48] [OK] 13113668893

[2013-12-16 14:55:48] [OK] 13322993040

 

我们可以采用主从数据库,将任务放在专用的从库上执行

我们可以创建很多个管道,用于做不同的工作,例如插入一个任务,更新一个任务,发短信一个任务,处理模板与静态化一个任务等等。


netkiller Nickname:netkiller | English name: Neo chen | QQ: 291379 | 订阅号:netkiller-ebook | 网站:http://www.netkiller.cn