Golang proxy: Dùng proxy HTTP, SOCKS5 trong net/http
Golang proxy là cách cấu hình chương trình viết bằng Go gửi yêu cầu HTTP qua máy chủ trung gian. Gợi ý tìm kiếm có đủ cụm "golang proxy http request", "socks5", "environment variable", cho thấy lập trình viên cần cả ba kiểu cấu hình. Bài này ProxyVN đi từ cơ chế của net/http tới mã chạy được cho HTTP, HTTPS, SOCKS5, xoay proxy và phân biệt với GOPROXY.
Tổng quan về Golang proxy
Trong Go, mọi yêu cầu HTTP đi qua http.Client, và http.Client dùng một http.Transport để mở kết nối. Theo tài liệu gói net/http, Transport có trường Proxy là một hàm nhận yêu cầu và trả về địa chỉ proxy cần dùng. Golang proxy về bản chất là cách đặt hàm này cho đúng.

Transport quyết định đường đi
Hàm Proxy của Transport
Hàm Proxy có dạng func(*http.Request) (*url.URL, error). Với mỗi yêu cầu, Transport gọi hàm này. Nếu hàm trả về URL, yêu cầu đi qua proxy đó. Nếu trả về nil, yêu cầu đi thẳng. Nếu trả về lỗi, yêu cầu thất bại. Thiết kế này cho phép chọn proxy khác nhau cho từng yêu cầu, rất tiện khi cần xoay proxy.
Hai hàm có sẵn
Gói net/http cung cấp hai hàm dựng sẵn:
- http.ProxyFromEnvironment: đọc biến môi trường HTTP_PROXY, HTTPS_PROXY, NO_PROXY và chữ thường tương ứng. Transport mặc định dùng hàm này.
- http.ProxyURL(u): luôn trả về một proxy cố định u.
Golang proxy khác GOPROXY
Đây là điểm nhiều người mới nhầm. GOPROXY là biến cấu hình của công cụ go, quyết định nơi tải module khi chạy go get, go mod download, mặc định là proxy.golang.org. Nó không liên quan tới việc chương trình của anh em gửi HTTP qua proxy. Phần cuối bài sẽ nói rõ hơn.
Cấu hình Golang proxy bằng biến môi trường
Cách nhanh nhất để chương trình Go đi qua proxy là đặt biến môi trường. Transport mặc định dùng http.ProxyFromEnvironment nên không cần sửa mã.
Đặt biến môi trường
Trên Windows PowerShell:
$env:HTTP_PROXY = "http://user01:matkhau01@103.x.x.11:8080"
$env:HTTPS_PROXY = "http://user01:matkhau01@103.x.x.11:8080"
$env:NO_PROXY = "localhost,127.0.0.1,.congty.vn"
go run main.go
Trên Linux, macOS dùng export HTTP_PROXY=... thay cho $env. HTTPS_PROXY áp dụng cho yêu cầu tới địa chỉ https, HTTP_PROXY cho địa chỉ http. Giá trị của HTTPS_PROXY vẫn thường là http:// vì kết nối tới proxy là HTTP, sau đó dựng đường hầm CONNECT tới website HTTPS.
Mã dùng biến môi trường
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
resp, err := http.Get("https://api.ipify.org")
if err != nil {
panic(err)
}
defer resp.Body.Close()
b, _ := io.ReadAll(resp.Body)
fmt.Println("IP:", string(b))
}
Chương trình in ra IP proxy nếu biến môi trường đúng. http.Get dùng http.DefaultClient, vốn dùng Transport mặc định đọc biến môi trường.
Lưu ý với localhost
Hàm ProxyFromEnvironment không dùng proxy cho yêu cầu tới localhost và 127.0.0.1. Đây là hành vi có chủ đích. Nếu cần kiểm thử proxy với máy chủ cục bộ, dùng http.ProxyURL thay vì biến môi trường. Bài no_proxy là gì giải thích cú pháp NO_PROXY.
Cấu hình Golang proxy HTTP cố định trong mã
Khi không muốn phụ thuộc biến môi trường, đặt proxy ngay trong mã bằng http.ProxyURL.
Mã mẫu
package main
import (
"fmt"
"io"
"net/http"
"net/url"
"time"
)
func main() {
pu, _ := url.Parse("http://user01:matkhau01@103.x.x.11:8080")
tr := &http.Transport{
Proxy: http.ProxyURL(pu),
MaxIdleConns: 50,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
}
client := &http.Client{Transport: tr, Timeout: 20 * time.Second}
resp, err := client.Get("https://api.ipify.org")
if err != nil {
fmt.Println("loi:", err)
return
}
defer resp.Body.Close()
b, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode, string(b))
}
Tài khoản và mật khẩu nằm trong URL proxy. Transport tự gửi header Proxy-Authorization theo kiểu Basic. Gói net/url xử lý việc phân tích URL.
Mật khẩu có ký tự đặc biệt với url.UserPassword
Nếu mật khẩu chứa @, :, /, #, dựng URL bằng url.UserPassword thay vì ghép chuỗi:
pu := &url.URL{
Scheme: "http",
Host: "103.x.x.11:8080",
User: url.UserPassword("user01", "m@t:khau#01"),
}
Cách này tự mã hoá ký tự đặc biệt, tránh lỗi 407 khó hiểu. Lỗi 407 nói chung được giải thích trong bài sửa lỗi 407 proxy authentication required.
Tái sử dụng Client
Tạo một http.Client dùng chung cho nhiều yêu cầu, không tạo mới mỗi lần. Transport giữ kết nối để dùng lại, tạo mới liên tục làm cạn cổng và chậm chương trình.
Cấu hình Golang proxy SOCKS5
Go hỗ trợ SOCKS5 theo hai cách: qua http.ProxyURL với scheme socks5, hoặc qua gói golang.org/x/net/proxy.

