nodejs中間層について話す

序文

nodejsフロントエンド業界の出現により、フロントエンド業界に無限の可能性がもたらされ、クライアント側の開発のみを担当していた多くの学生が、サーバー側のテクノロジーに徐々に連絡を取り、使用し始めています。

nodejs利益の多くをもたらしたが、それはまた、独自の制限があります。そして、それらの古い伝統的なプログラミング言語はよう比べJAVAPHPnodejsそして、彼らのために代替することはできませんが、また、将来的に推定することができ、状況を振ることは困難ですそれらの古いプログラミング言語の。

現在、nodejs主に以下のアプリケーションシナリオがあります。

  • フロントエンドエンジニアリング、たとえばrollupwebpackエンジニアリングの方向への探求
  • 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構成を直接使用することをお勧めします。転送が実行されます。

インターフェイスアグリゲーションとインターフェイス転送の両方が必要な場合は、コードレベルから解決するための推奨される方法です。

インターフェイスアグリゲーションとはどういう意味ですか?会社に2つの販売システムがあります。1つはオンラインeコマースプラットフォームの販売で、もう1つはオフラインの実店舗です。これらは異なるチームによって運営され、異なるデータシステムを維持しています。

現在のリクエストがeコマースプラットフォーム上の特定の商品の情報のみをクエリする場合は、インターフェースをeコマースプラットフォームシステムに転送するだけで済みます。同様に、オフラインの実店舗の販売実績のみをクエリする場合も同様です。特定の日に、リクエストを直接転送してオフラインデータシステムにクエリを実行し、応答データを返すことができます。上記のプラグインhttp-proxy-middlewareは複数のプロキシパスの構成をサポートしており、詳細なドキュメントをクエリできます。

このような需要があるため、今週の特定の製品のオンラインとオフラインの販売データの比較をクエリすることが目標です。次に、この時点で、node层オンライン販売データとオフラインを取得するために2つのリモートサーバーにリクエストを送信する必要があります。データの2つの部分が集約されて処理された後、フロントエンドに返されます。簡単な方法は次のとおりです。

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これは、2つのデータを集約するカスタムルートを表します。データを集約するための要件が​​さらにある場合は、このロジックを管理用のルーティングモジュールに個別にカプセル化し、プロキシ転送の前に記述する必要があります。

これにより、転送する必要のあるインターフェイスが転送の論理処理に引き渡され、データをパーソナライズする必要のあるインターフェイスがルーティング操作データ用に個別に書き込まれるようになります。

データキャッシュ

キャッシングは、システムパフォーマンスの向上とデータベースの負荷の軽減に重要な役割を果たし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中間層は、フロントエンドの制御されていないアクセスを制限できます。たとえば、一部の悪意のあるスクリプトがインターフェイスをループします。1秒あたり数十回のアクセスにより、サーバーの負荷が増加します。

redisこのリクエストうち解析し、私たちはこの機能を実現。最初のユーザーにアクセスするのを助けることができるip、アドレスipkey値がvalueに設定されている0にセーブredis

ユーザーは2回目の訪問を行い、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インターフェイスが201秒間に複数呼び出された場合にアクセスが拒否されることです

ログ操作

システムには、目のない人に相当するログがありません。ログは、オンラインシステムのエラーを見つけて分析するのに役立ちます。また、ログデータは、特定の結論や傾向を引き出すための統計計算にも使用できます。

nodeレイヤーは、インターフェイスアクセスログを例として、ログを管理する機能を引き受けることができます。システムに新しいログフォルダーを作成し、アクセス要求があるたびに、最初に要求されたパス、現在のアクセス時間、およびキャリーパラメータと端末データ情報次に、ログフォルダにtxtその日のログ状況保存するファイルを作成し、上記のデータとリクエストの応答結果をレコードに結合してtxtファイルに挿入します。次にアクセスするときは、上記のプロセスを続行してtxt、アクセスログファイル追加します。上記のプロキシ転送と同様に、プラグインhttp-proxy-middlewareは応答結果を返す方法の構成サポートし、対応するイベントで要求と応答を同時に取得できます。関数フック、およびこれらの2つのデータをログに保存できます。

ここで作成できる構成戦略も多数あります。実際の状況に応じて、1日に1つのログテキストを選択するか、トラフィックが多い場合は1時間に1つのログテキストを選択することもできます。

さらに、時間が経つにつれて、ログフォルダのファイルの内容はますます多くなります。これには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すると、中間層最も価値のある機能は、サーバー側のレンダリングとインターフェイスデータの集約です。エンタープライズアプリケーションの数が少なく、ビジネスが単純で拡張されていない場合は、中間層を追加することはお勧めしません。単純なことは複雑になります。

おすすめ

転載: blog.csdn.net/brokenkay/article/details/112711241