Tag Archives: Hystrix

Batching (collapsing) requests in Hystrix


Hystrix has an advanced feature of collapsing (or batching) requests. If two or more commands run similar request at the same time, Hystrix can combine them together, run one batched request and dispatch split results back to all commands. Let’s first see how Hystrix works without collapsing. Imagine we have a service that looks upStockPrice of a given Ticker: Read more>>

Netflix’s Hystrix latency and fault tolerance library, for Go


hystrix change Runner interface to allow user-defined methods to use simple r… 8 months ago
scripts simply vagrant provisioning 8 months ago
.gitignore vagrant with go 11 months ago
.travis.yml disable race checker. failing on travis with: 11 months ago
LICENSE Initial commit 11 months ago
README.md change Runner interface to allow user-defined methods to use simple r… 8 months ago
Vagrantfile simply vagrant provisioning 8 months ago

Hystrix is a great project from Netflix.

Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.

I think the Hystrix patterns of programmer-defined fallbacks and adaptive health monitoring are good for any distributed system. Go routines and channels are great concurrency primitives, but don’t directly help our application stay available during failures.

hystrix-go aims to allow Go programmers to easily build applications with similar execution semantics of the Java-based Hystrix library.

For more about how Hystrix works, refer to the Java Hystrix wiki

How to use

import "github.com/afex/hystrix-go/hystrix"

Define your struct with basic settings

type MyCommand struct{}

func (c *MyCommand) PoolName() string {
    return "MyCommand"
}

func (c *MyCommand) Timeout() time.Duration {
    return time.Millisecond * 100
}

Implement Run and Fallback methods

Define your application logic which relies on external systems. When that system is healthy this will be the only thing which executes.

func (c *MyCommand) Run() (interface{}, error) {
    // example: load the friends list from an external service, and return the count
    response, err := http.Get("http://service/friend_list")
    count := // snip: parse response count friends 
    if err != nil {
        return nil, err
    } else {
        return count, nil
    }
}

Define your fallback behavior. Ideally, the logic here will allow your application to gracefully handle theRun() method being unavailable.

This triggers when your Run() method returns an error, or whenever it is unable to complete based on avariety of health checks.

func (c *MyCommand) Fallback(err error) (interface{}, error) {
    // example: when friends service is slow or unavailable, act as though the user has no friends.
    return 0, nil
}

Synchronous execution

Start a command, and wait for it to finish.

command := hystrix.NewCommand(&MyCommand{})
result, err := command.Execute()

Asynchronous execution

Start a command, and receive channels to grab the response or error later.

command := hystrix.NewCommand(&MyCommand{})
results, errors := command.Queue()
select {
case result := <-results:
case err := <-errors:
}

Build and Test

  • Install vagrant and VirtualBox
  • Clone the hystrix-go repository
  • Inside the hystrix-go directory, run vagrant up, then vagrant ssh
  • cd /go/src/github.com/afex/hystrix-go
  • go test ./...