oxy

module
v2.0.0-alpha.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 7, 2021 License: Apache-2.0

README

Oxy

This is a fork of Oxy.

Oxy is a Go library with HTTP handlers that enhance HTTP standard library:

  • Buffer retries and buffers requests and responses
  • Stream passes-through requests, supports chunked encoding with configurable flush interval
  • Forward forwards requests to remote location and rewrites headers
  • Roundrobin is a round-robin load balancer
  • Circuit Breaker Hystrix-style circuit breaker
  • Connlimit Simultaneous connections limiter
  • Ratelimit Rate limiter (based on tokenbucket algo)
  • Trace Structured request and response logger

It is designed to be fully compatible with http standard library, easy to customize and reuse.

Status

  • Initial design is completed
  • Covered by tests

Quickstart

Every handler is http.Handler, so writing and plugging in a middleware is easy. Let us write a simple reverse proxy as an example:

Simple reverse proxy


import (
	"net/http"
	"abstraction.fr/oxy/v2/forward"
	"abstraction.fr/oxy/v2/testutils"
)

// Forwards incoming requests to whatever location URL points to, adds proper forwarding headers
fwd, _ := forward.New()

redirect := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
	// let us forward this request to another server
	req.URL = testutils.ParseURI("http://localhost:63450")
	fwd.ServeHTTP(w, req)
})

// that's it! our reverse proxy is ready!
s := &http.Server{
	Addr:    ":8080",
	Handler: redirect,
}

s.ListenAndServe()

As a next step, let us add a round robin load-balancer:


import (
	"net/http"
	"abstraction.fr/oxy/v2/forward"
	"abstraction.fr/oxy/v2/roundrobin"
)

// Forwards incoming requests to whatever location URL points to, adds proper forwarding headers
fwd, _ := forward.New()
lb, _ := roundrobin.New(fwd)

lb.UpsertServer(url1)
lb.UpsertServer(url2)

s := &http.Server{
	Addr:    ":8080",
	Handler: lb,
}

s.ListenAndServe()

What if we want to handle retries and replay the request in case of errors? buffer handler will help:


import (
	"net/http"
	"abstraction.fr/oxy/v2/forward"
	"abstraction.fr/oxy/v2/buffer"
	"abstraction.fr/oxy/v2/roundrobin"
)

// Forwards incoming requests to whatever location URL points to, adds proper forwarding headers

fwd, _ := forward.New()
lb, _ := roundrobin.New(fwd)

// buffer will read the request body and will replay the request again in case if forward returned status
// corresponding to nework error (e.g. Gateway Timeout)
buffer, _ := buffer.New(lb, buffer.Retry(`IsNetworkError() && Attempts() < 2`))

lb.UpsertServer(url1)
lb.UpsertServer(url2)

// that's it! our reverse proxy is ready!
s := &http.Server{
	Addr:    ":8080",
	Handler: buffer,
}
s.ListenAndServe()

Logging

As of v2, oxy let's you provide your own logger instead of forcing the use of logrus. To do so you have to provide a struct that comply with the minimal interface utils.Logger.

github.com/sirupsen/logrus

import (
	"abstraction.fr/oxy/v2/cbreaker"
	"github.com/sirupsen/logrus"
)

stdLogger := logrus.StandardLogger()
stdLogger.SetLevel(logrus.DebugLevel)

logrusLogger := stdLogger.WithField("lib", "vulcand/oxy")
logrusDebugFunc := func() bool {
	return logrusLogger.Logger.Level >= logrus.DebugLevel
}

cbLogger := cbreaker.Logger(logrusLogger)
cbDebug := cbreaker.Debug(logrusDebugFunc)

cb, err := cbreaker.New(next, "NetworkErrorRatio() > 0.3", cbLogger, cbDebug)

go.uber.org/zap

import (
	"abstraction.fr/oxy/v2/cbreaker"
	"go.uber.org/zap/zap"
	"go.uber.org/zap/zapcore"
)

zapAtomLevel := zap.NewAtomicLevel()
zapAtomLevel.SetLevel(zapcore.DebugLevel)

zapEncoderCfg := zap.NewProductionEncoderConfig()
zapEncoderCfg.EncodeLevel = zapcore.CapitalColorLevelEncoder

zapCore := zapcore.NewCore(zapcore.NewConsoleEncoder(zapEncoderCfg), zapcore.Lock(os.Stdout), zapAtomLevel)
zapLogger := zap.New(zapCore).With(zap.String("lib", "vulcand/oxy"))

zapSugaredLogger := zapLogger.Sugar()
zapDebug := func() bool {
	return zapAtomLevel.Enabled(zapcore.DebugLevel)
}

cbLogger := cbreaker.Logger(zapSugaredLogger)
cbDebug := cbreaker.Debug(zapDebug)

cb, err := cbreaker.New(next, "NetworkErrorRatio() > 0.3", cbLogger, cbDebug)

Directories

Path Synopsis
Package buffer provides http.Handler middleware that solves several problems when dealing with http requests: Reads the entire request and response into buffer, optionally buffering it to disk for large requests.
Package buffer provides http.Handler middleware that solves several problems when dealing with http requests: Reads the entire request and response into buffer, optionally buffering it to disk for large requests.
Package cbreaker implements circuit breaker similar to https://github.com/Netflix/Hystrix/wiki/How-it-Works Vulcan circuit breaker watches the error condtion to match after which it activates the fallback scenario, e.g.
Package cbreaker implements circuit breaker similar to https://github.com/Netflix/Hystrix/wiki/How-it-Works Vulcan circuit breaker watches the error condtion to match after which it activates the fallback scenario, e.g.
Package connlimit provides control over simultaneous connections coming from the same source
Package connlimit provides control over simultaneous connections coming from the same source
Package forward implements http handler that forwards requests to remote server and serves back the response websocket proxying support based on https://github.com/yhat/wsutil
Package forward implements http handler that forwards requests to remote server and serves back the response websocket proxying support based on https://github.com/yhat/wsutil
Package ratelimit Tokenbucket based request rate limiter
Package ratelimit Tokenbucket based request rate limiter
Package roundrobin implements dynamic weighted round robin load balancer http handler
Package roundrobin implements dynamic weighted round robin load balancer http handler
Package stream provides http.Handler middleware that passes-through the entire request Stream works around several limitations caused by buffering implementations, but also introduces certain risks.
Package stream provides http.Handler middleware that passes-through the entire request Stream works around several limitations caused by buffering implementations, but also introduces certain risks.
Package trace implement structured logging of requests
Package trace implement structured logging of requests

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL