Upgrade to Pro — share decks privately, control downloads, hide ads and more …

通信の不安定さに悩んでいたらシュッとプロキシを書けて改善できちゃった話

 通信の不安定さに悩んでいたらシュッとプロキシを書けて改善できちゃった話

SUZUKI Yoshiharu

June 06, 2024
Tweet

More Decks by SUZUKI Yoshiharu

Other Decks in Programming

Transcript

  1. 2 ⾃⼰紹介 ▪名前 鈴⽊ 善晴 / Yoshiharu Suzuki ▪所属 株式会社

    HRBrain テックリード 兼 バックエンドエンジニア ▪Go歴 4年
  2. 10 構成技術 標準(または準標準)の技術だけで、2⽇程度でプロキシを実現! • http.RoundTripper インターフェース … 「⼀回のHTTP通信」を表すインターフェース • golang.org/x/sync/semaphore

    パッケージ … セマフォの提供 💡セマフォとは? • コンピュータの並行処理において、共有リソースのアクセスを制御し、 競合を防ぐための機構 • カウンターを用いて、特定のリソースの利用可能数を管理する
  3. 11 ⼟台となるリバースプロキシを⽤意する func main() { target, _ := url.Parse("http://localhost:8080") //

    リバースプロキシの作成 proxy := httputil.NewSingleHostReverseProxy(target) // サーバ起動 srv := &http.Server{ Addr: ":9999", Handler: proxy, } _ = srv.ListenAndServe() }
  4. 12 通信に⼿を⼊れる余地を作る http.RoundTripperを加える // カスタマイズするための構造体 type c struct{} func (c

    *c) RoundTrip(r *http.Request) (*http.Response, error) { // 標準で用意されているデフォルト実装へ移譲するだけ return http.DefaultTransport.RoundTrip(r) } func main() { ... proxy := httputil.NewSingleHostReverseProxy(target) // プロキシの動きをカスタマイズ proxy.Transport = &c{} ... } 2:50
  5. 13 同時通信に上限を設定して完成🙌 semaphoreも加える type c struct { sem *semaphore.Weighted //

    同時通信を制御するセマフォ } func (c *c) RoundTrip(r *http.Request) (*http.Response, error) { _ = c.sem.Acquire(r.Context(), 1) // 1通信につき1つ使う defer c.sem.Release(1) // 最後に解放 return http.DefaultTransport.RoundTrip(r) } func main() { ... proxy := httputil.NewSingleHostReverseProxy(target) proxy.Transport = &c{ sem: semaphore.NewWeighted(1), // 同時通信の上限が1の例 } ... } 󰢃 󰢃 󰢏 3:35
  6. 14 同時通信に上限を設定して完成🙌 semaphoreも加える type c struct { sem *semaphore.Weighted //

    同時通信を制御するセマフォ } func (c *c) RoundTrip(r *http.Request) (*http.Response, error) { _ = c.sem.Acquire(r.Context(), 1) // 1通信につき1つ使う defer c.sem.Release(1) // 最後に解放 return http.DefaultTransport.RoundTrip(r) } func main() { ... proxy := httputil.NewSingleHostReverseProxy(target) proxy.Transport = &c{ sem: semaphore.NewWeighted(1), // 同時通信の上限が1の例 } ... } 󰢃 󰢃 󰢏