[Redis] แจ้งเตือน Key expired โดย Key space notifications ผ่าน Nodejs กัน
ก่อนอื่นขอเกริ่นก่อนนะครับ พอดีว่าที่ทำงานผมมีโปรเจคหนึ่งที่กำลังทำอยู่เกี่ยวกับการซื้อขายแต่ โจทย์มีอยู่ว่า หลังจากการซื้อขายนั้นเงินจะยังไม่ถูกโอนไปยังคนขายจะต้องรอการยืนยันบางอย่างก่อนแล้วของที่ผู้ขายจะถูกจองไว้เป็นเวลา 2 วัน ถ้าหากสองวันนั้นไม่มีการยืนยันตัว transaction นั้นก็จะถูกยกเลิกไป แล้วของที่อยู่ในสถานะการจองก็จะถูกยกเลิกเหมือนกัน
หลังจากที่ค้นหาข้อมูลวิธีการทำให้ง่ายที่สุดตามสไตล์คนขี้เกียจแล้วก็ได้ไปเจอ feature Key space notifications ที่เจ๋งสุดๆของ Redis เข้าให้โดยหลักการทำงานก็จะเป็น Publish/Subscribe โดยที่หลักจากที่ key ของเราหมดอายุมันก็จะส่ง event Expired มาที่ Application ของเราจาก Topic/Channel ที่เราไป subscribe นั้นเอง
เริ่มต้นสำหรับคนที่ไม่มี Redis อย่างผมก็ต้องลง Redis ผ่าน docker ก่อนนะครับ
$ docker run -d --name redis-notification -p 6379:6379 redis
ซึ่งหลังจากที่รัน docker แล้วผมได้ทำการสร้าง project ขึ้นมาใหม่จาก express-generator ขอใช้ชื่อว่า nodejs-redis-keyspace-notifications ละกันครับ
จากนั้นติดตั้ง package ioRedis ซึ่งเป็น redis client สำหรับเชื่อมต่อกับ service Redis ของเรา
$ npm install ioredis
เพิ่ม configuration สำหรับ Redis เข้าไปที่ app.js
// Redis configuration
const ioRedis = require('ioredis')
const host = 'localhost'
const port = 6379
const db = 0
const password = ''/* Setup redis client and set key-space-notification event when key expired */
const redis = new ioRedis({host, port, db, password})
redis.on('ready', ()=> {
redis.config('SET', 'notify-keyspace-events', 'Ex')
})
SET notify-keyspace-events EX เป็นการกำหนดให้ service redis enable feature notify-keyspace-events ซึ่ง parameter E หมายถึงการ กำหนด Keyevent event ให้ publish ข้อความออกมาโดยเราจะต้องไป subscribe topic = “__keyevent@<db>__ prefix” ส่วน parameter x คือ expired event จะถูกสร้างขึ้นหลังจากที่ key นั้นๆ ของเรา expired ไปแล้ว
หลังจากเรา config ค่าสำหรับ client ที่จะไปเชื่อมต่อ Service Redis เสร็จแล้วให้เรา Client สำหรับ subscribe topic Expired ที่ถูก publish มาจาก Redis ของเรา
const subscriber = new ioRedis({ host, port, db, password })
subscriber.subscribe("__keyevent@0__:expired")
subscriber.on('message',async (channel, message) => {
// Do somethings
console.log(message);
})
เป็นอันเสร็จสิ้นสำหรับการ config จากนั้นทดสอบรัน application ของเราดูครับ
ทดสอบรันก่อน~~
รันผ่านแล้วสามารถเชื่อมต่อกับ Service Redis ได้แล้ว จากนั้นลอง set คีย์พร้อมกับกำหนด expired time เข้าไปสัก 5 วินาทีครับ
หลังจากผ่านไป 5 วินาที Service Redis ก็ส่ง event มาด้วย เป็นอันว่า application ของเราทำงานโดยไม่พบ BUG ครับ 55555
เป็นอันว่าโปรเจคที่ทำงานของผมก็เดินหน้าต่อไปได้แล้วครับ 5555 ขอบคุณทุกท่านที่เข้ามาอ่านกันนะครับ สำหรับวันนี้ขอบคุณและสวัสดีครับ
ส่วนตรงนี้เป็น github ของตัว project นะครับพี่ๆน้องๆ สามารถ clone มาลองเล่นดูกันได้ครับ
https://github.com/toygame/nodejs-redis-keyspace-notifications
Keyspace notifications allow clients to subscribe to Pub/Sub channels in order to receive events affecting the Redis data set in some way.
ioredis is a robust, full-featured Redis client that is used in the world’s biggest online commerce company Alibaba and many other awesome companies.