MySQL-UDF-HTTP + Express + WebSocket 实现数据库推送 - Go语言中文社区

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 句柄实现推送。

参考资料

版权声明:本文来源简书,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://www.jianshu.com/p/b1b794e12013
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-01-12 13:23:50
  • 阅读 ( 1179 )
  • 分类:数据库

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