場(chǎng)景
在很多 WEB 應(yīng)用中,都會(huì)存在這樣一種場(chǎng)景,數(shù)據(jù)庫(kù)服務(wù)器(為區(qū)別扮演各種角色的數(shù)據(jù)庫(kù)產(chǎn)品,以下稱(chēng) MySQL)都位于 WEB 服務(wù)器(以下稱(chēng) Express)之后,為 Express 提供服務(wù)。這樣就帶來(lái)一個(gè)問(wèn)題,作為主動(dòng)方的 Express,無(wú)法被動(dòng)感知 MySQL 內(nèi)容的變化,一旦數(shù)據(jù)庫(kù)數(shù)據(jù)變化,而我們想要在發(fā)生這種變化時(shí)做一些邏輯時(shí),當(dāng)下現(xiàn)有的東西是無(wú)法滿(mǎn)足的。
分析
怎樣才能有效追蹤數(shù)據(jù)庫(kù)的變化?一般人會(huì)想用輪詢(xún)的方式去解決的問(wèn)題,那是最笨的方法了。這個(gè)問(wèn)題的難點(diǎn)在于如何使數(shù)據(jù)庫(kù)由被動(dòng)變成主動(dòng)的角色?,F(xiàn)在我們利用 MySQL 的一個(gè)接口 MySQL-UDF,采用發(fā)起 http 的方式,由被動(dòng)變得主動(dòng)。
所需食材與準(zhǔn)備
1. 下載與安裝 MySQL。
注意一:要到 MySQL 官網(wǎng)下載 Linux - Generic(glibc) 版本的,不然在下一步安裝 MySQL-udf-http 插件時(shí)會(huì)因各種路徑問(wèn)題痛苦無(wú)比。
-
步驟:直接參照官網(wǎng) 2.2 Installing MySQL on Unix/Linux Using Generic Binaries 即可無(wú)憂(yōu)部署好,下面也貼一下官網(wǎng)的步驟:
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 # 以后用這個(gè)開(kāi)MySQL服務(wù)
我是沒(méi)有加 MySQL 這個(gè)用戶(hù)和相關(guān)用戶(hù)組了,大家可根據(jù)個(gè)人喜好,酌量添加。
注意二:在執(zhí)行
bin/mysqld --initialize --user=mysql中的 --user=mysql 中的 user 是指你當(dāng)前 Linux 系統(tǒng)的用戶(hù),不是 MySQL 用戶(hù)。這句話(huà)之后,CLI 上會(huì)給出一個(gè)臨時(shí)密碼,要記住,一會(huì)兒還得用它進(jìn) MySQL shell 呢。-
注意三: 那個(gè)臨時(shí)密碼呦,強(qiáng)度太高了,肯定是要改成我們自己熟知的低強(qiáng)度密碼啊,所以使用上述臨時(shí)密碼進(jìn)入 MySQL shell 后,不會(huì)用正常方式改密碼的我,就直接 UPDATE 用戶(hù)表。
mysql> use mysql; mysql> UPDATE user SET authentication_string = PASSWORD('******'), Host = '%' WHERE User = 'root'; mysql> FLUSH PRIVILEGES;以上方法實(shí)踐證明真的不行,不過(guò) Host 字段是早晚要修改的,應(yīng)使用以下命令:
mysql> ALTER USER 'root@localhost' IDENTIFIED BY '******';如果服務(wù)啟了,仍然其它機(jī)器 telnet 不到本機(jī) 3306 端口,那就要檢測(cè)本機(jī)防火墻,另外,檢查位于
etc/mysql/mysql.conf.d文件中的bind-address = 127.0.0.1這一句是否打開(kāi),若是,注釋掉此句,重啟 MySQL 服務(wù)。一般來(lái)講本部分就完全可以了。
2. 安裝 MySQL-udf-http
MySQL-udf-http是已經(jīng)寫(xiě)好的 MySQL-udf 關(guān)于http 的接口,我們無(wú)需自己編寫(xiě) http 的 C 接口,只需下載已經(jīng)寫(xiě)好的,然后編譯使用即可。
-
下載 libcurl。不要使用 anaconda 集成的那個(gè),到 curl 官網(wǎng)下載,然后編譯安裝:
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,步驟如下,此處體現(xiàn)路徑的致命性:
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 中定義函數(shù)了:
#刪除 DROP FUNCTION IF EXISTS http_get; DROP FUNCTION IF EXISTS http_post; DROP FUNCTION IF EXISTS http_put; DROP FUNCTION IF EXISTS http_delete; #創(chuàng)建 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'; 實(shí)例: 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參考的資料中說(shuō)可以將 URL 和請(qǐng)求參數(shù)作為兩個(gè)參數(shù)傳入 http_get 函數(shù),我測(cè)試的是不行…可能是我笨吧,就 CONCAT 拼了下。
3. 設(shè)置MySQL 觸發(fā)器
新建一個(gè) AFTER UPDATE 觸發(fā)器:
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 ;
最后那個(gè) INTO 變量語(yǔ)句是必須的,觸發(fā)器不允許返回結(jié)果集。
4. WebSocket推送
在 Express 中開(kāi)一個(gè) API,接到 MySQL 的 HTTP 請(qǐng)求后,操作相關(guān) WebSocket 句柄實(shí)現(xiàn)推送。