HTTP proxy và SOCKS5 trong Go
Cách 1: Scheme socks5 trong http.ProxyURL
Transport của Go nhận URL proxy dạng socks5://. Cách này đơn giản nhất:
pu, _ := url.Parse("socks5://user01:matkhau01@103.x.x.11:1080")
client := &http.Client{
Transport: &http.Transport{Proxy: http.ProxyURL(pu)},
Timeout: 20 * time.Second,
}
Tài khoản và mật khẩu được gửi theo cơ chế xác thực của SOCKS5 trong RFC 1929. Tên miền được gửi cho proxy phân giải.
Cách 2: Gói golang.org/x/net/proxy
Gói golang.org/x/net/proxy cung cấp hàm SOCKS5 trả về một Dialer. Dialer này dùng được cho cả HTTP lẫn kết nối TCP thô:
package main
import (
"context"
"fmt"
"io"
"net"
"net/http"
"time"
"golang.org/x/net/proxy"
)
func main() {
auth := &proxy.Auth{User: "user01", Password: "matkhau01"}
d, err := proxy.SOCKS5("tcp", "103.x.x.11:1080", auth, proxy.Direct)
if err != nil {
panic(err)
}
cd := d.(proxy.ContextDialer)
tr := &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return cd.DialContext(ctx, network, addr)
},
}
client := &http.Client{Transport: tr, Timeout: 20 * time.Second}
resp, err := client.Get("https://api.ipify.org")
if err != nil {
fmt.Println("loi:", err)
return
}
defer resp.Body.Close()
b, _ := io.ReadAll(resp.Body)
fmt.Println(string(b))
}
Cài gói bằng lệnh go get golang.org/x/net. Cách này hợp khi cần kết nối TCP không phải HTTP qua SOCKS5, ví dụ giao thức riêng.
Chọn HTTP hay SOCKS5 cho chương trình Go
Với yêu cầu web thông thường, cả hai đều chạy tốt. HTTP dễ gỡ lỗi hơn vì nhiều công cụ hỗ trợ. SOCKS5 hợp khi cần chuyển lưu lượng không phải HTTP. Bài proxy HTTP và SOCKS5 khác nhau thế nào phân tích kỹ.
Xoay Golang proxy theo từng yêu cầu
Khi thu thập dữ liệu khối lượng lớn, xoay proxy giúp phân tán yêu cầu. Nhờ hàm Proxy nhận từng yêu cầu, Go cho phép xoay rất gọn.

