目錄
介面聚合
数据缓存
接口限流
日志操作
结尾
首頁 web前端 js教程 一文透過實踐解析nodejs中間件

一文透過實踐解析nodejs中間件

Sep 27, 2022 pm 08:36 PM
node.js node 中介軟體

一文透過實踐解析nodejs中間件

nodejs的出現為前端產業帶來了無限的可能性,讓許多原來只負責客戶端開發的同學也慢慢開始接觸和使用伺服器端技術.

雖然nodejs帶來了很多的好處,但是它也存在自身的局限性.和那些傳統老牌的程式語言相比,如JAVA,PHP.nodejs並不能成為它們的替代品,而且在可預估的未來,也很難撼動那些老牌程式語言的地位。 【相關教學推薦:nodejs影片教學

#目前nodejs主要有以下幾個應用場景.

  • 前端工程化,例如rollup,webpack在工程化方向的探索
  • #nodejs中間層
  • 客戶端整合nodejs ,例如electron
  • 市面上一些不太複雜的應用選擇nodejs作為後端程式語言

本文主要講一講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的支持以及首屏加载速度,因此服务器端渲染不可或缺.前端项目目前大多采用reactvue框架开发,如果用nodejs承担服务器端渲染的任务,那么可以确保一套代码既可以做客户端渲染也能支持服务器端渲染,而这些工作都可以让前端程序员独立来完成.服务器端渲染技术非常重要,后面会开一个小节单独讲解.

综上来看,nodejs做中间层最有价值的功能是服务器端渲染和接口数据聚合.如果企业应用数量较少业务简单还没有规模化,不建议添加中间层,那样反而让简单的事情变得复杂.

更多node相关知识,请访问:nodejs 教程

以上是一文透過實踐解析nodejs中間件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1653
14
CakePHP 教程
1413
52
Laravel 教程
1304
25
PHP教程
1251
29
C# 教程
1224
24
Pi Node教學:什麼是Pi節點?如何安裝和設定Pi Node? Pi Node教學:什麼是Pi節點?如何安裝和設定Pi Node? Mar 05, 2025 pm 05:57 PM

PiNetwork節點詳解及安裝指南本文將詳細介紹PiNetwork生態系統中的關鍵角色——Pi節點,並提供安裝和配置的完整步驟。 Pi節點在PiNetwork區塊鏈測試網推出後,成為眾多先鋒積極參與測試的重要環節,為即將到來的主網發布做準備。如果您還不了解PiNetwork,請參考Pi幣是什麼?上市價格多少? Pi用途、挖礦及安全性分析。什麼是PiNetwork? PiNetwork項目始於2019年,擁有其專屬加密貨幣Pi幣。該項目旨在創建一個人人可參與

tomcat中間件原理是什麼 tomcat中間件原理是什麼 Dec 27, 2023 pm 04:40 PM

tomcat中間件原理是基於Java Servlet和Java EE規格來實現的。 Tomcat作為Servlet容器,負責處理HTTP請求和回應,提供Web應用程式的運作環境。 Tomcat中間件的原理主要涉及:1、容器模型;2、元件化架構;3、Servlet處理機制;4、事件監聽和過濾器;5、組態管理;6、安全性;7、叢集和負載平衡; 8、連接器技術;9、嵌入式模式等等。

如何在Laravel中使用中間件處理表單驗證 如何在Laravel中使用中間件處理表單驗證 Nov 02, 2023 pm 03:57 PM

如何在Laravel中使用中間件處理表單驗證,需要具體程式碼範例引言:在Laravel中,表單驗證是非常常見的任務。為了確保使用者輸入的資料的有效性和安全性,我們通常會對表單提交的資料進行驗證。 Laravel提供了一個方便的表單驗證功能,同時也支援使用中間件來處理表單驗證。本文將詳細介紹如何在Laravel中使用中間件處理表單驗證,並提供具體的程式碼範例

使用Angular和Node進行基於令牌的身份驗證 使用Angular和Node進行基於令牌的身份驗證 Sep 01, 2023 pm 02:01 PM

身份驗證是任何網路應用程式中最重要的部分之一。本教程討論基於令牌的身份驗證系統以及它們與傳統登入系統的差異。在本教程結束時,您將看到一個用Angular和Node.js編寫的完整工作演示。傳統身份驗證系統在繼續基於令牌的身份驗證系統之前,讓我們先來看看傳統的身份驗證系統。使用者在登入表單中提供使用者名稱和密碼,然後點擊登入。發出請求後,透過查詢資料庫在後端驗證使用者。如果請求有效,則使用從資料庫中獲取的使用者資訊建立會話,然後在回應頭中傳回會話訊息,以便將會話ID儲存在瀏覽器中。提供用於存取應用程式中受

如何在Laravel中使用中間件進行資料加速 如何在Laravel中使用中間件進行資料加速 Nov 02, 2023 am 09:40 AM

如何在Laravel中使用中間件進行資料加速引言:在使用Laravel框架開發Web應用程式時,資料加速是提高應用程式效能的關鍵。中間件是Laravel提供的重要功能,可以在請求到達控制器之前或回應返回之前對請求進行處理。本文將重點放在如何在Laravel中使用中間件實現資料加速,並提供具體的程式碼範例。一、什麼是中間件中間件是Laravel框架中一種機制,用

如何在Laravel中使用中間件進行回應轉換 如何在Laravel中使用中間件進行回應轉換 Nov 03, 2023 am 09:57 AM

如何在Laravel中使用中間件進行回應轉換中間件是Laravel框架中非常強大且實用的功能之一。它允許我們在請求進入控制器之前或回應被發送給客戶端之前,對請求和回應進行處理。在本文中,我將示範如何使用中間件在Laravel中進行回應轉換。在開始之前,確保你已經安裝了Laravel並創建了一個新的專案。現在,我們將按照以下步驟進行操作:建立一個新的中間件打開

在Slim框架中使用中間件(Middleware)設定跨域資源共享(CORS)的方法 在Slim框架中使用中間件(Middleware)設定跨域資源共享(CORS)的方法 Jul 30, 2023 pm 08:34 PM

在Slim框架中使用中間件(Middleware)設定跨域資源共享(CORS)的方法跨域資源共享(CORS)是一種機制,允許伺服器在HTTP響應頭中設定一些額外的信息,來告知瀏覽器是否允許跨域請求。在一些前後端分離的專案中,使用CORS機制可以實現前端跨域請求後端介面的需求。在使用Slim框架開發RESTAPI時,我們可以使用中間件(Middleware)

如何在Laravel中使用中間件進行資料恢復 如何在Laravel中使用中間件進行資料恢復 Nov 02, 2023 pm 02:12 PM

Laravel是一個流行的PHPWeb應用程式框架,提供了許多快速且簡單的方式來建立高效、安全且可擴展的Web應用程式。在開發Laravel應用程式時,我們經常需要考慮資料恢復的問題,即如何在資料遺失或損壞的情況下恢復資料並保證應用程式的正常運作。在本文中,我們將介紹如何使用Laravel中間件來實現資料復原功能,並提供具體的程式碼範例。一、什麼是Lara

See all articles