インターネットの急速な発展に伴い、さまざまなサーバーからデータを取得する必要があるアプリケーションが増えており、これらのデータ要求は複数の中間サーバーを経由する必要があるため、アプリケーションの開発時にプロキシの使用が必要になることがよくあります。要求は、必要なデータが取得されるまでリモート サーバーに送信されます。
この記事では、Go 言語を使用して、クライアントのリクエストを別のサーバーに転送して応答を返す単純なプロキシ サーバーを構築する方法を紹介します。プロキシ サーバーは複数のクライアント リクエストを効率的に処理できるため、バックエンド サーバーへの負担が軽減され、アプリケーションのパフォーマンスとスケーラビリティが向上します。
概要
この記事では、受信リクエストをクライアントに送信し、応答をターゲット サーバーに転送する golang ベースのプロキシ サーバーを作成する方法を学びます。標準ライブラリ net/http 実装を使用します。これは、HTTP リクエストとレスポンスを処理するためのシンプルかつ効率的な方法を提供します。
準備
プロキシ サーバーの作成を開始する前に、まず Go 環境をインストールする必要があります。 Go は公式 Web サイト https://golang.org/ からダウンロードしてインストールできます。
プロキシ サーバーの仕組み
プロキシ サーバーでは、Go 言語の net/http パッケージを使用して、クライアントのリクエストをインターセプトするコードを記述する必要があります。このパッケージは、HTTP 要求と応答を処理およびデコードするための多くの便利な関数と構造を提供します。プロキシ サーバーでは、http.Handle() 関数を使用してクライアントのリクエストをインターセプトし、リモート サーバーにリダイレクトします。次に、http.Client() 構造を使用してリモート サーバーにリクエストを送信し、クライアントに応答を返します。
次の疑似コードは、プロキシ サーバーがどのように動作するかを示しています。
クライアントがリクエストを行うとき:
プロキシ サーバーの作成
次に、プロキシ サーバーの実装の作成を開始しましょう。 HTTP サーバーを作成し、そのリスニング アドレス、ポート、クライアントの待ち時間を設定する必要があります。また、クライアントのリクエストに基づいて異なるハンドラーが選択されるように、ルーティング ルールを追加する必要もあります。この例では、http.Handle() 関数を使用してルートを追加し、クライアントからリクエストされた URL が /proxy の場合、リクエストを指定されたサーバーにリダイレクトします。以下はコード スニペットです:
package main import ( "log" "net/http" ) func main() { // 创建 http 服务器 proxy := &Proxy{} // 添加路由规则 http.Handle("/proxy", proxy) // 监听地址及端口 log.Fatal(http.ListenAndServe(":8080", nil)) } // 代理服务器结构体 type Proxy struct { } // 实现 http.Handler 接口的 ServeHTTP 方法 func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { // 处理代理请求 }
上記のコードでは、Proxy という名前の構造を作成し、その構造の http.Handler インターフェイスに ServeHTTP() メソッドを実装します。 ServeHTTP() メソッドは、http.ResponseWriter オブジェクトと *http.Request オブジェクトの 2 つのパラメータを受け取ります。前者はサーバーからクライアントに返されるデータを表し、後者はクライアントから要求された HTTP リクエスト ヘッダーとリクエスト本文を表します。
次に、クライアントが URL で /proxy をリクエストしたときに設定するルーティング ルールを追加して設定します。リクエストはハンドラーにリダイレクトされます。
次に、プロキシ リクエストを処理するコードを記述する必要があります。ターゲットサーバーが存在すること、およびクライアントによって要求されたデータが正しいことを確認する必要があります。ここでは、http.NewRequest() 関数を使用して、新しい HTTP リクエスト オブジェクトを作成できます。次に、http.Client() の Do() メソッドを使用してリクエストを送信し、応答を待ちます。最後に、クライアントに応答を返します。
以下は完全なコードです:
package main
import (
"io/ioutil" "log" "net/http"
)
func main() {
// 创建 http 服务器 proxy := &Proxy{} // 添加路由规则 http.Handle("/proxy", proxy) // 监听地址及端口 log.Fatal(http.ListenAndServe(":8080", nil))
}
// プロキシ サーバーの構造
type Proxy struct {
}
// net/http.Handler インターフェイスの ServeHTTP メソッドを実装します
func (p Proxy) ServeHTTP(w http.ResponseWriter, r http.Request) {
// 检查目标服务器是否存在 targetUrl := "http://localhost:8888" if len(targetUrl) == 0 { w.WriteHeader(http.StatusBadGateway) return } // 检查客户端请求的数据是否正确 if r.Method != "GET" { w.WriteHeader(http.StatusMethodNotAllowed) return } // 创建一个新的 HTTP 请求对象 req, err := http.NewRequest("GET", targetUrl, nil) if err != nil { log.Fatal("请求创建失败", err) } // 使用 http.Client() 发送请求 client := &http.Client{} resp, err := client.Do(req) if err != nil { log.Fatal("请求发送失败", err) } defer resp.Body.Close() // 读取响应的数据 body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal("读取响应数据失败", err) } // 将响应数据返回给客户端 w.Write(body)
}
运行代理服务器 现在我们已经完成了代理服务器的编写,请使用以下命令在命令行中运行该服务器,其中 targetUrl 是我们要转发的目标服务器的 IP 地址和端口。 $ go run main.go -targetUrl=http://localhost:8888 接下来,在浏览器中输入以下 URL,将客户端请求发送到代理服务器中: http://localhost:8080/proxy 此时,代理服务器将转发该请求到目标服务器,并等待响应。当目标服务器返回响应时,代理服务器将响应数据返回给客户端。我们可以在代码中设置超时时间来控制客户端请求的等待时间,以及设置日志记录来实时查看代理服务器的运行情况。 结论 本文介绍了如何使用 Go 语言构建代理服务器,并演示了代理服务器的操作流程。虽然我们实现的代理服务器比较简单,但可以轻松扩展它来处理更复杂的请求。如果您有进一步的需求,可以使用类似的方法来扩展该服务器,以更好地满足您的需求。
以上がgolangプロキシ転送の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。