1. 程式人生 > 其它 >資料庫程序間通訊解決方案之MQ

資料庫程序間通訊解決方案之MQ

資料庫程序間通訊解決方案之MQ

摘要

你是否想過當資料庫中的資料發生變化的時候出發某種操作?但因資料無法與其他程序通訊(傳遞訊號)讓你放棄,而改用每隔一段時間查詢一次資料變化的方法?下面的外掛可以解決你的問題。

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


目錄

  • 1. 背景
  • 2. 應用場景
  • 3. Mysql plugin
  • 4. plugin 的開發與使用
  • 5. 外掛如何使用

1. 背景

之前我發表過一篇文章 http://netkiller.github.io/journal/mysql.plugin.fifo.html

該文章中提出了通過fifo 管道,實現資料庫與其他程序的通訊。屬於 IPC 機制(同一個OS/伺服器內),後我有采用ZeroMQ重新實現了一個 RPC 機制的方案,同時相容IPC(跨越OS/伺服器)

各種縮寫的全稱 IPC(IPC :Inter-Process Communication 程序間通訊),ITC(ITC : Inter Thread Communication 執行緒間通訊)與RPC(RPC: Remote Procedure Calls遠端過程呼叫)。

支援協議

inproc://my_publisher
tcp://server001:5555
ipc:///tmp/feeds/0		

2. 應用場景

如果你像處理資料,由於各種原因你不能在程式中實現,你可以使用這個外掛。當資料庫中的資料發生變化的時候出發某種操作,你可以使用這個外掛。

有時候你的專案可能是外包的,專案結束後外包方不會在管你,你有無法改動現有程式碼,或者根本不敢改。你可以使用這個外掛

採用MQ技術對資料庫無任何壓力,與採用程式處理並無不同,省卻了寫程式碼

處理方法,可以採用同步或者非同步方式

例 1. 傳送簡訊

傳送簡訊、郵件,只需要查詢出相應手機號碼,傳送到MQ的服務端,服務端接收到手機號碼後,放入佇列中,多執行緒程式從佇列中領取任務,傳送簡訊。

select zmq_client('tcp://localhost:5555',mobile) from demo where subscribed='Y' ...;			

傳遞多個引數,可以使用符號分隔

select zmq_client('tcp://localhost:5555',concat(name,',',mobile,', news')) from demo;
select zmq_client('tcp://localhost:5555',concat(name,'|',mobile,'|news')) from demo;			

json格式

select zmq_client('tcp://localhost:5555',concat('{name:',name,', tel:',mobile,', template:news}')) from demo;			

建議採用非同步方式,MQ端接收到任務立即反饋 “成功”資訊,因為我們不太關心是否能傳送成功,本身就是盲目性的傳送,手機號碼是否可用我們無從得知,簡訊或者郵件的傳送到達率不是100%,所以當進入佇列後,讓程式自行處理,將成功或者失敗資訊記錄到日誌中即可。

例 2. 處理圖片

首先查詢出需要處理圖片,然後將路徑與解析度傳遞給MQ另一端的處理程式

select zmq_client('tcp://localhost:5555',concat(image,',800x600}')) from demo;			

建議採用非同步方式,MQ端接收到任務立即反饋 “成功”資訊

例 3. 身份證號碼校驗

select zmq_client('tcp://localhost:5555',id_number) from demo;			

可以採用同步方案,因為MQ款處理幾乎不會延遲,直接將處理結構反饋

例 4. 靜態化案例

情景模擬,你的專案是你個電商專案,採用外包模式開發,專案已經開發完成。外包放不再負責維護,你現在要做靜態化。增加該功能,你要檢查多處與商品表相關的造作。

於其改程式碼,不如程式從外部處理,這樣更保險。我們只要寫一個程式將動態 URL 下載儲存成靜態即可,當資料發生變化的時候重新下載覆蓋即可

CREATE DEFINER=`dba`@`%` TRIGGER `demo_after_insert` AFTER INSERT ON `demo` FOR EACH ROW BEGIN
	select zmq_client('tcp://localhost:5555', NEW.id);
END
CREATE DEFINER=`dba`@`%` TRIGGER `demo_after_update` AFTER UPDATE ON `demo` FOR EACH ROW BEGIN
	select zmq_client('tcp://localhost:5555', NEW.id);
