In a service oriented architecture, an existing challenge is to manage running binaries, dependencies and networking. Orchestra's goal is to provide a unique place where you can run, stop, aggregate logs and config your Go binaries.
- Standalone: The first requirement is to provide support as a standalone tool, without external dependencies (apart from docker when using vendors). An optional flag will be provided to run the Go binaries inside a docker container.
- Rerun: Reload (build, test and run) services upon modification
- Vendors: Specify dependecies with existing services. Vendor software (e.g. postgres, rabbitmq, etc) will run inside Docker. This feature relies on
crane. - Configuration: A global configuration file will be required to specify
ENVvariables for every service. An optional configuration file can be specified - Testing: Run unit tests and acceptance tests.
- Logging: Show aggregated logs for every service in the fleet.
- Reliability: Services started with Orchestra should operate atomically and in a reliable way. When Orchestra starts a service should check for the running processes, and match and kill services running outside this toolkit (e.g. running
go run main.goinside a service folder or the./servicebinary) - Scale: Services should be able to scale, by default the scale level is set to 1. A scale value can be set for every service inside their configuration file.
start- rerun: uses rerun to run the services
- scale: overwrites the defined scale parameter
stoprestartvendorslogsps
- The application will create a
.orchestrafolder in the directory (inside theGOPATH) that we want to orchestrate. The purpose of this directoy is to provide the necessary context when running orchestra again. - The application can be run in every folder inside the
GOPATH, e.g. let's assume that we have a single repo (calledmyservices) with all the services in different folders, you can run orchestra inside that folder and it will recursively (withdepth=1) look in every directory for a configuration file (i.e.service.yml) and register the services. This approach works seamlessly with services split in multiple repositories in one GitHub account. - Logging is extremely important, and with great logging comes great responsibilities. For simplicity we'll redirect the output of a service into a file, then we use
github.com/ActiveState/taillibrary to aggregate the logs of different services, maybe make them colorful and prefix them with the service name. - Code reload of Go binaries can be achieved using
github.com/skelterjohn/rerun. It relies onfsnotifyand it watches for changes in the Go files. It can be possible, before every run, to run the tests again usinggo test. I am considering of forking the project for the sake of better logging. - The application is a pure command-line toolkit, for this reason we may need commands, maybe subcommands and flags. For simplicity I intend to use the well known
github.com/codegangsta/clilibrary. YAMLwill be used as the standard format to store configuration files. In Go, a YAML parser is required,github.com/go-yaml/yamlis my favorite option at the moment to marshal or unmarshal files.- An initialization process may be used to initialize a folder as an orchestra project. This may be a useful step to do some checks before start looking into all subdirectories and start running the binaries.