Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk melaksanakan anti-proksi dalam golang

Bagaimana untuk melaksanakan anti-proksi dalam golang

PHPz
PHPzasal
2023-04-25 09:11:361987semak imbas

Golang ialah bahasa pengaturcaraan yang cekap dan ringkas Sokongan serentak yang kuat dan kelajuan penyusunan pantas menjadikannya disegani secara meluas dalam bidang pengaturcaraan rangkaian. Proksi terbalik ialah seni bina rangkaian biasa yang memajukan permintaan ke pelayan yang berbeza untuk mengoptimumkan trafik rangkaian dan meningkatkan prestasi sistem. Dalam artikel ini, kita akan membincangkan cara melaksanakan proksi terbalik menggunakan Golang.

  1. Apakah proksi terbalik?

Proksi terbalik ialah seni bina rangkaian yang memajukan permintaan pelanggan ke pelayan hujung belakang dan kemudian mengembalikan respons kepada klien. Tidak seperti proksi hadapan, proksi terbalik menyembunyikan identiti pelayan bahagian belakang dan menyediakan beberapa perkhidmatan tambahan kepada pelanggan, seperti pengimbangan beban, caching dan peningkatan keselamatan.

Inti proksi terbalik ialah pengimbangan beban. Apabila pelanggan memulakan permintaan kepada proksi terbalik, proksi terbalik mengedarkan permintaan kepada pelayan bahagian belakang yang paling sesuai untuk memaksimumkan kecekapan dan prestasi rangkaian. Selain itu, proksi terbalik boleh mengurangkan beban pelayan melalui caching dan boleh menyediakan ciri seperti penamatan SSL dan tembok api untuk meningkatkan keselamatan rangkaian.

  1. Menggunakan Golang untuk melaksanakan proksi terbalik

Menggunakan Golang untuk melaksanakan proksi terbalik adalah sangat mudah. Golang menyediakan perpustakaan standard "net/http/httputil", yang mengandungi beberapa fungsi dan struktur berguna yang boleh melaksanakan proksi terbalik dengan mudah.

Berikut ialah contoh proksi terbalik Golang yang mudah:

package main

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

func main() {
    proxy := httputil.NewSingleHostReverseProxy(&url.URL{
        Scheme: "http",
        Host:   "localhost:8080",
    })
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        proxy.ServeHTTP(w, r)
    })
    log.Fatal(http.ListenAndServe(":3000", nil))
}

Dalam contoh ini, kami menggunakan fungsi httputil.NewSingleHostReverseProxy untuk mencipta objek proksi terbalik dan memajukan permintaan kepada hos tempatan Pelabuhan 8080. Kami kemudian menggunakan fungsi http.HandleFunc untuk mengaitkan fungsi pengendali dengan laluan "/" dan memulakan proksi terbalik pada pelayan tempatan di port 3000.

  1. Konfigurasi lanjutan proksi songsang

Proksi songsang yang dicipta oleh kod di atas adalah sangat mudah, tetapi dalam aplikasi sebenar, kami mungkin memerlukan konfigurasi yang lebih lanjut untuk memenuhi keperluan tertentu . Berikut ialah beberapa contoh konfigurasi lanjutan untuk proksi terbalik:

  • Pengimbangan Beban

Pengimbangan beban ialah salah satu fungsi teras proksi terbalik. Golang menyediakan beberapa algoritma untuk mengagihkan permintaan secara sama rata antara berbilang pelayan bahagian belakang. Berikut ialah contoh pengimbangan beban mudah:

package main

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

func main() {
    backends := []*url.URL{
        &url.URL{
            Scheme: "http",
            Host:   "localhost:8080",
        },
        &url.URL{
            Scheme: "http",
            Host:   "localhost:8081",
        },
        &url.URL{
            Scheme: "http",
            Host:   "localhost:8082",
        },
    }

    proxy := httputil.NewSingleHostReverseProxy(backends[0])
    proxy.Transport = &http.Transport{
        Dial: func(network, address string) (net.Conn, error) {
            return net.DialTimeout(network, address, time.Second)
        },
        MaxIdleConns:        10,
        IdleConnTimeout:     30 * time.Second,
        DisableCompression:  true,
    }

    proxy.ModifyResponse = func(r *http.Response) error {
        r.Header.Set("X-Proxy", "Golang Reverse Proxy")
        return nil
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        i := rand.Intn(len(backends))
        proxy.URL = backends[i]
        proxy.ServeHTTP(w, r)
    })

    log.Fatal(http.ListenAndServe(":3000", nil))
}

Dalam contoh ini, kami menggunakan tatasusunan hujung belakang yang mengandungi tiga pelayan hujung belakang dan pilih satu secara rawak apabila permintaan tiba. Kami juga menyediakan fungsi ModifyResponse yang menambahkan pengepala "X-Proxy" pada pengepala respons dan menggunakan medan httputil.ReverseProxy.Transport tersuai untuk membenarkan sifat sambungan rangkaian tersuai. Akhirnya, kami mempunyai pelayan proksi terbalik yang mendengar pada port tempatan 3000.

  • Penamatan SSL