END
CREATE DEFINER=`dba`@`%` TRIGGER `demo_after_delete` AFTER DELETE ON `demo` FOR EACH ROW BEGIN
	select zmq_client('tcp://localhost:5555', NEW.id);
END			

MQ 另一端的服務會下載http://www.example.com/goods.php?cid=111&id=100, 然後生成html頁面,http://www.example.com/111/100.html

插入會新建頁面,更新會覆蓋頁面,刪除會刪除頁面

這樣無論商品的價格,屬性改變,靜態化程式都會做出相應的處理。

例 5. 資料同步案例

我們有多個數據庫,A 庫裡面的資料發生變化後,要同步書庫到B庫,或者處理結果,或者資料轉換後寫入其他資料庫中

方法也是採用觸發器或者EVENT處理

3. Mysql plugin

我開發了幾個 UDF, 共4個 function

UDF

  • zmq_client(sockt,message)
  • sockt .成功返回true,失敗返回flase.

有了上面的function後你就可以在begin,commit,rollback 直接穿插使用,實現在事物處理期間做你愛做的事。也可以用在觸發器與EVENT定時任務中。

4. plugin 的開發與使用

編譯UDF你需要安裝下面的軟體包

sudo apt-get install pkg-config
sudo apt-get install libmysqlclient-dev

sudo apt-get install gcc gcc-c++ make cmake		

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

編譯udf,最後將so檔案複製到 /usr/lib/mysql/plugin/

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

cmake .
make && make install		

裝載

create function zmq_client returns string soname 'libzeromq.so';
create function zmq_publish returns string soname 'libzeromq.so';		

解除安裝

drop function zmq_client;
drop function zmq_publish;		

確認安裝成功

		mysql> SELECT * FROM `mysql`.`func` where name like 'zmq%';
+-------------+-----+--------------+----------+
| name        | ret | dl           | type     |
+-------------+-----+--------------+----------+
| zmq_client  |   0 | libzeromq.so | function |
| zmq_publish |   0 | libzeromq.so | function |
+-------------+-----+--------------+----------+
2 rows in set (0.00 sec)		

5. 外掛如何使用

外掛有很多種用法,這裡僅僅一個例

編譯zeromq server 測試程式

cd test
cmake .
make		

啟動服務程序

./server		

傳送Hello world!

		mysql> select zmq_client('tcp://localhost:5555','Hello world!');
+---------------------------------------------------+
| zmq_client('tcp://localhost:5555','Hello world!') |
+---------------------------------------------------+
| Hello world! OK                                   |
+---------------------------------------------------+
1 row in set (0.01 sec)		

檢視伺服器端是否接收到資訊。

$ ./server
Received: Hello world!		

我們再將上面的例子使用觸發器進一步優化

		mysql> select zmq_client('tcp://localhost:5555',mobile) from demo;
+-------------------------------------------+
| zmq_client('tcp://localhost:5555',mobile) |
+-------------------------------------------+
| 13113668891 OK                            |
| 13113668892 OK                            |
| 13113668893 OK                            |
| 13322993040 OK                            |
| 13588997745 OK                            |
+-------------------------------------------+
5 rows in set (0.03 sec)		

伺服器端已經接收到資料庫發過來的資訊

$ ./server
Received: Hello world!
Received: 13113668891
Received: 13113668892
Received: 13113668893
Received: 13322993040
Received: 13588997745		

我們可以拼裝json或者序列化資料,傳送給遠端

		mysql> select zmq_client('tcp://localhost:5555',concat('{name:',name,', tel:',mobile,'}')) from demo;
+------------------------------------------------------------------------------+
| zmq_client('tcp://localhost:5555',concat('{name:',name,', tel:',mobile,'}')) |
+------------------------------------------------------------------------------+
| {name:neo, tel:13113668891} OK                                               |
| {name:jam, tel:13113668892} OK                                               |
| {name:leo, tel:13113668893} OK                                               |
| {name:jerry, tel:13322993040} OK                                             |
| {name:tom, tel:13588997745} OK                                               |
+------------------------------------------------------------------------------+
5 rows in set (0.03 sec)		

返回資料取決於你服務端怎麼編寫處理程式,你可以返回true/false等等。

觸發器以及事務處理,這裡就不演示了