MySQL-UDF-HTTP + Express + WebSocket 实现数据库推送

场景

在很多 WEB 应用中,都会存在这样一种场景,数据库服务器(为区别扮演各种角色的数据库产品,以下称 MySQL)都位于 WEB 服务器(以下称 Express)之后,为 Express 提供服务。这样就带来一个问题,作为主动方的 Express,无法被动感知 MySQL 内容的变化,一旦数据库数据变化,而我们想要在发生这种变化时做一些逻辑时,当下现有的东西是无法满足的。

分析

怎样才能有效追踪数据库的变化?一般人会想用轮询的方式去解决的问题,那是最笨的方法了。这个问题的难点在于如何使数据库由被动变成主动的角色。现在我们利用 MySQL 的一个接口 MySQL-UDF,采用发起 http 的方式,由被动变得主动。

所需食材与准备

1. 下载与安装 MySQL

  • 注意一:要到 MySQL 官网下载 Linux - Generic(glibc) 版本的,不然在下一步安装 MySQL-udf-http 插件时会因各种路径问题痛苦无比。

  • 步骤:直接参照官网 2.2 Installing MySQL on Unix/Linux Using Generic Binaries 即可无忧部署好,下面也贴一下官网的步骤:

    shell> groupadd mysql
    shell> useradd -r -g mysql -s /bin/false mysql
    shell> cd /usr/local
    shell> tar zxvf /path/to/mysql-VERSION-OS.tar.gz
    shell> ln -s full-path-to-mysql-VERSION-OS mysql
    shell> cd mysql
    shell> mkdir mysql-files
    shell> chown mysql:mysql mysql-files
    shell> chmod 750 mysql-files
    shell> bin/mysqld --initialize --user=mysql 
    shell> bin/mysql_ssl_rsa_setup              
    shell> bin/mysqld_safe --user=mysql &
    # Next command is optional
    shell> cp support-files/mysql.server /etc/init.d/mysql.server
    shell> sudo /etc/init.d/mysql.server restart # 以后用这个开MySQL服务
    

我是没有加 MySQL 这个用户和相关用户组了,大家可根据个人喜好,酌量添加。

  • 注意二:在执行 bin/mysqld --initialize --user=mysql 中的 --user=mysql 中的 user 是指你当前 Linux 系统的用户,不是 MySQL 用户。这句话之后,CLI 上会给出一个临时密码,要记住,一会儿还得用它进 MySQL shell 呢。

  • 注意三: 那个临时密码呦,强度太高了,肯定是要改成我们自己熟知的低强度密码啊,所以使用上述临时密码进入 MySQL shell 后,不会用正常方式改密码的我,就直接 UPDATE 用户表。

    mysql> use mysql;
    mysql> UPDATE user SET authentication_string = PASSWORD('******'), Host = '%' WHERE User = 'root';
    mysql> FLUSH PRIVILEGES;
    

    以上方法实践证明真的不行,不过 Host 字段是早晚要修改的,应使用以下命令:

    mysql> ALTER USER 'root@localhost' IDENTIFIED BY '******';
    

    如果服务启了,仍然其它机器 telnet 不到本机 3306 端口,那就要检测本机防火墙,另外,检查位于 etc/mysql/mysql.conf.d 文件中的 bind-address = 127.0.0.1 这一句是否打开,若是,注释掉此句,重启 MySQL 服务。一般来讲本部分就完全可以了。

2. 安装 MySQL-udf-http

MySQL-udf-http是已经写好的 MySQL-udf 关于http 的接口,我们无需自己编写 httpC 接口,只需下载已经写好的,然后编译使用即可。

  • 下载 libcurl。不要使用 anaconda 集成的那个,到 curl 官网下载,然后编译安装:

    tar zxvf curl-7.59.0.tar.gz
    cd curl-7.21.1/
    ./configure --prefix=/usr
    make && make install
    
  • 下载安装 mysql-udf-http。下载地址是:http://pan.baidu.com/s/1nuYZqR3,步骤如下,此处体现路径的致命性:

    tar zxvf mysql-udf-http-1.0.tar.gz
    cd mysql-udf-http-1.0
    ./configure --prefix=/usr/local/mysql-udf-http --with-mysql=/usr/local/mysql/bin/mysql_config
    make && make install
    ln -s /usr/local/mysql-udf-http/lib/mysql-udf-http.so.0.0.0 /usr/local/mysql/lib/plugin/mysql-udf-http.so
    service mysql restart
    
  • 插件安装好了,下面要在 MySQL 中定义函数了:

    #删除
    DROP FUNCTION IF EXISTS http_get;
    DROP FUNCTION IF EXISTS http_post;
    DROP FUNCTION IF EXISTS http_put;
    DROP FUNCTION IF EXISTS http_delete;
    #创建
    CREATE FUNCTION http_get returns string soname 'mysql-udf-http.so';
    CREATE FUNCTION http_post returns string soname 'mysql-udf-http.so';
    CREATE FUNCTION http_put returns string soname 'mysql-udf-http.so';
    CREATE FUNCTION http_delete returns string soname 'mysql-udf-http.so';
    实例:
    SELECT http_get('some url') AS res;
    SELECT http_get(CONCAT('http://192.168.1.140:3000/mysql-event-server/role-privilege-refresh?roleid=', OLD.grp_rolnum)) INTO @tmp
    

    参考的资料中说可以将 URL 和请求参数作为两个参数传入 http_get 函数,我测试的是不行…可能是我笨吧,就 CONCAT 拼了下。

3. 设置MySQL 触发器

新建一个 AFTER UPDATE 触发器:

DROP TRIGGER `privilegeUpdate`;
CREATE DEFINER=`root`@`%` TRIGGER `privilegeUpdate` AFTER UPDATE ON `pub_rolperminfo`
FOR EACH ROW SELECT http_get(CONCAT('http://192.168.1.140:3000/mysql-event-server/role-privilege-refresh?roleid=', OLD.grp_rolnum)) INTO @tmp ;

最后那个 INTO 变量语句是必须的,触发器不允许返回结果集。

4. WebSocket推送

Express 中开一个 API,接到 MySQLHTTP 请求后,操作相关 WebSocket 句柄实现推送。

参考资料

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352