Xoay proxy theo yêu cầu
Xoay vòng tròn bằng hàm Proxy
package main
import (
"net/http"
"net/url"
"sync/atomic"
"time"
)
func newRotatingClient(list []string) *http.Client {
var urls []*url.URL
for _, s := range list {
u, err := url.Parse(s)
if err == nil {
urls = append(urls, u)
}
}
var n uint64
pick := func(_ *http.Request) (*url.URL, error) {
i := atomic.AddUint64(&n, 1)
return urls[int(i)%len(urls)], nil
}
return &http.Client{
Transport: &http.Transport{Proxy: pick, MaxIdleConnsPerHost: 4},
Timeout: 20 * time.Second,
}
}
Biến đếm dùng atomic để an toàn khi nhiều goroutine cùng gửi yêu cầu. Mỗi yêu cầu nhận proxy kế tiếp trong danh sách.
Lưu ý về kết nối được giữ lại
Transport giữ kết nối nhàn rỗi để dùng lại theo từng proxy. Với danh sách proxy dài, số kết nối giữ lại có thể lớn. Đặt MaxIdleConnsPerHost và IdleConnTimeout hợp lý để không chiếm quá nhiều tài nguyên.
Proxy xoay một cổng
Nếu nhà cung cấp có proxy xoay với một cổng cố định, IP phía sau tự đổi, chỉ cần http.ProxyURL với cổng đó. Không cần tự xoay trong mã. Bài proxy pool là gì bàn về cách chia proxy cho từng loại công việc.
Xử lý lỗi và thử lại với Golang proxy
Proxy có thể chết, chậm hoặc bị website chặn. Mã cần xử lý lỗi rõ ràng để không dừng cả chương trình vì một proxy hỏng.
Đặt timeout đầy đủ
Client.Timeout giới hạn tổng thời gian một yêu cầu. Transport còn có TLSHandshakeTimeout, ResponseHeaderTimeout. Không đặt timeout là lỗi phổ biến khiến goroutine treo vô thời hạn khi proxy không phản hồi.
Thử lại với proxy khác
func getWithRetry(clients []*http.Client, target string, tries int) (*http.Response, error) {
var lastErr error
for i := 0; i < tries; i++ {
c := clients[i%len(clients)]
resp, err := c.Get(target)
if err == nil && resp.StatusCode < 500 && resp.StatusCode != 429 {
return resp, nil
}
if resp != nil {
resp.Body.Close()
}
lastErr = err
time.Sleep(time.Duration(i+1) * time.Second)
}
return nil, lastErr
}
Mã dừng ở yêu cầu thành công đầu tiên, nghỉ tăng dần giữa các lần thử. Mã 429 cho biết website đang giới hạn, cần chậm lại thay vì thử dồn dập. Bài mua proxy bị lỗi 429 phân tích ngưỡng request.
Loại proxy hỏng khỏi danh sách
Ghi nhận số lỗi liên tiếp của từng proxy. Vượt ngưỡng thì tạm loại proxy đó, kiểm tra lại sau. Cơ chế chuyển proxy tự động được bàn trong bài proxy failover.
Kiểm soát tốc độ khi dùng Golang proxy
Go dễ chạy hàng nghìn goroutine song song. Không kiểm soát, chương trình có thể gửi quá nhiều yêu cầu, làm proxy quá tải và website chặn.
Giới hạn số yêu cầu đồng thời
Dùng kênh có bộ đệm làm semaphore:
sem := make(chan struct{}, 10)
for _, u := range targets {
sem <- struct{}{}
go func(u string) {
defer func() { <-sem }()
resp, err := client.Get(u)
if err == nil {
resp.Body.Close()
}
}(u)
}
Tối đa 10 yêu cầu chạy cùng lúc. Điều chỉnh con số theo số proxy và giới hạn của website.
Giới hạn số yêu cầu mỗi giây
Gói golang.org/x/time/rate cung cấp bộ giới hạn tốc độ kiểu token bucket. Gọi limiter.Wait(ctx) trước mỗi yêu cầu để không vượt mức đã đặt. Kết hợp giới hạn đồng thời và giới hạn tốc độ giúp lưu lượng đều đặn. Bài 1 proxy chạy được bao nhiêu luồng giúp chọn số luồng cho mỗi proxy.
Kiểm tra Golang proxy hoạt động đúng
Kiểm tra IP chương trình Go đang dùng
Gọi một dịch vụ trả về IP như api.ipify.org. Nếu IP trả về là IP proxy, cấu hình đúng. Nếu là IP thật, proxy chưa được dùng, thường do Transport tuỳ chỉnh quên đặt trường Proxy.
Kiểm tra bằng curl để so sánh
curl -x http://user01:matkhau01@103.x.x.11:8080 https://api.ipify.org
Nếu curl chạy mà Go lỗi, vấn đề nằm ở mã. Nếu cả hai lỗi, vấn đề ở proxy. Bài cURL proxy là gì có thêm cách gỡ lỗi.
Ghi nhật ký proxy đã dùng
Trong hàm Proxy tuỳ chỉnh, ghi lại proxy chọn cho từng yêu cầu khi đang gỡ lỗi. Nhật ký giúp biết proxy nào hay lỗi.
Bảng tra nhanh lỗi Golang proxy
Lỗi |
Nguyên nhân khả dĩ |
Cách xử lý |
|---|---|---|
proxyconnect tcp: connection refused |
Sai địa chỉ, cổng hoặc proxy chết |
Kiểm tra proxy bằng curl |
Proxy Authentication Required (407) |
Sai tài khoản, ký tự đặc biệt |
Dùng url.UserPassword |
socks connect: general failure |
Proxy SOCKS5 không tới được website |
Đổi proxy, kiểm tra website |
context deadline exceeded |
Proxy chậm hoặc không phản hồi |
Tăng timeout hợp lý, đổi proxy |
IP trả về vẫn là IP thật |
Transport không đặt Proxy |
Gán Proxy cho Transport tuỳ chỉnh |
Localhost không đi qua proxy |
ProxyFromEnvironment bỏ qua localhost |
Dùng http.ProxyURL khi kiểm thử |
Phân biệt Golang proxy với GOPROXY

