Goの勉強録

とりわけ忙しい訳ではないのですが、今回の内容は紆余曲折しつつ結構ヘビーだったので勉強録の更新が遅れてしまいました。

過去の勉強録でだいたいGo言語でWebアプリケーションを作るのに最低限必要な技術は揃ったので、途中の成果物としてチャットアプリケーションを作っています。その中で色々試行錯誤していた中、結構つまづいたリバースプロキシの並列処理での実装などを勉強したのでそれをまとめていきたいと思います。
将来的には Angular + Go + Docker で一つのアプリケーションを作っていきたいと思っています。

過去の勉強録

    • Go言語の環境構築 Hello Worldまで

 

    • go言語 静的ページの作成

 

    • AngularJSのhttp通信からのpostリクエストをgo側で取得

 

    go言語でhtmlから取得したデータをjson形式で保存する

雑談

Angular + GoとGoogleに溺愛開発環境の中にDockerで運用するかと頑張っていました。Dockerいいですよね。。
コマンド一つで仮想マシン立ち上げられるし、設定ファイルに書き込むだけで色々できる。。なんでこんな便利なツールを知っておきながら勉強しなかったんやと後悔しました。まだまだDocker初心者ですがDockerの記事もまとめていこうかなと思います。

本題

今回の本題のgolangの特徴である並列処理を使ってリバースプロキシを実装しようというものです。
リバースプロキシについてこちらの記事のがわかりやすかったです。
今回の実装は9000、9001ポートでサーバを立てて9000に来たリクエストを9001に投げるという実装です。

では実装のコードをみていきましょう。

package main

import (
    "fmt"
    "log"
    "net/http"
    "net/http/httputil"
)

func main() {
    serve()
}

func serve() {
    // ポート 9000 と 9001 を開くチャンネルの作成
    hosting9000 := make(chan bool)
    hosting9001 := make(chan bool)

    // ポート 9000 に来たリクエストを 9001 に投げる処理の定義
    go func() {
        director := func(request *http.Request) {
            fmt.Println("Launch Reverse Proxy")
            request.URL.Scheme = "http"
            request.URL.Host = ":9000"
        }
        rp := &httputil.ReverseProxy{Director: director}
        server := http.Server{
            Addr:    ":9001",
            Handler: rp,
        }
        if err := server.ListenAndServe(); err != nil {
            log.Fatal(err.Error())
        }
        hosting9000 <- true
    }()

    // ポート 9001 でホスティングの処理の定義
    go func() {
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintf(w, "Hello Go")
            fmt.Println("Launch on 9001")
        })
        http.ListenAndServe(":9001", nil)
        hosting9001 <- true
    }()

    // チャンネルの呼び出し
    <-hosting9001
    <-hosting9000
}

go run main.goでlocalhost:9000にアクセスするとlogに Launch Reverse Proxy が出力され、 Launch on 9001 が出力されます。

まとめ

リバースプロキシを基本情報で知っていたけどどのような実装の仕方か分からなかったが、なんとなく実装の仕方がわかりました。

もっといい実装方法など指摘や質問を歓迎しています!

参考

https://kido0617.github.io/go/2016-08-10-reverse-proxy/
https://qiita.com/suin/items/82ecb6f63ff4104d4f5d

bannerAds