色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

HTTP反向代理服務器的編寫程序

我快閉嘴 ? 作者:工程師李察 ? 2018-10-06 10:00 ? 次閱讀

如果你經常使用 Node.js 編寫 Web 服務端程序,一定對使用 Nginx 作為 反向代理 服務并不陌生。在生產環境中,我們往往需要將程序部署到內網多臺服務器上,在一臺多核服務器上,為了充分利用所有 CPU 資源,也需要啟動多個服務進程,它們分別監聽不同的端口。然后使用 Nginx 作為反向代理服務器,接收來自用戶瀏覽器的請求并轉發到后端的多臺 Web 服務器上。大概工作流程如下圖:

HTTP反向代理服務器的編寫程序

在 Node.js 上實現一個簡單的 HTTP 代理程序還是非常簡單的,本文章的例子的核心代碼只有 60 多行,只要理解 內置 http 模塊 的基本用法即可,具體請看下文。

接口設計與相關技術

使用 http.createServer() 創建的 HTTP 服務器,處理請求的函數格式一般為 function (req, res) {}(下文簡稱為 requestHandler),其接收兩個參數,分別為 http.IncomingMessage 和 http.ServerResponse 對象,我們可以通過這兩個對象來取得請求的所有信息并對它進行響應。

主流的 Node.js Web 框架的中間件(比如 connect)一般都有兩種形式:

中間件不需要任何初始化參數,則其導出結果為一個 requestHandler

中間件需要初始化參數,則其導出結果為中間件的初始化函數,執行該初始化函數時,傳入一個 options 對象,執行后返回一個 requestHandler

為了使代碼更規范,在本文例子中,我們將反向代理程序設計成一個中間件的格式,并使用以上第二種接口形式:


HTTP反向代理服務器的編寫程序

說明:

上面的代碼中,reverseProxy 是反向代理服務器中間件的初始化函數,它接受一個對象參數,servers 是后端服務器地址列表,每個地址為 IP地址:端口 這樣的格式

執行 reverseProxy() 后返回一個 function (req, res) {} 這樣的函數,用于處理 HTTP 請求,可作為 http.createServer() 和 connect 中間件的 app.use() 的處理函數

當接收到客戶端請求時,按順序循環從 servers 數組中取出一個服務器地址,將請求代理到這個地址的服務器上

服務器在接收到 HTTP 請求后,首先需要發起一個新的 HTTP 請求到要代理的目標服務器,可以使用 http.request() 來發送請求:

HTTP反向代理服務器的編寫程序

要將客戶端的請求體(Body 部分,在 POST、PUT 這些請求時會有請求體)轉發到另一個服務器上,可以使用 Stream 對象的 pipe() 方法,比如:

說明:

req 對象是一個 Readable Stream(可讀流),通過 data 事件來接收數據,當收到 end 事件時表示數據接收完畢

res 對象是一個 Writable Stream (可寫流),通過 write() 方法來輸出數據,end() 方法來結束輸出

為了簡化從 Readable Stream 監聽 data 事件來獲取數據并使用 Writable Stream 的 write() 方法來輸出,可以使用 Readable Stream 的 pipe() 方法

以上只是提到了實現 HTTP 代理需要的關鍵技術,相關接口的詳細文檔可以參考這里:https://nodejs.org/api/http.html#http_http_request_options_callback

當然為了實現一個接口友好的程序,往往還需要很多 額外 的工作,具體請看下文。

簡單版本

以下是實現一個簡單 HTTP 反向代理服務器的各個文件和代碼(沒有任何第三方庫依賴),為了使代碼更簡潔,使用了一些最新的 ES 語法特性,需要使用 Node v8.x 最新版本來運行:

文件 proxy.js:


文件 log.js:

const util = require("util"); /** 打印日志 */ module.exports = function log(...args) { const time = new Date().toLocaleString(); console.log(time, util.format(...args)); };

說明:

log.js 文件實現了一個用于打印日志的函數 log(),它可以支持 console.log()一樣的用法,并且自動在輸出前面加上當前的日期和時間,方便我們瀏覽日志

reverseProxy() 函數入口使用 assert 模塊來進行基本的參數檢查,如果參數格式不符合要求即拋出異常,保證可以第一時間讓開發者知道,而不是在運行期間發生各種 不可預測 的錯誤

getTarget() 函數用于循環返回一個目標服務器地址

bindError() 函數用于監聽 error 事件,避免整個程序因為沒有捕捉網絡異常而崩潰,同時可以統一返回出錯信息給客戶端

為了測試我們的代碼運行的效果,我編寫了一個簡單的程序,文件 server.js:

執行以下命令啟動:

