8.Redis
安装完成执行 redis-server 就可以启动服务, redis-cli 就可以 起一个主机域名加端口号,使用的话直接 set 键 值即可。get 键可以得到值,也就是 key vlaue 的形式。 keys * 查看所有的
key , del 键可以删除一些 key。
9.nodejs链接Redis的demo
用Redis存储session:
- nodejs连接redis的demo
- 封装成工具函数,可供API使用
新建一个 redis-test 的目录,然后 npm 初始化,新建一个 index.js,安装 redis(npm 安装),引入 redis。创建客户端, 需要使用 createClient 方法,传入端口号(默认 6379),主 机名。调用 on 监听 error。接下来就可以通过 set 方法设置 key 了(可以加多一给 redis.print 的属性,完成会打印出来成功的提示)。
get 方法需要传入一个回调函数监听 err 和真正的值(异步), 获取完成就调用 quit 方法退出。Shutdown 就是关闭 redis。
const redis =require(" redis")引入redis const redisclient = redis.createclient(6379,'127.0.0.1')1/创建客户端 redisclient.on( 'error' , err =>{//监听错误 console.log(err) } redisclient.set('myname' , 'xiangbei' , redis.print)//设置键值且打印成功提示 redisclient.get('myname' , (err,val)=>{1/获取犍值且获取完成关闭客户端 if (err){ console.log(err) return console.log('val:' , val)redisclient.quit() })
10.node.js链接Redis封装工具函数
接下来就可以把 redis 给封装起来,注意我们回到 blog 重启的话会让我们处于未登录状态,原因也很简单,因为设置session 数据是写在 app.js 中,默认是空对象,这个问题可以通过引入 redis 解决(再重启就是重启 blog 了,与 redis 没有关系,不会丢失登录)。
打开 db.js ,定义一个 REDIS_CONF 来储存 redis 的配置,同理是分为两种配置。建好配置后我们打开 db 文件夹,建一个 redis.js ,引入 redis 和配置,创建客户端。提供两个函数 set (传入 val 和 key 基本和原本写的一样,只不过需要判断 val 是不是对象,是则利用 stringify 转换)和 get (传入 key ,因为是异步,这里用promise 来封装)。 同样的退出的话也不能写在 get 里面,和 mysql 是一个道理。针对获取的结果其实有多种情况:第一种是瞎传的 key (val=null,即找不到对应 key 的值,这个返回 null )。 第二种是如果传入的是对象我们前面给它 stringify 了,现在
肯定要解开 JSON.parse ,但是如果原本不是对象那自然会报错(用 try catch 捕获进行兼容,并不是错误)直接返回原本的值即可。
REDIS CONF ={ port: 6379, host: '127.0.8.1' }
const redis =require( 'redis') const { REDIS_CONF} = require( '../conf/db') //创建一个客户端 const redisclient = redis.createclient(REDIS_CONF.portm,REDIS_CONF.host) redisclient.on( 'error', err =>{ console.log(err) )) //定义设置redis的方法 function set (key, val){ if (typeof val === 'object') {//如果值是对象则转换为json字符串 val = JSoN.stringify(val) } redisClient.set(key, val,redis.print) }
11.session存入Redis
回到 app.js ,注释掉 session 数据和解析 session 的代码。引 入 get set ,使用 redis 来解析 session 。 如果不存在 userId 则设置状态为 true ,设置 userId ,初始化 session,将 userId 为空对象。那么就可以利用 get 方法来获取 session 。 解析完 session 就可以回到登录来修改,需要引入 set 将其同步到 redis 。
let needsetcookie = false let userId = req.cookie.userIdif (l userId){ needsetcookie = true userId =“s{Date.nok(]${Math.random(1 //设置redis中的session(不要管是userid还是sessionId,反正就是同一个时间戳而已2)set(userId,0) //i27.0.0.1;6379get i59791251814I_8.7153950171260812“” 获取session req.sessionId = userId //同一个时网戳换个表达而已,才能让各地使用 get(req.sessionTd) then((sessionData) ={/这里的sessionData就是根操key lblsessionId拿到对应的值《可能找不到即为nutL)if (sessionData -- null) { lset(req, sessionId,(H)1/似乎没有必要,之前已经设置过时何戢为空对象,但是!!那是因为不存在userId才建的! !req.session - o再把当前session票空(开辟空向) else ( req.session = sessionbatal 应值给’127.0.0.1:6379 get 1597912518141_0.7153950171260812 "“(1"usernamel" l "qibin ", "reaLnamel"; ["lxe)xaalxe1 xe5l:85luxb国 console.log( sessionbata)return getPostData(req))
12.完成server端登录代码
到目前为止,我们登录和登录验证的功能基本实现,那么就 可以丢到 blog.js 中,而由于需要使用登录和登录验证的路由太多了,我们还是封装成一个中间件比较合适。 定义一个函数 LoginCheck (与 user 里面的作区别),如果找 不到 username 就返回失败 model (主要是来拦截未登录用户)放到路由中,如果该函数有值说明未登录,直接 return 。 无值是已经登录那么执行之前的代码,记得将部分信息替换成真实的登录者(删除和更新路由)。 回到 router 再将登录改成 POST ,注销 login-test。
//登录验证函数 const LoginCheck = (req) => { if ( req . sessi son. username) { return Promi se.resolve( new ErrorModel(”尚未登录”) } } }
13. 联调-html界面
和前端联调:
- 登录功能依赖cookie , 必须用浏览器来联调
- cookie跨域不共享的,前端和server端必须同域
- 需要用到nignx做代理,让前后端端同域
有关的 html 已经写好了,比较简单这里直接用就行。安装 http-server,启动 http-serve -p 8001,这个时候启动浏览器,它请求的诸如博客 list 什么的都是以 8001 开头的,自然是找
不到,我们需要做的就是,让 nginx 将 8001 变为 8000 ,然后统一变成 localhost : 8000
14.Nginx配置
静态服务就是那种不需要服务端解析就能直接拿上来的资源(图片什么的)负载均衡就是让集群的每个机器都尽可能的占用相同的资源(就不要偏差太大,平均流量)。反向代理就是转变访问的地址。
Nginx介绍:
- 高性能的web服务器,开源免费
- 一般用于做静态服务、 负载均衡(本课用不到)
- 还有反向代理(本课用到)
如下图所示,先经过 nginx,再由 nginx 根据路径(带有 api 的走 8000 的 node.js,其余的走 8001 的 html 界面)。
Nginx反向代理
反向代理就是对客户端不可见(就不看调试里面发送的请求是不知道我的实际地址什么的)的代理(只能由服务端控制),相反的是正向代理,由客户端来控制的代理。
Nginx命令:
- 测试配置文件格式是否正确nginx -t
- 启动nginx;重启 nginx -S reload
- 停止nginx -S stop
接下来我们就来配置一下 nginx,打开配置文件,可以在第 3 行加上 worker_processes 2;(cpu 有几核就写多少,就可以启动多少个 nginx 进程,性能也就越高,只不过这个一般是运维的人管的,我们不写也行)。 来到 35 行第一个 server,改成 8080 端口,43 行找到 location 这个是我们不用,用#将它们注释掉,写自己的代理,代理分为两个,一个是/即根目录开始的(html)走 8001,一个是 api 开始的(node.js)走 8000(这个还需要把 host 传过去)。
保存完成我们利用 nginx -t 测试一下,成功的话则启动 nginx发现可以访问了。
Nginx 出现的问题:
1. nginx: [emerg] unexpected "}" 这个要么是该行附件有特殊字符(如$ 写成了 # 报错)
2. 什么 1133 这个是因为路径有中文。
联调出现的问题:
1. 没有打开 http-server ,也就是说需要同时开启 node.js 个 http-server 静态服务以及 nginx 才可以让 nginx 生效。(所以基本上 nginx 只是充当反向代理的作用就是改改地址,具体 还得靠前两个,因为前两个端口不同, nginx 只是将两个连起来转变其中一个的路径)
2. 页面打开失败,一方面是路由没有 return ,另一方面是路径问题(把相对路径改成绝对路径即可)