Nodejs中间件的应用场景有哪些,怎么使用
Admin 2022-10-09 群英技术资讯 339 次浏览
nodejs
的出现为前端行业带来了无限的可能性,让很多原来只负责客户端开发的同学也慢慢开始接触和使用服务器端技术.虽然
nodejs
带来了很多的好处,但是它也存在自身的局限性.和那些传统老牌的编程语言相比,如JAVA
,PHP
.nodejs
并不能成为它们的替代品,而且在可预估的未来,也很难撼动那些老牌编程语言的地位。目前
nodejs
主要有以下几个应用场景.
- 前端工程化,比如
rollup
,webpack
在工程化方向的探索nodejs
中间层- 客户端集成
nodejs
,比如electron
- 市面上一些不太复杂的应用选择
nodejs
作为后端编程语言本文主要讲一讲
nodejs
作为中间层的一些实践,查看下图.传统的的开发模式由浏览器直接和
Server
层直接通信,中间层的加入意味着在浏览器和Server
层之间额外添加了一层.原来客户端直接向
Server
发送请求,Server
层收到请求后经过计算处理将结果返回给浏览器.如今浏览器将请求发送给
node层
,node层
经过一轮处理后再向Server层
发起请求.Server层
处理完毕将响应结果返回给node层
,node层
最后将数据返回给浏览器.因为
node层
的出现,Server层
可以只用关注业务本身,而不必理会前端对字段的特殊要求。
node层
可以向server
层获取数据,再通过对数据的计算整合转换成符合前端UI
要求的数据格式.另外整个应用如果采用微服务架构,那么Server层
会有很多台管理单独业务模块的服务器,node层
就很好的适配了微服务的架构,它可以向多台服务器发起请求获取到不同模块的数据再整合转化发送给前端.下面着重介绍一下
nodejs
作为中间层的部分实践.代理转发
代理转发在实际中有很多广泛的应用.浏览器首先将请求发送给
node服务器
,请求收到后node服务器
可以对请求做一些处理,比如将原来的路径变换一下,请求头的信息改变一下,再把修改后的请求发送给远程真实的服务器.远程服务器计算出响应结果再返回给
node服务器
,node服务器
仍然可以对响应做选择性处理再分返回给浏览器.代理转发可以解决前端日常开发中经常遇到的跨域问题,另外它还屏蔽了远程真实服务器的细节,让浏览器只与
node服务器
通信.下面是简单的实践.
const express = require('express'); const { createProxyMiddleware } = require('http-proxy-middleware'); const app = express();//创建应用 app.use("/api",createProxyMiddleware( //设置代理转发 { target: 'http://www.xxx.com', //举例随便写的地址 changeOrigin: true, pathRewrite: function (path) { return path.replace('/api', '/server/api'); } }) ); app.use("*",(req,res)=>{ //不是以'/api'开头的路由全部返回"hello world" res.send("hello world"); }) app.listen(3000);
http-proxy-middleware
是一个第三方依赖包,可以非常方便设置代理转发,需要通过npm
安装.如果当前访问的路径是以
/api
开头,那么该请求就会被http-proxy-middleware
拦截.观察http-proxy-middleware
里面配置的参数.
target
代表远程真实服务器的地址.changeOrigin
设置为true
,表示将请求转发到target
地址上.pathRewrite
是对请求路径做一下处理,将/api
转换成/server/api
.上面的案例意思很明显,假如当前浏览器访问
http://localhost:3000/api/list
.因为这个路径以/api
开头所以会被拦截,从而触发pathRewrite
函数修改访问路径.最终访问路径就变成了http://www.xxx.com/server/api/list
,然后就会向这个路径发起请求,得到响应后再返回给浏览器.接口聚合
上面介绍的接口转发在实践中很少会单独应用,如果仅仅只是为了转发一下数据,那还不如直接用
nginx
配置一下,转发就搞定了.如果接口聚合和接口转发都需要,那么从代码层面去解决还是优先考虑的方式.
接口聚合是什么意思呢?假设现在企业有两个销售体系,一个是线上的电商平台销售,另一个是线下实体店.它们分别属于不同的团队运营,维护着不同的数据系统.
如果当前请求只是想查询一下电商平台某款商品的信息,只需要将接口转发给电商平台系统即可.同理如果仅仅只是查询线下实体店某一天的销售业绩,可以直接把请求转发给线下数据系统查询,再把响应数据返回.上面介绍的插件
http-proxy-middleware
支持配置多个代理路径,详细可查询文档.现在有这么一个需求,目标是查询本周某款商品在线上和线下销售数据的对比.那么这个时候就需要
node层
向两个远程服务器发送请求分别获取线上销售数据和线下销售数据,将这两部分数据聚合处理后再返回给前端.简单实践如下.
const express = require('express'); const { createProxyMiddleware } = require('http-proxy-middleware'); const app = express();//创建应用 //伪代码 app.get("/getSaleInfo",async (req,res)=>{ const online_data = await getOnline(); //获取线上数据 const offline_data = await getOffline(); //获取线下数据 res.send(dataHanlder(online_data,offline_data)); //对数据处理后返回给前端 }) proxyHanlder(app);//伪代码,将代理转发的逻辑封装起来 app.use("*",(req,res)=>{ res.send("hello world"); }) app.listen(3000);
/getSaleInfo
代表着将两条数据聚合的自定义路由,如果需要聚合数据的需求比较多,这块逻辑要单独封装到路由模块中管理,并且要写在代理转发的前面.这样就确保了需要转发的接口就交给转发的逻辑处理,需要个性化处理数据的接口就单独编写路由操作数据.
数据缓存
缓存对于提升系统性能,减小数据库压力起到了无足轻重的作用.一般常用的缓存软件是
redis
,它可以被理解成数据存储在内存当中的数据库.由于数据放在内存中,读写速度非常快,能极快的响应用户的请求.在
node层
部署redis
管理缓存数据,可以提升整体应用性能.但不是什么数据都建议存放在redis
中,只有那些不经常变动的数据应该设置成缓存.比如商品的信息数据,浏览器对某个商品发起请求,想查看该商品的详情.请求第一次到达
node
层,redis
此时是空的.那么node
开始请求server
层得到响应结果,此时在将响应结果返回给浏览器之前,将该次请求的访问路径作为key
值,响应结果作为value
存储到redis
中.这样之后再有相同的请求发来时,先查看redis
有没有缓存该请求的数据,如果缓存了直接将数据返回,如果没有缓存再去请求server
层,把上述流程再走一遍.
redis
还可以对缓存数据设置过期时间和清除,可以根据具体的业务操作.简单实践如下.
const express = require('express'); const app = express();//创建应用 //伪代码 app.use("*",(req,res,next)=>{ const path = req.originalUrl; //获取访问路径 if(redisClient.getItem(path)){ //查看redis中有没有缓存该条接口的数据 res.send(redisClient.getItem(path)); // 返回缓存数据 }else{ next(); //不执行任何操作,直接放行 } }) aggregate(app); //伪代码,将接口聚合的逻辑封装起来 proxyHanlder(app);//伪代码,将代理转发的逻辑封装起来 app.use("*",(req,res)=>{ res.send("hello world"); }) app.listen(3000);接口限流
node
做中间层可以对前端无节制的访问做限制.比如有些恶意的脚本循环访问接口,一秒钟访问几十次增大了服务器的负载.
redis
可以帮助我们实现这一功能.用户第一次访问,解析出本次请求的ip
地址,将ip
作为key
值,value
置为0
存到redis
中.用户第二次访问,取出
ip
找到redis
中对应的value
,然后自增1
.如果是相同的人重复大量访问,value
在短期内就自增到了很大的数字,我们可以每次获取这个数字判端是否超过了设定的预期标准,超过则拒绝本次请求.简单实践如下.
const express = require('express'); const app = express();//创建应用 //伪代码 app.use("*",(req,res,next)=>{ const ip = req.ip; let num = 0; if(redisClient.getItem(ip)){ //是否缓存了当前的ip字段 num = redisClient.incr(ip); //每访问一下,计数加1 }else{ redisClient.setItem(ip,0); redisClient.setExpireTime(5); //设置过期时间为5秒,5秒后再获取该ip为空 } if(num > 20){ res.send("非法访问"); }else{ next();//放行 } }) cacheData(app)//伪代码.缓存接口数据 aggregate(app); //伪代码,将接口聚合的逻辑封装起来 proxyHanlder(app);//伪代码,将代理转发的逻辑封装起来 app.use("*",(req,res)=>{ res.send("hello world"); }) app.listen(3000);在应用的前面设置一层限流中间件,每次访问来临先判端是否缓存过.第一次访问肯定没有缓存,就将当前
ip
对应的值设置为0
并添加过期时间为5
秒钟.下一次相同的用户再访问时就会将value
自增1
.最后的效果就达到了
5
秒内调用接口的次数超过20
次便拒绝访问.日志操作
系统没有日志,相当于人没有双眼.日志可以帮助我们发现分析定位线上系统出现的错误.另外通过日志数据也可以进行统计计算得出某些结论和趋势.
node
层能够承担起管理日志的功能,以接口访问日志为例.在系统中新建一个日志文件夹,每次有请求访问时,首先解析请求的路径、当前的访问时间以及携带的参数和终端数据信息.然后在日志文件夹创建一个txt
文件存放当天日志情况,将上述数据和该请求的响应结果组合成一条记录插入txt
文件中.下一次访问继续走上面流程往txt
文件添加访问日志.像上面介绍的代理转发,插件http-proxy-middleware
支持配置如何返回响应结果,那么在相应的事件函数钩子里就可以同时得到请求和响应,有了这两块数据就可以存放到日志中.这里还能制定很多的配置策略.可以选择一天一个日志文本,如果访问量巨大也可以选择一个小时一个日志文本,依据实际情况而定.
另外随着时间的延长,日志文件夹的文件内容会越来越多.这就需要编写
linux
操作系统定时任务来迁移和备份这些日志数据.日志操作简单实践如下.
//伪代码 app.use("/getList",async (req,res)=>{ const list = await getProductList(); //获取商品数据 const { 访问时间,访问路径,参数 } = req; logger.log('info',`${访问时间}-${访问路径和参数}:${list}`);//将数据存储到日志文件中 res.send(list);//将结果返回给客户端 })结尾
中间层另外还可以做很多其他事情,比如监控、鉴权和服务器端渲染(ssr).这部分由于内容比较多可以单独成章,网络上也有大量如何实践的文章,可搜索查阅学习.
其实上面所谈到的所有功能其他编程语言都可以做到,这也成为了很多人质疑是否需要在架构上额外再加一层的顾虑.
添加
nodejs
中间层,对于前端同学来说肯定是好消息.因为它能让前端承担更多的工作任务,让前端的业务比重变大.另外后端从此只需要关注自身业务,前端继续干着自己擅长的事,从整体上是能提升开发效率.但从宏观角度上看,架构额外增加一层势必会造成整个应用性能上的损耗,另外在部署,测试层面都会增大运维成本.
当下前后端分离已经成为了主流的开发模式,很多类型的应用需要seo的支持以及首屏加载速度,因此服务器端渲染不可或缺.前端项目目前大多采用
react
或vue
框架开发,如果用nodejs
承担服务器端渲染的任务,那么可以确保一套代码既可以做客户端渲染也能支持服务器端渲染,而这些工作都可以让前端程序员独立来完成.服务器端渲染技术非常重要,后面会开一个小节单独讲解.综上来看,
nodejs
做中间层最有价值的功能是服务器端渲染和接口数据聚合.如果企业应用数量较少业务简单还没有规模化,不建议添加中间层,那样反而让简单的事情变得复杂.
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
从零开始在vue-cli4配置自适应vw布局的实现, 简介<br /> viewportWidth也是vw布局从配置上来说比rem布局简洁了很多,bu需要配置安装lib,也不需要增加一个rem.js文件<br /> 简称拎包使用<br /> 安装包<br /> <br /> <br /> npm install postcss-px-t
目录1、ref属性2、props配置项props总结3、mixin混入3.1、局部混入3.2、全局混入mixin混入总结4、插件插件总结1、ref属性被用来给元素或子组件注册引用信息(id的替代者)应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)使用方式:打标识:h1 ref=xxx.
jQuery中this是什么意思?一些新手可能对于jQuery中this及其应用不是很了解,对此篇就给大家来简单的介绍一下this以及this的使用,对大家学习和认识有用的的帮助,需要的朋友可以了解看看,接下来就跟随小编学习一下吧。
这篇文章主要为大家介绍了Vue编程三部曲之模型树优化示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
js中!的用法是比较灵活的,它除了做逻辑运算常常会用!做类型判断,可以用!与上对象来求得一个布尔值,
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008