Пример #1
0
func new(c *C, p string) (*roundrobin.RoundRobin, *Streamer) {
	logger := utils.NewFileLogger(os.Stdout, utils.INFO)
	// forwarder will proxy the request to whatever destination
	fwd, err := forward.New(forward.Logger(logger))
	c.Assert(err, IsNil)

	// load balancer will round robin request
	lb, err := roundrobin.New(fwd)
	c.Assert(err, IsNil)

	// stream handler will forward requests to redirect, make sure it uses files
	st, err := New(lb, Logger(logger), Retry(p), MemRequestBodyBytes(1))
	c.Assert(err, IsNil)

	return lb, st
}
Пример #2
0
func (f *frontend) rebuild() error {
	settings := f.frontend.HTTPSettings()

	// set up forwarder
	fwd, err := forward.New(
		forward.Logger(f.log),
		forward.RoundTripper(f.backend.transport),
		forward.Rewriter(
			&forward.HeaderRewriter{
				Hostname:           settings.Hostname,
				TrustForwardHeader: settings.TrustForwardHeader,
			}),
		forward.PassHostHeader(settings.PassHostHeader))

	// rtwatcher will be observing and aggregating metrics
	watcher, err := NewWatcher(fwd)
	if err != nil {
		return err
	}

	// Create a load balancer
	rr, err := roundrobin.New(watcher)
	if err != nil {
		return err
	}

	// Rebalancer will readjust load balancer weights based on error ratios
	rb, err := roundrobin.NewRebalancer(rr, roundrobin.RebalancerLogger(f.log))
	if err != nil {
		return err
	}

	// create middlewares sorted by priority and chain them
	middlewares := f.sortedMiddlewares()
	handlers := make([]http.Handler, len(middlewares))
	for i, m := range middlewares {
		var prev http.Handler
		if i == 0 {
			prev = rb
		} else {
			prev = handlers[i-1]
		}
		h, err := m.Middleware.NewHandler(prev)
		if err != nil {
			return err
		}
		handlers[i] = h
	}

	var next http.Handler
	if len(handlers) != 0 {
		next = handlers[len(handlers)-1]
	} else {
		next = rb
	}

	// stream will retry and replay requests, fix encodings
	if settings.FailoverPredicate == "" {
		settings.FailoverPredicate = `IsNetworkError() && RequestMethod() == "GET" && Attempts() < 2`
	}
	str, err := stream.New(next,
		stream.Logger(f.log),
		stream.Retry(settings.FailoverPredicate),
		stream.MaxRequestBodyBytes(settings.Limits.MaxBodyBytes),
		stream.MemRequestBodyBytes(settings.Limits.MaxMemBodyBytes))
	if err != nil {
		return err
	}

	if err := syncServers(f.mux, rb, f.backend, watcher); err != nil {
		return err
	}

	// Add the frontend to the router
	if err := f.mux.router.Handle(f.frontend.Route, str); err != nil {
		return err
	}

	f.lb = rb
	f.handler = str
	f.watcher = watcher
	return nil
}