node JS 中 redis 的应用

一、node JS 中的 redis

  1. 解决方案 redis,如下所示:
  • web serverredis 拆分为两个单独的服务
  • 双方都是独立的,都是可扩展的,例如都扩展成集群
  • 包括 mysql,也是一个单独的服务,也可扩展
  1. session 适用于 redis,如下所示:
  • session 访问频繁,对性能要求极高
  • session 可不考虑断电丢失数据的问题,这也是内存的硬伤
  • session 数据量不好太大,相比于 mysql 中存储的数据
  1. 网站数据不适合用 redis,如下所示:
  • 操作频率不是太高,相比 session 操作
  • 断电不能丢失,必须保留
  • 数据量太大,内存成本太高
  1. 通过 npm i redis koa-redis koa-generic-session --save 命令下载 redis、koa-redis 和 koa-generic-sessio

  2. redis 目录下,新建两个 CMD 窗口,分别输入 redis-server.exe redis.windows.confredis-cli.exe -h 127.0.0.1 -p 6379 命令,启动 redis

  3. 新建 config 目录,在里面建立 db.js 文件,进行 redismysql 的一些配置,代码如下所示:


const {
    
     isProd } = require('../utils/env')

let REDIS_CONF = {
    
    
  port: 6379,
  host: '127.0.0.1'
}

let MYSQL_CONF = {
    
    
  host: 'localhost',
  user: 'root',
  password: '123456',
  port: '3306',
  database: 'koa2_weibo_db'
}

if (isProd) {
    
    
  REDIS_CONF = {
    
    
    port: 6379,
    host: '127.0.0.1'
  }

  MYSQL_CONF = {
    
    
    host: 'localhost',
    user: 'root',
    password: '123456',
    port: '3306',
    database: 'koa2_weibo_db'
  }
}

module.exports = {
    
    
  REDIS_CONF,
  MYSQL_CONF
}
  1. 新建 cache 目录,在里面建立 _redis.js 文件,进行设置连接 redissetget 方法,代码如下所示:
// 连接 redis 方法的 get  set

const redis = require('redis')
const {
    
     REDIS_CONF } = require('../config/db')

// 创建客户端
const redisClient = redis.createClient(REDIS_CONF.port, REDIS_CONF.host)
redisClient.on('errno', err => {
    
    
  console.log('redis errno', err)
})

// set
/**
 * redis  set
 * @param {string} key 键
 * @param {string} val 值
 * @param {number} timeout 过期时间,单位 s
 */
function set(key, val, timeout = 60 * 60 ) {
    
    
  if (typeof val === 'object') {
    
    
    val = JSON.stringify(val)
  }
  // 设置键和值
  redisClient.set(key, val)
  // 设置过期时间
  redisClient.expire(key, timeout)
}

// get
/**
 * redis get
 * @param {string} key 键
 */
function get(key) {
    
    
  const promise = new Promise((resolve, reject) => {
    
    
    redisClient.get(key, (err, val) => {
    
    
      if (err) {
    
    
        reject(err)
        return
      }

      if (val == null) {
    
    
        resolve(null)
        return
      }

      try {
    
    
        resolve(JSON.parse(val))
      } catch (ex) {
    
    
        resolve(val)
      }
    })
  })
  return promise
}

module.exports = {
    
    
  set,
  get
}
  1. app.js 文件中,引入 koa-rediskoa-generic-session,让 redissession 之间进行关联,代码如下所示:
const session = require('koa-generic-session')
const redisStore = require('koa-redis')

// session 配置
app.keys = ['Uas*305wf29#']
app.use(session({
    
    
  key: 'weibo.sid', // cookie name 默认是 `koa.sid`
  prefix: 'weibo:sess', // redis key 的前缀,默认是 `koa.sess:`
  cookie: {
    
    
    path: '/',
    httpOnly: true,
    maxAge: 24 * 60 * 60 * 1000 // ms cookie 过期时间
  },
  ttl: 24 * 60 * 60 * 1000, // redis 过期时间
  store: redisStore({
    
    
    all: `${
      
      REDIS_CONF.host}:${
      
      REDIS_CONF.port}`
  })
}))
  • 完整 app.js,代码如下所示:
// 业务逻辑
const Koa = require('koa')
const app = new Koa()
const views = require('koa-views')
const json = require('koa-json')
const onerror = require('koa-onerror')
const bodyparser = require('koa-bodyparser')
const logger = require('koa-logger')
const session = require('koa-generic-session')
const redisStore = require('koa-redis')

const {
    
     REDIS_CONF } = require('./config/db')
const {
    
     isProd } = require('./utils/env')

// 路由
const index = require('./routes/index')
const users = require('./routes/users')
const errorViewRouter = require('./routes/view/error')


// error handler
let onerrorConfig = {
    
    }
if (isProd) {
    
    
  onerrorConfig = {
    
    
    redirect: '/error'
  }
}
onerror(app, onerrorConfig)

// middlewares
app.use(bodyparser({
    
    
  enableTypes:['json', 'form', 'text']
}))
app.use(json())
app.use(logger())
app.use(require('koa-static')(__dirname + '/public'))

app.use(views(__dirname + '/views', {
    
    
  extension: 'ejs'
}))

// debugger

// session 配置
app.keys = ['Uas*305wf29#']
app.use(session({
    
    
  key: 'weibo.sid', // cookie name 默认是 `koa.sid`
  prefix: 'weibo:sess', // redis key 的前缀,默认是 `koa.sess:`
  cookie: {
    
    
    path: '/',
    httpOnly: true,
    maxAge: 24 * 60 * 60 * 1000 // ms cookie 过期时间
  },
  ttl: 24 * 60 * 60 * 1000, // redis 过期时间
  store: redisStore({
    
    
    all: `${
      
      REDIS_CONF.host}:${
      
      REDIS_CONF.port}`
  })
}))

// logger
app.use(async (ctx, next) => {
    
    
  const start = new Date()
  await next()
  const ms = new Date() - start
  console.log(`${
      
      ctx.method} ${
      
      ctx.url} - ${
      
      ms}ms`)
})

// routes
app.use(index.routes(), index.allowedMethods())
app.use(users.routes(), users.allowedMethods())
app.use(errorViewRouter.routes(), errorViewRouter.allowedMethods())

// error-handling
app.on('error', (err, ctx) => {
    
    
  console.error('server error', err, ctx)
});

module.exports = app

  1. routes 文件下的 index.js 文件中,去进行使用 redis,当访问 http://localhost:3000/json 这个路由的时候,session 就会产生,存入 redis,代码如下所示:
const router = require('koa-router')()

router.get('/json', async (ctx, next) => {
    
    
  const session = ctx.session
  if (session.viewNum == null) {
    
    
    session.viewNum = 0
  }
  session.viewNum++
  
  ctx.body = {
    
    
    title: 'koa2 json',
    viewNum: session.viewNum
  }
})
  1. 当在浏览器窗口进行访问 http://localhost:3000/json,就会进行计数,同时 redis 中也会有值,如下图所示

猜你喜欢

转载自blog.csdn.net/weixin_42614080/article/details/112744463