Thanapon Tapala

Backend Developer

Embedded Developer

Smart Farmer

Maker

Thanapon Tapala

Backend Developer

Embedded Developer

Smart Farmer

Maker

Blog Post

[Redis] แจ้งเตือน Key expired โดย Key space notifications ผ่าน Nodejs กัน

October 13, 2020 NodeJs, Redis
[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 ของเราดูครับ

ทดสอบรันก่อน~~

Image for post

รันผ่านแล้วสามารถเชื่อมต่อกับ Service Redis ได้แล้ว จากนั้นลอง set คีย์พร้อมกับกำหนด expired time เข้าไปสัก 5 วินาทีครับ

Image for post

หลังจากผ่านไป 5 วินาที Service Redis ก็ส่ง event มาด้วย เป็นอันว่า application ของเราทำงานโดยไม่พบ BUG ครับ 55555

Image for post

เป็นอันว่าโปรเจคที่ทำงานของผมก็เดินหน้าต่อไปได้แล้วครับ 5555 ขอบคุณทุกท่านที่เข้ามาอ่านกันนะครับ สำหรับวันนี้ขอบคุณและสวัสดีครับ

ส่วนตรงนี้เป็น github ของตัว project นะครับพี่ๆน้องๆ สามารถ clone มาลองเล่นดูกันได้ครับ

nodejs-redis-keyspace-notifications

https://github.com/toygame/nodejs-redis-keyspace-notifications

redis.io/topics/notifications

Keyspace notifications allow clients to subscribe to Pub/Sub channels in order to receive events affecting the Redis data set in some way.

github.com/luin/ioredis

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.

Taggs: