網(wǎng)頁在線代理服務器(網(wǎng)頁在線代理瀏覽)

上述命令會用提供的腳本啟動 Pipy 服務器。敏銳的用戶可能已經(jīng)注意到,我們通過環(huán)境變量PIPY_CONFIG_FILE提供了一個遠程 Pipy 腳本的鏈接,而不是一個本地文件,Pipy 足夠智能,可以處理這種情況。


下面是tutorial/01-hello/hello.js文件的內(nèi)容,供參考:

pipy()




.listen(8080)
  .serveHTTP(
    new Message('Hi, there!\n')
  )

在這個腳本中,我們定義了一個端口管道,它監(jiān)聽 8080 端口,并為從監(jiān)聽端口收到的每個 HTTP 請求返回“Hi, there!”。


既然我們已經(jīng)通過上面的docker run命令暴露了本地 8080 端口,那么我們可以在同一端口上進行測試了:

$ curl http://localhost:8080

執(zhí)行上述命令,控制臺中應該顯示“Hi, there!”。


如果是出于學習、開發(fā)或調(diào)試的目的,建議在本地安裝 Pipy(從源代碼構(gòu)建 Pipy 或針對你的操作系統(tǒng)下載一個預構(gòu)建版本),因為它提供了 Web 管理控制臺以及相關(guān)的文檔和教程。


安裝到本地后,運行pipy,不需要任何參數(shù),就可以在6060端口啟動管理控制臺,但如果要監(jiān)聽不同的端口,可以通過--admin-port=參數(shù)配置。


監(jiān)聽 6060 端口的 Pipy 管理控制臺


要從源代碼構(gòu)建 Pipy 或針對你的操作系統(tǒng)安裝預編譯的二進制文件,請參考PipyGitHub 庫的 README.md 文件。

通過 CLI 運行

要啟動 Pipy 代理,可以用一個 PipyJS 腳本文件運行 Pipy。例如,如果需要一個簡單的回顯服務器,針對每個傳入的請求都用所接收到的消息體進行響應,那么就用腳本tutorial/01-hello/hello.js:

$ pipy tutorial/01-hel lo/hello.js

另外,在開發(fā)和調(diào)試時,可以啟動帶有內(nèi)置 Web UI 的 Pipy:

$ pipy tutorial/01-hello/hello.js --admin-port=6060

顯示命令行選項

$ pipy --help

列出內(nèi)置過濾器及其參數(shù)

$ pipy --list-filters
$ pipy --help-filters   

前文從概念和技術(shù)上對 Pipy 做了一個簡短的介紹,這些內(nèi)容也是我們實現(xiàn)一個支持緩存和負載均衡的網(wǎng)絡代理所需要了解的,這一點我們在下一節(jié)會看到。

編寫一個網(wǎng)絡代理

假設(shè)我們正在運行不同服務的單獨實例,我們想要添加一個代理,根據(jù)請求的 URL 路徑將流量轉(zhuǎn)發(fā)到相關(guān)服務。這樣做的好處是,我們只需要提供一個 URL,并在后端擴展我們的服務,而用戶不需要分別記住不同服務的 URL。在正常情況下,服務會在不同的節(jié)點上運行,每個服務可以有多個實例在運行。假設(shè)在這個例子中,我們正在運行下面的服務,我們希望根據(jù) URI 將流量分配給它們。

服務

URI

主機:端口

service-hi