GOPROXY khác proxy mạng
GOPROXY là gì
GOPROXY là biến môi trường của công cụ go, quyết định nơi tải module. Theo tài liệu Go Modules Reference, giá trị mặc định trỏ tới proxy.golang.org rồi tới direct. Công ty có thể dựng proxy module riêng như Athens hay Nexus để lưu đệm và kiểm soát module.
Khi máy sau proxy mạng
Nếu máy lập trình nằm sau proxy công ty, lệnh go get cần HTTP_PROXY, HTTPS_PROXY để ra Internet, đồng thời GOPROXY để biết tải module từ đâu. Hai biến làm hai việc khác nhau. Đặt GOPROXY không giúp vượt qua proxy công ty, và ngược lại.
Ví dụ cấu hình cho máy sau proxy công ty
go env -w GOPROXY=https://proxy.golang.org,direct
go env -w GONOSUMDB=git.congty.vn
go env -w GOPRIVATE=git.congty.vn
$env:HTTPS_PROXY = "http://proxy.congty.vn:8080"
go mod download
GOPRIVATE khai báo module nội bộ không đi qua proxy module công khai. HTTPS_PROXY đưa kết nối ra Internet qua proxy công ty.
Chọn proxy cho chương trình Go
Chương trình Go thu thập dữ liệu công khai
Dùng proxy dân cư xoay hoặc danh sách proxy dân cư tĩnh, kết hợp giới hạn tốc độ. Với website Việt Nam, IP Việt Nam theo nhà mạng cho kết quả gần người dùng thật.
Gọi API theo khu vực
Dùng proxy datacenter tốc độ cao nếu API không chặn IP datacenter. Ổn định và chi phí thấp.
Dịch vụ nội bộ cần IP cố định
Một số đối tác chỉ cho phép IP cố định gọi API. Proxy tĩnh riêng giúp chương trình Go chạy ở bất kỳ đâu vẫn ra Internet bằng một IP đã đăng ký. Anh em có thể mua proxy tĩnh tại ProxyVN với cả HTTP và SOCKS5.
Cơ chế CONNECT khi Golang proxy làm việc với HTTPS
Hiểu cách Go đi qua proxy HTTP khi gọi website HTTPS giúp anh em đọc lỗi chính xác hơn. Quá trình gồm ba bước, mỗi bước có thể hỏng theo kiểu riêng.
Bước 1: Kết nối tới proxy
Transport mở kết nối TCP tới địa chỉ proxy. Nếu sai địa chỉ, sai cổng hoặc tường lửa chặn, lỗi xuất hiện ngay với tiền tố proxyconnect. Đây là lỗi dễ nhận biết nhất, thường do gõ sai hoặc proxy đã chết.
Bước 2: Gửi lệnh CONNECT
Transport gửi lệnh CONNECT kèm tên miền và cổng của website, cộng header Proxy-Authorization nếu URL proxy có tài khoản. Proxy trả 200 nếu đồng ý dựng đường hầm, 407 nếu sai xác thực, 403 nếu proxy không cho phép tên miền đó. Cơ chế CONNECT được mô tả trong tài liệu proxy và đường hầm của MDN.
Bước 3: Bắt tay TLS với website
Sau khi đường hầm được dựng, Go bắt tay TLS trực tiếp với website qua đường hầm. Proxy chỉ chuyển byte, không đọc được nội dung. Lỗi chứng chỉ ở bước này thường do proxy công ty can thiệp HTTPS. Khi đó cần thêm chứng chỉ của công ty vào kho tin cậy, không nên tắt kiểm tra chứng chỉ bằng InsecureSkipVerify.
Ý nghĩa với việc gỡ lỗi
Lỗi ở bước 1 là vấn đề kết nối. Lỗi ở bước 2 là vấn đề xác thực hoặc chính sách proxy. Lỗi ở bước 3 là vấn đề chứng chỉ. Đọc kỹ thông báo lỗi để biết bước nào hỏng, thay vì đổi proxy ngay. Bài proxy tunnel là gì giải thích thêm về đường hầm.
Golang proxy trong crawler Colly
Colly là thư viện thu thập dữ liệu phổ biến trong cộng đồng Go. Colly có sẵn cơ chế xoay proxy, giúp anh em không phải tự viết hàm Proxy.
Xoay proxy vòng tròn với Colly
Gói proxy của Colly có hàm RoundRobinProxySwitcher nhận danh sách địa chỉ proxy và trả về hàm chọn proxy. Gán hàm này cho collector bằng SetProxyFunc. Mỗi yêu cầu sẽ lần lượt dùng proxy kế tiếp. Danh sách có thể trộn proxy HTTP và SOCKS5.
c := colly.NewCollector(colly.Async(true))
rp, err := proxy.RoundRobinProxySwitcher(
"http://user01:matkhau01@103.x.x.11:8080",
"socks5://user02:matkhau02@103.x.x.12:1080",
)
if err != nil {
panic(err)
}
c.SetProxyFunc(rp)
c.Limit(&colly.LimitRule{DomainGlob: "*", Parallelism: 4, RandomDelay: 2 * time.Second})
Đây là ví dụ triển khai chung theo cách dùng phổ biến của Colly, anh em đối chiếu với tài liệu phiên bản đang cài.
Giới hạn tốc độ trong Colly
LimitRule cho phép đặt số yêu cầu song song và độ trễ ngẫu nhiên theo tên miền. Đây là cách đơn giản để crawler không gửi quá nhanh. Kết hợp với xoay proxy, mỗi IP gửi ít yêu cầu hơn và khoảng cách giữa các yêu cầu tự nhiên hơn.
Theo dõi proxy nào đang dùng
Trong hàm OnResponse, có thể đọc thông tin yêu cầu để ghi lại proxy đã dùng. Thống kê tỉ lệ lỗi theo proxy giúp phát hiện proxy kém. Bài proxy success rate hướng dẫn cách đo và cải thiện tỉ lệ thành công.
Golang proxy trong Docker và môi trường máy chủ
Chương trình Go thường được đóng gói thành container và chạy trên máy chủ. Cấu hình proxy trong môi trường này cần thống nhất để tránh lỗi khi triển khai.
Truyền biến môi trường vào container
Nếu chương trình dùng ProxyFromEnvironment, truyền HTTP_PROXY, HTTPS_PROXY, NO_PROXY khi chạy container bằng tham số -e hoặc tệp cấu hình. Không ghi mật khẩu proxy vào Dockerfile vì nó sẽ nằm trong lớp ảnh. Dùng cơ chế quản lý bí mật của nền tảng triển khai.
NO_PROXY cho dịch vụ nội bộ của ứng dụng Go
Trong cụm máy chủ, chương trình thường gọi dịch vụ nội bộ như cơ sở dữ liệu, bộ nhớ đệm, dịch vụ khác qua tên nội bộ. Các tên này phải nằm trong NO_PROXY, nếu không yêu cầu nội bộ sẽ bị đẩy ra proxy và thất bại. Đây là lỗi rất phổ biến khi chuyển từ máy cá nhân lên máy chủ.
Chứng chỉ trong ảnh tối giản
Ảnh container tối giản như scratch hay distroless có thể thiếu kho chứng chỉ. Khi gọi HTTPS qua proxy, Go cần chứng chỉ gốc để kiểm tra website. Sao chép tệp chứng chỉ vào ảnh hoặc dùng ảnh nền có sẵn chứng chỉ. Cấu hình proxy cho Docker daemon có trong bài proxy Docker.
Viết kiểm thử cho mã dùng Golang proxy
Mã có xoay proxy, thử lại, giới hạn tốc độ cần được kiểm thử. Go có gói net/http/httptest giúp dựng máy chủ giả trong kiểm thử.
Dựng máy chủ đích giả
Dùng httptest.NewServer tạo một máy chủ trả về nội dung cố định. Chương trình gọi máy chủ này thay vì website thật. Kiểm thử chạy nhanh, không phụ thuộc mạng.
Dựng proxy giả
Có thể dựng một máy chủ đóng vai proxy, ghi lại yêu cầu nhận được. Kiểm thử xác nhận chương trình thật sự gửi qua proxy, gửi đúng header xác thực, xoay đúng thứ tự. Lưu ý ProxyFromEnvironment bỏ qua localhost, nên trong kiểm thử dùng http.ProxyURL trỏ tới proxy giả.
Kiểm thử tình huống lỗi
Cho proxy giả trả 407, 429, 503 hoặc đóng kết nối giữa chừng. Kiểm tra mã thử lại đúng số lần, nghỉ đúng khoảng, loại proxy hỏng đúng ngưỡng. Kiểm thử tình huống lỗi giúp chương trình bền hơn khi chạy thật với proxy không ổn định.
Bảo mật khi dùng Golang proxy
Không ghi mật khẩu proxy vào mã nguồn
Đọc thông tin proxy từ biến môi trường hoặc tệp cấu hình không đưa lên kho mã. Khi in URL proxy ra nhật ký, che phần mật khẩu. Hàm Redacted của url.URL giúp in URL với mật khẩu đã được thay bằng ký tự che.
Không bật InsecureSkipVerify
InsecureSkipVerify bằng true trong cấu hình TLS làm chương trình chấp nhận mọi chứng chỉ, kể cả của kẻ tấn công trung gian. Chỉ dùng tạm khi gỡ lỗi trong môi trường cô lập, không bao giờ để trong mã chạy thật.
Chọn nhà cung cấp proxy rõ ràng
Proxy miễn phí có thể ghi lại yêu cầu, kể cả token API gửi trong header. Với dịch vụ quan trọng, dùng proxy từ nhà cung cấp có hỗ trợ và cam kết rõ ràng.
Đo hiệu năng Golang proxy
Trước khi đưa danh sách proxy vào chương trình chạy thật, đo hiệu năng giúp loại proxy chậm và chọn số luồng phù hợp. Go có sẵn công cụ để làm việc này mà không cần thư viện ngoài.
Đo thời gian từng giai đoạn
Gói net/http/httptrace cho phép gắn các hàm theo dõi vào yêu cầu: thời điểm bắt đầu kết nối, kết nối xong, bắt tay TLS xong, nhận byte đầu tiên. Ghi lại các mốc này cho từng proxy, anh em biết proxy chậm ở khâu nào. Proxy chậm ở khâu kết nối thường do ở xa. Proxy chậm ở khâu nhận byte đầu tiên có thể do quá tải hoặc website đích chậm.
Chạy thử nhiều lần
Một lần đo không đủ tin cậy. Gửi vài chục yêu cầu qua mỗi proxy, tính trung vị và phân vị 95 của thời gian phản hồi. Proxy có trung vị tốt nhưng phân vị 95 rất cao là proxy chập chờn, dễ gây lỗi hết thời gian chờ.
So sánh hiệu năng Go với kết nối trực tiếp
Đo cùng website khi không dùng proxy để có mốc so sánh. Chênh lệch là phần do proxy gây ra. Bài benchmark proxy hướng dẫn quy trình đo tốc độ và độ ổn định chi tiết, còn bài test ping khi mua proxy giúp kiểm tra nhanh độ trễ.
Chọn số luồng sau khi đo
Từ kết quả đo, chọn số yêu cầu đồng thời sao cho thời gian phản hồi không tăng vọt. Tăng dần số luồng, theo dõi tỉ lệ lỗi. Khi lỗi bắt đầu tăng, giảm về mức trước đó. Con số phù hợp khác nhau giữa các website và các loại proxy.
Quy trình đưa Golang proxy vào dự án thật
Gom các phần ở trên thành một quy trình giúp đội phát triển đưa proxy vào dự án Go một cách có kiểm soát.
Bước 1: Đóng gói cấu hình proxy
Tạo một gói nội bộ chịu trách nhiệm dựng http.Client có proxy. Gói đọc cấu hình từ biến môi trường hoặc tệp, kiểm tra hợp lệ, trả về client dùng chung. Các phần khác của dự án chỉ gọi gói này, không tự dựng Transport riêng. Cách làm này giúp đổi proxy ở một chỗ.
Bước 2: Ghi nhật ký có che mật khẩu
Gói ghi nhật ký proxy đang dùng ở mức gỡ lỗi, che mật khẩu bằng hàm Redacted. Khi có sự cố, nhật ký cho biết proxy nào, lúc nào, lỗi gì.
Bước 3: Kiểm thử với proxy giả
Viết kiểm thử với httptest cho các tình huống thành công, 407, 429, hết thời gian chờ. Chạy kiểm thử trong quy trình tích hợp liên tục để mỗi thay đổi đều được kiểm tra.
Bước 4: Theo dõi khi chạy thật
Đo tỉ lệ lỗi, thời gian phản hồi theo từng proxy. Đặt cảnh báo khi tỉ lệ lỗi vượt ngưỡng. Thay proxy kém trước khi ảnh hưởng tới dữ liệu.
Bước 5: Rà soát định kỳ
Mỗi tháng rà soát danh sách proxy, hạn sử dụng, chi phí và hiệu năng. Loại proxy không còn cần thiết, gia hạn proxy đang tốt. Bài dấu hiệu cần thay proxy liệt kê các cảnh báo cần chú ý.
Câu hỏi thường gặp về Golang proxy
Có cần thư viện ngoài để dùng proxy trong Go không
Không với HTTP và SOCKS5 qua http.ProxyURL. Chỉ cần golang.org/x/net/proxy khi muốn dùng Dialer SOCKS5 cho kết nối không phải HTTP.
Proxy có hỗ trợ HTTP/2 không
Khi dùng proxy HTTP với website HTTPS, Go dựng đường hầm CONNECT rồi bắt tay TLS với website, HTTP/2 vẫn có thể được thương lượng. Hành vi cụ thể phụ thuộc phiên bản Go và cấu hình Transport.
Làm sao dùng proxy khác nhau cho từng tên miền
Viết hàm Proxy kiểm tra req.URL.Host rồi trả về proxy tương ứng. Ví dụ tên miền nội bộ trả nil để đi thẳng, tên miền bên ngoài trả proxy.
Golang proxy có hỗ trợ tệp PAC không
Thư viện chuẩn không đọc tệp PAC. Nếu môi trường công ty dùng PAC, cách đơn giản là hỏi bộ phận IT địa chỉ proxy thật cho các tên miền cần gọi, rồi cấu hình trực tiếp.
Xem thêm:
Tổng kết
Golang proxy xoay quanh trường Proxy của http.Transport: dùng biến môi trường, http.ProxyURL cho HTTP, SOCKS5, hoặc hàm tuỳ chỉnh để xoay. Đặt timeout, giới hạn tốc độ và đừng nhầm với GOPROXY. Cần proxy ổn định cho chương trình Go, liên hệ Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam để cấu hình Golang proxy.