Kemunculan
nodejs
telah membawa kemungkinan tanpa had kepada industri hadapan, membolehkan ramai pelajar yang pada asalnya hanya bertanggungjawab untuk pembangunan sisi pelanggan perlahan-lahan mula berhubung dengan dan menggunakan teknologi bahagian pelayan.
Walaupun nodejs
membawa banyak faedah, ia juga mempunyai batasan tersendiri Berbanding dengan bahasa pengaturcaraan tradisional dan lama tersebut, seperti JAVA
, PHP
.nodejs
. tidak boleh menjadi pengganti Mereka, dan pada masa hadapan, sukar untuk menggoncang status bahasa pengaturcaraan lama tersebut. [Cadangan tutorial berkaitan: tutorial video nodejs]
Pada masa ini, nodejs
terutamanya mempunyai senario aplikasi berikut.
rollup
,webpack
Penerokaan ke arah kejuruteraannodejs
Lapisan tengahnodejs
, sepertielectron
nodejs
sebagai bahasa pengaturcaraan bahagian belakang Artikel ini terutamanya membincangkan beberapa amalan nodejs
sebagai lapisan tengah, lihat gambar di bawah.
Dalam model pembangunan tradisional, penyemak imbas berkomunikasi secara langsung dengan lapisan Server
Penambahan lapisan tengah bermakna lapisan tambahan ditambah antara penyemak imbas dan Server
lapisan.
Asal Pelanggan terus menghantar permintaan kepada Server
, dan lapisan Server
menerima permintaan dan mengembalikan hasilnya kepada penyemak imbas selepas pengiraan dan pemprosesan penyemak imbas menghantar permintaan kepada
melalui proses Selepas satu pusingan pemprosesan, mulakan permintaan untuk node层
akan mengembalikan hasil respons kepada node层
akhirnya mengembalikan data kepada penyemak imbas. Server层
Server层
node层
boleh mendapatkan data daripada lapisan node层
, dan kemudian mengira dan menyepadukan data ke dalam format data yang memenuhi keperluan bahagian hadapan
Akan ada banyak pelayan yang mengurus modul perniagaan yang berasingan node层
disesuaikan dengan baik kepada seni bina perkhidmatan mikro. Ia boleh memulakan permintaan kepada berbilang pelayan untuk mendapatkan data daripada modul yang berbeza dan kemudian menyepadukan dan mengubahnya dan hantar ke hujung hadapan. Pemajuan proksi mempunyai banyak aplikasi luas dalam amalan Pelayar Pertama, hantar permintaan ke Server层
Selepas menerima permintaan,
node层
Pelayan jauh mengira hasil respons dan mengembalikannya kepada server
masih boleh memproses respons dan mengembalikannya ke penyemak imbas .UI
Server层
Pemajuan proksi boleh menyelesaikan rutin harian masalah silang domain yang sering dihadapi dalam pembangunan, selain itu, ia juga menyekat butiran pelayan sebenar jauh, membenarkan penyemak imbas hanya berkomunikasi dengan. node层
. Berikut ialah amalan mudah
nodejs
node服务器
node服务器
node服务器
node服务器
ditetapkan kepada
Pada alamat proses laluan permintaan dan tukarkan node服务器
kepada
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
Maksud kes di atas adalah jelas Jika akses penyemak imbas semasa npm
Kerana laluan ini bermula dengan
untuk mengubah suai laluan akses Pada akhirnya, laluan akses menjadi /api
, dan kemudian permintaan akan dibuat ke laluan ini dan respons akan diperolehi dan kemudian kembali ke penyemak imbas. http-proxy-middleware
http-proxy-middleware
target
Pemajuan antara muka yang diperkenalkan di atas jarang digunakan secara bersendirian Jika ia hanya untuk memajukan data, maka adalah lebih baik untuk mengkonfigurasinya terus dengan changeOrigin
Jika kedua-dua pengagregatan antara muka dan pemajuan antara muka diperlukan, maka menyelesaikannya daripada tahap kod masih menjadi keutamaan true
target
Penggabungan antara muka Apa yang dilakukan Anggapkan bahawa syarikat itu kini mempunyai dua sistem jualan, satu adalah jualan platform e-dagang dalam talian, dan satu lagi adalah kedai fizikal luar talian Mereka dikendalikan oleh pasukan yang berbeza dan mengekalkan sistem data yang berbeza如果当前请求只是想查询一下电商平台某款商品的信息,只需要将接口转发给电商平台系统即可.同理如果仅仅只是查询线下实体店某一天的销售业绩,可以直接把请求转发给线下数据系统查询,再把响应数据返回.上面介绍的插件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
做中间层最有价值的功能是服务器端渲染和接口数据聚合.如果企业应用数量较少业务简单还没有规模化,不建议添加中间层,那样反而让简单的事情变得复杂.
更多node相关知识,请访问:nodejs 教程!
Atas ialah kandungan terperinci Artikel yang menganalisis perisian tengah nodejs melalui amalan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!