/hi/*

"127.0.0.1:8080", "127.0.0.1:8082"

service-echo

/echo

"127.0.0.1:8081"

service-tell-ip

/ip/*

"127.0.0.1:8082"

Pipy 的腳本是用 JavaScript 編寫的,你可以用任何文本編輯器來編輯它們。另外,如果你在本地安裝了 Pipy,就可以使用 Pipy 提供的 Web 端管理 UI,它提供了語法高亮、自動完成、提示等特性,你甚至可以運行腳本,所有這些都在同一個控制臺上。


好了,讓我們啟動一個 Pipy 實例,不需要任何參數(shù),這樣,Pipy 管理控制臺將在 6060 端口啟動。現(xiàn)在,打開你喜歡的 Web 瀏覽器,導航到 http://localhost:6060,就會看到 Pipy 內(nèi)置的 Web 端管理 UI(如圖 1)。

創(chuàng)建一個 Pipy 程序

將代碼和配置分開是一種很好的設(shè)計實踐。Pipy 通過插件(你可以把它想成是 JavaScript 模塊)來支持這種模塊化設(shè)計。也就是說,我們將把配置數(shù)據(jù)存儲在 config 文件夾下,把編碼邏輯存儲在 plugins 文件夾下不同的文件中。主代理服務器腳本將存儲在根目錄下,主代理腳本(proxy.js)將包含并組合這些單獨的模塊所定義的功能。 一旦我們完成了下述步驟,最終的文件夾結(jié)構(gòu)將是下面這個樣子:

├── config
│   ├── balancer.JSON
│   ├── proxy.json
│   └── Router.json
├── plugins
│   ├── balancer.js
│   ├── default.js
│   └── router.js
└── proxy.js

讓我們開始吧:

  1. 點擊新建代碼庫,在對話框中輸入/proxy(或任何你想使用的名稱)作為代碼庫名稱,然后點擊創(chuàng)建。你將進入到新創(chuàng)建的代碼庫的代碼編輯器。
  2. 點擊上面的“+”按鈕,添加一個新文件。輸入/config/proxy.json(這是配置文件,我們將用來配置代理)作為文件名,然后點擊創(chuàng)建。
  3. 現(xiàn)在,你會看到,左側(cè)窗格的config文件夾下多了一個proxy.json文件。點擊該文件把它打開,并添加如下所示的配置信息,務必點擊頂部面板上的磁盤圖標來保存文件:
{
  "listen": 8000,
  "plugins": [
    "plugins/router.js",
    "plugins/balancer.js",
    "plugins/default.js"
  ]
}
  1. 重復步驟 2 和 3,創(chuàng)建另一個文件/config/router.json,它將存儲路由信息,配置數(shù)據(jù)如下:
{
  "routes": {
    "/hi/*": "service-hi",
    "/echo": "service-echo",
    "/ip/*": "service-tell-ip"
  }
}
  1. 重復步驟 2 和 3,創(chuàng)建另一個文件/config/balancer.json,它將存儲服務到目標的映射信息,內(nèi)容如下:
 {
  "services": {
    "service-hi"      : ["127.0.0.1:8080", "127.0.0.1:8082"],
    "service-echo"    : ["127.0.0.1:8081"],
    "service-tell-ip" : ["127.0.0.1:8082"]
  }
}
  1. 現(xiàn)在,我們編寫第一個 Pipy 腳本,當我們收到一個沒有配置任何目標(端點/url)的請求時,它將被用作默認的后備選項。重復上述步驟,創(chuàng)建文件/plugins/default.js。使用 default 作為文件名只是一個習慣做法,并不是 Pipy 的要求,你可以選擇任何你喜歡的名字。該腳本將包含如下代碼,返回 HTTP 狀態(tài)代碼 404,信息為 No handler found:
pipy()




.pipeline('request')
  .replaceMessage(
    new Message({ status: 404 }, 'No handler found')
  )
  1. 創(chuàng)建/plugins/router.js文件,存儲路由邏輯:
(config =>




pipy({
  _router: new algo.URLRouter(config.routes),
})




.export('router', {
  __serviceID: '',
})




.pipeline('request')
  .handleMessageStart(
    msg => (
      __serviceID = _router.find(
        msg.head.headers.host,
        msg.head.path,
      )
    )
  )




)(JSON.decode(pipy.load('config/router.json')))
  1. 創(chuàng)建/plugins/balancer.js文件,存儲了我們的負載均衡邏輯。順便說明一下,Pipy 提供了多種負載均衡算法,但簡單起見,我們這里將使用 Round Robin 算法。
(config =>




pipy({
  _services: (
    Object.fromEntries(
      Object.entries(config.services).map(
        ([k, v]) => [
          k, new algo.RoundRobinLoadBalancer(v)
        ]
      )
    )
  ),




  _balancer: null,
  _balancerCache: null,
  _target: '',
})




.import({
  __turnDown: 'proxy',
  __serviceID: 'router',
})




.pipeline('session')
  .handleStreamStart(
    () => (
      _balancerCache = new algo.Cache(
        // k is a balancer, v is a target
        (k  ) => k.select(),
        (k,v) => k.deselect(v),
      )
    )
  )
  .handleStreamEnd(
    () => (
      _balancerCache.clear()
    )
  )




.pipeline('request')
  .handleMessageStart(
    () => (
      _balancer = _services[__serviceID],
      _balancer && (_target = _balancerCache.get(_balancer)),
      _target && (__turnDown = true)
    )
  )
  .link(
    'forward', () => Boolean(_target),
    ''
  )




.pipeline('forward')
  .muxHTTP(
    'connection',
    () => _target
  )




.pipeline('connection')
  .connect(
    () => _target
  )




)(JSON.decode(pipy.load('config/balancer.json')))
  1. 現(xiàn)在,我們來編寫入口點或代理服務器腳本,它會使用上述插件。創(chuàng)建一個新的代碼庫(步驟 1),這個過程會創(chuàng)建一個默認的main.js文件作為入口點。我們可以用它作為我們的主入口點,或者如果你希望換個名字,可以隨時刪除main.js,然后用你選的名字新建一個文件。讓我們刪除它并新建一個名為/proxy.js的文件。務必點下頂部的旗標,將其設(shè)置為主入口點,這可以確保在你點擊運行按鈕(右側(cè)的箭頭圖標)時開始執(zhí)行腳本:
(config =>




pipy()




.export('proxy', {
  __turnDown: false,
})




.listen(config.listen)
  .use(config.plugins, 'session')
  .demuxHTTP('request')




.pipeline('request')
  .use(
    config.plugins,
    'request',
    'response',
    () => __turnDown
  )




)(JSON.decode(pipy.load('config/proxy.json')))

如果你已經(jīng)按照上面的步驟進行了操作,就可以看到類似于以下截圖的東西:



現(xiàn)在,我們點擊播放圖標按鈕(右起第四個)來運行我們的腳本。如果腳本沒有任何錯誤,我們將看到 Pipy 運行我們的代理腳本,輸出類似下面這樣:



這表明我們的代理服務器正在監(jiān)聽 8000 端口(這是在/config/proxy.json中配置的)。我們用 curl 來運行一個測試:

$ curl -i http://localhost:8000




HTTP/1.1 404 Not Found
content-length: 10
connection: keep-alive




No handler found

這沒問題,因為我們沒有為 root 配置任何目標。讓我們試下配置過的路由,如/hi

$ curl -i http://localhost:8000/hi




HTTP/1.1 502 Connection Refused
content-length: 0
connection: keep-alive

我們看到了 502 Connection Refused 這個消息,因為我們沒有在配置的目標端口上運行服務。


你可以更新/config/balancer.json,加入你已經(jīng)運行的服務的主機、端口等細節(jié),以匹配你的實際情況,或者我們在 Pipy 中編寫一個腳本,監(jiān)聽我們配置的端口,并返回簡單的消息。


將以下代碼片段保存到你本地計算機上的一個文件中,命名為mock-proxy.js,并記住文件的存儲位置。

pipy()




.listen(8080)
  .serveHTTP(
    new Message('Hi, there!\n')
  )




.listen(8081)
  .serveHTTP(
    msg => new Message(msg.body)
  )




.listen(8082)
  .serveHTTP(
    msg => new Message(
      `You are requesting ${msg.head.path} from ${__inbound.remoteAddress}\n`
    )
  )

打開一個新的終端窗口,通過 Pipy 運行這個腳本(其中/path/to是存儲該腳本文件的位置):

$ pipy /path/to/mock-proxy.js




2022-01-11 18:56:31 [INF] [config]
2022-01-11 18:56:31 [INF] [config] Module /mock-proxy.js
2022-01-11 18:56:31 [INF] [config] ================
2022-01-11 18:56:31 [INF] [config]
2022-01-11 18:56:31 [INF] [config]  [Listen on :::8080]
2022-01-11 18:56:31 [INF] [config]  ----->|
2022-01-11 18:56:31 [INF] [config]        |
2022-01-11 18:56:31 [INF] [config]       serveHTTP
2022-01-11 18:56:31 [INF] [config]        |
2022-01-11 18:56:31 [INF] [config]  <-----|
2022-01-11 18:56:31 [INF] [config]  
2022-01-11 18:56:31 [INF] [config]  [Listen on :::8081]
2022-01-11 18:56:31 [INF] [config]  ----->|
2022-01-11 18:56:31 [INF] [config]        |
2022-01-11 18:56:31 [INF] [config]       serveHTTP
2022-01-11 18:56:31 [INF] [config]        |
2022-01-11 18:56:31 [INF] [config]  <-----|
2022-01-11 18:56:31 [INF] [config]  
2022-01-11 18:56:31 [INF] [config]  [Listen on :::8082]
2022-01-11 18:56:31 [INF] [config]  ----->|
2022-01-11 18:56:31 [INF] [config]        |
2022-01-11 18:56:31 [INF] [config]       serveHTTP
2022-01-11 18:56:31 [INF] [config]        |
2022-01-11 18:56:31 [INF] [config]  <-----|
2022-01-11 18:56:31 [INF] [config]  
2022-01-11 18:56:31 [INF] [listener] Listening on port 8080 at ::
2022-01-11 18:56:31 [INF] [listener] Listening on port 8081 at ::
2022-01-11 18:56:31 [INF] [listener] Listening on port 8082 at ::

現(xiàn)在,我們已經(jīng)模擬了監(jiān)聽 8080、8081 和 8082 端口的服務。讓我們在代理服務器上再做一次測試,你會看到,模擬服務返回了正確的響應。

小結(jié)

我們使用了 Pipy 的許多特性,包括變量聲明、導入/導出變量、插件、管道子管道、過濾器鏈、handleMessageStart、handleStreamStart和link等 Pipy 過濾器,以及JSON、algo.URLRouter、algo.RoundRobinLoadBalancer和algo.Cache等 Pipy 類。徹底解釋所有這些概念超出了本文的范圍,如果你希望了解更多信息,請閱讀 Pipy 的文檔。你可以通過 Pipy 的 Web 端管理 UI 查看這些文檔,并按照入門教程一步步操作。

結(jié)語

來自Flomesh的 Pipy 是一個開源、高性能、輕量級的網(wǎng)絡流量處理器,適用于多種場景,包括邊緣路由器、負載平衡 &代理(正向/反向)、API 網(wǎng)關(guān)、靜態(tài) HTTP 服務器、服務網(wǎng)格挎斗等。Pipy 仍在積極開發(fā)之中,并由全職的提交者和貢獻者維護,雖然仍是早期版本,但已有多個商業(yè)客戶完成了測試并投入生產(chǎn)應用。它的創(chuàng)建者和維護者Flomesh.cn提供的商用解決方案就是以 Pipy 為核心。


這篇文章對 Pipy 做了一個非常簡要的介紹和概述。GitHub 上提供了入門教程和文檔,你也可以通過 Pipy 管理控制臺的 Web UI 查看。社區(qū)非常歡迎大家為 Pipy 的發(fā)展做貢獻,也歡迎大家在自己特定的場景下進行試用,或者提供反饋和意見。


作者簡介:

Ali Naqvi 是一位擁有超過 20 年 IT 行業(yè)經(jīng)驗的專業(yè)人士。他非常熱衷于開發(fā)以及為開源軟件做貢獻。他主要關(guān)注開發(fā)、軟件架構(gòu)、DevOps 等領(lǐng)域。他經(jīng)常發(fā)表演講,是當?shù)厣鐓^(qū)/分會的活躍成員,致力于傳播 OSS、DevOps 和 Agile 理念和知識。


原文鏈接:

How to Create a Network Proxy Using Stream Processor Pipy

好了,這篇文章的內(nèi)容發(fā)貨聯(lián)盟就和大家分享到這里,如果大家網(wǎng)絡推廣引流創(chuàng)業(yè)感興趣,可以添加微信:80709525  備注:發(fā)貨聯(lián)盟引流學習; 我拉你進直播課程學習群,每周135晚上都是有實戰(zhàn)干貨的推廣引流技術(shù)課程免費分享!


版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 sumchina520@foxmail.com 舉報,一經(jīng)查實,本站將立刻刪除。

您可能還會喜歡:

發(fā)表評論

◎歡迎參與討論,請在這里發(fā)表您的看法、交流您的觀點。