博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据库进程间通信解决方案
阅读量:6278 次
发布时间:2019-06-22

本文共 4914 字,大约阅读时间需要 16 分钟。

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

数据库与其他第三方应用程序进程间通信解决方案

MrNeo Chen (netkiller)陈景峰(BG7NYT)

中国广东省深圳市龙华新区民治街道溪山美地
518131
+86 13113668890
+86 755 29812080

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

版权 © 2011, 2012, 2013 

$Date: 2013-12-16 13:34:20 +0800 (Thu, 16 May 2013) $

摘要

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

原文出处:

我的系列文档

 

     

 


目录

1. 背景

你是否有这样的需求:

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

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

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

 

2. 解决思路

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

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

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

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

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

3. Mysql plugin

我开发了几个 UDF, 共4个 function

UDF

fifo_create(pipename)

创建管道.成功返回true,失败返回flase.

fifo_remove(pipename)

删除管道.成功返回true,失败返回flase.

fifo_read(pipename)

读操作.

fifo_write(pipename,message)

写操作 pipename管道名,message消息正文.

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

4. plugin 的开发与使用

编译UDF你需要安装下面的软件包

sudo apt-get install pkg-configsudo apt-get install libmysqlclient-devsudo apt-get install gcc gcc-c++ make automake autoconf

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

git clone https://github.com/netkiller/mysql-image-plugin.gitcd mysql-image-plugingcc -O3  -g  -I/usr/include/mysql -I/usr/include  -fPIC -lm -lz -shared -o fifo.so fifo.csudo 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;

5. 插件如何使用

插件有很多种用法,这里仅仅一个例

CREATE TABLE `demo` (	`id` INT(11) NULL DEFAULT NULL,	`name` CHAR(10) NULL DEFAULT NULL,	`mobile` VARCHAR(50) NULL DEFAULT NULL)COLLATE='utf8_general_ci'ENGINE=InnoDB;INSERT INTO `demo` (`id`, `name`, `mobile`) VALUES	(1, 'neo', '13113668891'),	(2, 'jam', '13113668892'),	(3, 'leo', '13113668893');

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

#!/bin/bash######################################### Homepage: http://netkiller.github.io# Author: neo 
########################################NAME=demoPIPE=/tmp/myfifo########################################LOGFILE=/tmp/$NAME.logPIDFILE=/tmp/${NAME}.pid########################################function start(){ if [ -f "$PIDFILE" ]; then exit 2 fi if [ ! -f "$LOGFILE" ]; then > ${LOGFILE} fi for (( ; ; )) do while read line do 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 2esacexit $?

启动守护进程

$ ./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=InnoDBCREATE 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;END

测试

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

6. 部署相关问题

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

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

转载地址:http://gcbva.baihongyu.com/

你可能感兴趣的文章
(轉貼) Eclipse + CDT + MinGW 安裝方法 (C/C++) (gcc) (g++) (OS) (Windows)
查看>>
还原数据库
查看>>
作业调度框架 Quartz.NET 2.0 beta 发布
查看>>
mysql性能的检查和调优方法
查看>>
项目管理中的导向性
查看>>
Android WebView 学习
查看>>
(转)从给定的文本中,查找其中最长的重复子字符串的问题
查看>>
HDU 2159
查看>>
spring batch中用到的表
查看>>
资源文件夹res/raw和assets的使用
查看>>
UINode扩展
查看>>
LINUX常用命令
查看>>
百度云盘demo
查看>>
概率论与数理统计习题
查看>>
初学structs2,简单配置
查看>>
Laravel5.0学习--01 入门
查看>>
时间戳解读
查看>>
sbin/hadoop-daemon.sh: line 165: /tmp/hadoop-hxsyl-journalnode.pid: Permission denied
查看>>
@RequestMapping 用法详解之地址映射
查看>>
254页PPT!这是一份写给NLP研究者的编程指南
查看>>