Penamatan SSL ialah teknik yang boleh meningkatkan prestasi dan keselamatan tapak web. Proksi terbalik boleh berfungsi sebagai titik penamatan SSL, menerima permintaan SSL daripada pelanggan dan memajukan permintaan HTTP yang tidak disulitkan ke pelayan bahagian belakang. Jika aplikasi anda menggunakan penyulitan SSL, teknologi ini boleh menjadi cara terbaik untuk mengurangkan beban pada pelayan. Berikut ialah contoh penamatan SSL mudah:

package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/http/httputil"
    "net/url"
)

func main() {
    cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
    if err != nil {
        log.Fatalf("Failed to load keypair: %s", err)
    }

    certBytes, err := ioutil.ReadFile("cert.pem")
    if err != nil {
        log.Fatalf("Failed to read cert file: %s", err)
    }

    rootCAs := x509.NewCertPool()
    ok := rootCAs.AppendCertsFromPEM(certBytes)
    if !ok {
        log.Fatal("Failed to append root CA")
    }

    proxy := httputil.NewSingleHostReverseProxy(&url.URL{
        Scheme: "http",
        Host:   "localhost:8080",
    })
    proxy.Transport = &http.Transport{
        TLSClientConfig: &tls.Config{
            Certificates:       []tls.Certificate{cert},
            RootCAs:            rootCAs,
            InsecureSkipVerify: true,
        },
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        proxy.ServeHTTP(w, r)
    })

    log.Fatal(http.ListenAndServeTLS(":3000", "cert.pem", "key.pem", nil))
}

Dalam contoh ini kami memuatkan sijil TLS dan kunci peribadi daripada sistem fail menggunakan fungsi tls.LoadX509KeyPair dan membina akar menggunakan kumpulan Sijil fungsi x509.NewCertPool . Kami kemudiannya menetapkan sijil yang dimuatkan dan kumpulan sijil akar kepada medan httputil.ReverseProxy.Transport.TLSClientConfig untuk memastikan sambungan selamat kepada klien. Selain itu, kami menggunakan fungsi http.ListenAndServeTLS untuk menyokong sambungan HTTPS.

  • Caching

Caching ialah teknologi yang boleh meningkatkan prestasi proksi songsang dengan ketara. Proksi terbalik boleh menyimpan sumber statik bahagian hadapan, dengan itu mengurangkan tekanan pada pelayan. Berikut ialah contoh cache mudah:

package main

import (
    "bytes"
    "fmt"
    "log"
    "net/http"
    "net/http/httputil"
    "net/url"
    "time"
)

var cache = make(map[string]*bytes.Buffer)

func main() {
    proxy := httputil.NewSingleHostReverseProxy(&url.URL{
        Scheme: "http",
        Host:   "localhost:8080",
    })

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        if r.Method == "GET" {
            if buf, ok := cache[r.URL.Path]; ok {
                w.Write(buf.Bytes())
                return
            }
        }

        if r.Method == "POST" || r.Method == "PUT" || r.Method == "DELETE" {
            delete(cache, r.URL.Path)
        }

        proxy.ServeHTTP(w, r)

        if r.Method == "GET" && r.Header.Get("Cache-Control") != "no-cache" {
            buf := bytes.NewBuffer(nil)
            buf.ReadFrom(w.(http.ResponseWriter))
            cache[r.URL.Path] = buf
        }
    })

    log.Fatal(http.ListenAndServe(":3000", nil))
}

Dalam contoh ini, kami menggunakan cache pembolehubah peta untuk menyimpan hasil jawapan yang dicache. Apabila sumber yang sepadan wujud dalam cache, kami boleh terus mengembalikan hasilnya kepada klien tanpa meminta pelayan bahagian belakang. Dan kami menggunakan jenis asas *bytes.Buffer antara muka http.ResponseWriter untuk cache hasil respons. Selain itu, apabila kaedah permintaan ialah POST, PUT atau DELETE, kami memadamkan cache supaya data yang dikemas kini diambil daripada pelayan bahagian belakang. Akhir sekali, kami mengendalikan sama ada kami perlu menyimpan cache hasil respons dengan menyemak medan "Cache-Control" dalam pengepala permintaan.

  1. Kesimpulan

Proksi songsang ialah seni bina rangkaian berkuasa yang boleh meningkatkan prestasi dan keselamatan sistem dengan ketara dengan menyembunyikan pelayan bahagian belakang dan menyediakan pelbagai perkhidmatan seks tambahan. Sangat mudah untuk melaksanakan proksi terbalik menggunakan Golang menyediakan banyak fungsi dan struktur yang berguna untuk membuat pelayan proksi terbalik dengan mudah. Dalam artikel ini, kami memperkenalkan konsep asas proksi terbalik dan menunjukkan cara melaksanakan konfigurasi berbeza proksi terbalik lanjutan menggunakan Golang.

Atas ialah kandungan terperinci Bagaimana untuk melaksanakan anti-proksi dalam golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn