序文
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
構成を直接使用することをお勧めします。転送が実行されます。
インターフェイスアグリゲーションとインターフェイス転送の両方が必要な場合は、コードレベルから解決するための推奨される方法です。
インターフェイスアグリゲーションとはどういう意味ですか?会社に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
、アドレスip
とkey
値が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
インターフェイスが20
1秒間に複数回呼び出された場合にアクセスが拒否されることです。
ログ操作
システムには、目のない人に相当するログがありません。ログは、オンラインシステムのエラーを見つけて分析するのに役立ちます。また、ログデータは、特定の結論や傾向を引き出すための統計計算にも使用できます。
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
すると、中間層の最も価値のある機能は、サーバー側のレンダリングとインターフェイスデータの集約です。エンタープライズアプリケーションの数が少なく、ビジネスが単純で拡張されていない場合は、中間層を追加することはお勧めしません。単純なことは複雑になります。