nodeserver.js

然后可以通過 curl 命令來查看返回的結果:

curlhttp://127.0.0.1:3000/hello/world

連續執行多次該命令,如無意外輸出結果應該是這樣的(輸出內容端口部分按照順序循環):

注意:如果使用瀏覽器來打開該網址,看到的結果順序可能是不一樣的,因為瀏覽器會自動嘗試請求/favicon,這樣刷新一次頁面實際上是發送了兩次請求。

單元測試

上文我們已經完成了一個基本的 HTTP 反向代理程序,也通過簡單的方法驗證了它是能正常工作的。但是,我們并沒有足夠的測試,比如只驗證了 GET 請求,并沒有驗證 POST 請求或者其他的請求方法。而且通過手工去做更多的測試也比較麻煩,很容易遺漏。所以,接下來我們要給它加上自動化的單元測試。

在本文中我們選用在 Node.js 界應用廣泛的 mocha 作為單元測試框架,搭配使用 supertest 來進行 HTTP 接口請求的測試。由于 supertest 已經自帶了一些基本的斷言方法,我們暫時不需要 chai 或者 should 這樣的第三方斷言庫。

首先執行 npm init 初始化一個 package.json 文件,并執行以下命令安裝 mocha和 supertest:

npminstallmochasupertest--save-dev

然后新建文件 test.js:

說明:

在單元測試開始前,需要通過 before() 來注冊回調函數,以便在開始執行測試用例時先把服務器啟動起來

同理,通過 after() 注冊回調函數,以便在執行完所有測試用例后把服務器關閉以釋放資源(否則 mocha 進程不會退出)

使用 supertest 發送請求時,代理服務器不需要監聽端口,只需要將 server 實例作為調用參數即可

接著修改 package.json 文件的 scripts 部分:

如果一切正常,我們應該會看到這樣的輸出結果,其中 passing 這樣的提示表示我們的測試完全通過了:

當然以上的測試代碼還遠遠不夠,剩下的就交給讀者們來實現了。

接口改進

如果要設計成一個比較通用的反向代理中間件,我們還可以通過提供一個生成 http.ClientRequest 的函數來實現在代理時動態修改請求:

然后在原來的 http.request(info, (res2) => {}) 部分可以改為監聽 response 事件:

constreq2=http.request(options.request(info));

req2.on("response",res2=>{});

同理,我們也可以通過提供一個函數來修改部分的響應內容:

此處只發散一下思路,具體實現方法和代碼就不再贅述了。

總結

本文主要介紹了如何使用內置的 http 模塊來創建一個 HTTP 服務器,以及發起一個 HTTP 請求,并簡單介紹了如何對 HTTP 接口進行測試。在實現 HTTP 請求代理的過程中,主要是運用了 Stream 對象的 pipe() 方法,關鍵部分代碼只有區區幾行。Node.js 中的很多程序都運用了 Stream 這樣的思想,將數據當做一個流,使用 pipe 將一個流轉換成另一個流,可以看出 Stream 在 Node.js 的重要性。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Web
    Web
    +關注

    關注

    2

    文章

    1262

    瀏覽量

    69441
  • HTTP
    +關注

    關注

    0

    文章

    504

    瀏覽量

    31194
  • 代理服務器
    +關注

    關注

    0

    文章

    9

    瀏覽量

    8001
收藏 人收藏

    評論

    相關推薦

    10個關于linux中Squid代理服務器的實用面試問答

    (常被視作代理服務的代名詞)就是這樣一個應用程序,它不但可以被作為代理服務器,其同時也是在該類工具中比較被廣泛使用的一種。本文旨在提高你在遇到關于
    發表于 09-28 10:19

    網絡代理服務器的內存

    網絡代理服務器的內存              網絡加速產品多采用SDRAM 和DDR SDRAM兩種內存。  &nb
    發表于 01-07 14:06 ?587次閱讀

    網絡代理服務器的網絡接口

    網絡代理服務器的網絡接口         
    發表于 01-07 14:08 ?599次閱讀

    網絡代理服務器

    網絡代理服務器              網絡代理服務器有別于傳統的網絡加速軟件,它是專門指高速緩存服務器產品,即Cache
    發表于 01-07 14:09 ?1009次閱讀

    Apache代理服務器配置說明

    Apache代理服務器 1. 安裝apache。 2. 修改\Apache\conf\httpd.conf配置文件, 首先要添加代理服務器模塊。找到下面這幾行: #LoadModule
    發表于 04-29 16:49 ?0次下載

    vpn代理服務器_VPN代理軟件下載

    vpn代理服務器使用,通過vpn代理登錄谷歌電子市場,本文提供了vpn代理軟件下載,供vpn代理使用的朋友下載
    發表于 09-14 09:50 ?111次下載

    Nginx架構介紹 Nginx服務器模型分析

    Nginx是一款免費的、開源的、高性能、模塊化、輕量級的HTTP服務器反向代理服務器以及電子郵件(IMAP/POP3)代理服務器
    的頭像 發表于 01-10 16:32 ?9215次閱讀
    Nginx架構介紹 Nginx<b class='flag-5'>服務器</b>模型分析

    正向代理反向代理的區別

    Nginx作為時下最流行的HTTP服務器之一,同時它是一個反向代理服務器,提到反向代理服務器,有
    的頭像 發表于 05-03 17:42 ?3513次閱讀
    正向<b class='flag-5'>代理</b>和<b class='flag-5'>反向</b><b class='flag-5'>代理</b>的區別

    基于高斯混合模型的Web代理服務器緩存

    基于高斯混合模型的Web代理服務器緩存
    發表于 06-23 16:46 ?17次下載

    代理服務器IP如何使用,這幾點需要注意了

    作為信息的中轉站,偽裝自己的真實IP,保障上網安全。那么,如何安全且合理的使用代理IP技術呢? 代理服務器是介于客戶端和Web服務器之間的另一臺服務器,有了它之后,瀏覽
    的頭像 發表于 07-22 17:19 ?4246次閱讀

    詳解Nginx高性能的HTTP反向代理服務器

    Nginx 是一個高性能的 HTTP反向代理服務器,特點是占用內存少,并發能力強,事實上 Nginx 的并發能力確實在同類型的網頁服務器中表現較好。
    的頭像 發表于 03-16 11:23 ?2446次閱讀

    恒訊科技分析:代理服務器的類型有哪些?

    代理服務器是一臺攔截和管理兩個設備、網絡或協議之間的流量的計算機。代理是充當我們的計算機與我們正在使用的網站和互聯網服務之間的中介的網關。它們可以用作防火墻、過濾器、緩存或促進共享網絡連接。這是
    的頭像 發表于 10-23 15:08 ?171次閱讀
    恒訊科技分析:<b class='flag-5'>代理服務器</b>的類型有哪些?

    代理服務器用戶名,主要作用是什么?

    代理服務器用戶名是指用于訪問和控制代理服務器的身份驗證信息之一。用戶名通常由代理服務器的管理員或服務提供商設定,用于確保只有授權用戶能夠訪問和使用
    的頭像 發表于 09-13 09:48 ?219次閱讀

    使用Python構建高效的HTTP代理服務器

    構建一個高效的HTTP代理服務器在Python中涉及多個方面,包括性能優化、并發處理、協議支持(HTTP/HTTPS)、錯誤處理以及日志記錄等。
    的頭像 發表于 10-23 07:41 ?155次閱讀

    Python中代理服務器的配置與應用

    在網絡通信中,代理服務器作為一種重要的網絡中間件,充當著客戶端和目標服務器之間的中間人角色。它能夠接收來自客戶端的請求,并將這些請求轉發給目標服務器,然后將服務器的響應返回給客戶端。P
    的頭像 發表于 11-12 07:13 ?168次閱讀
    主站蜘蛛池模板: MD传媒在线观看佳片| 野花日本大全免费观看3中文版 | 99免费精品| 久久午夜伦理| 野花日本大全免费高清完整版| 国产人妖一区二区| 跳蛋按摩棒玉势PLAY高H| 动漫女生的逼| 熟妇无码乱子成人精品| 国产爱豆果冻传媒在线观看视频 | 久久伦理影院| 中国大陆一级毛片免费| 久久亚洲精品2017| 最新国自产拍天天更新| 门事件快播| 9国产露脸精品国产麻豆| 国产综合在线观看| 亚洲精品无码葡京AV天堂| 99国产精品久久久久久久日本竹| 久久成人无码国产免费播放| 伊人色综合久久天天网| 老师的快感电影完整版| 91情国产l精品国产亚洲区| 挠黑色超薄丝袜脚心vk40分钟| 99精彩免费观看| 强奷乱码欧妇女中文字幕熟女| 大香交伊人| 亚洲AV美女成人网站P站| 吉吉av电影| 4虎影院午夜在线观看| 女张腿男人桶羞羞漫画| 大屁股国产白浆一二区| 乌克兰14一18处交见血| 黄色日本女人| 4455永久在线毛片观看| 日本一二三区在线视频| 99久久国语露脸精品国产| 日本红怡院亚洲红怡院最新| 国产欧美精品国产国产专区| 中国明星16xxxxhd| 日本中文字幕伊人成中文字幕|