165 lines
4.8 KiB
Markdown
165 lines
4.8 KiB
Markdown
# Turbine
|
|
|
|
A modular service framework.
|
|
|
|
## Launchpad (Process Manager)
|
|
|
|
The `launchpad` is a CLI tool located in `pkg/launchpad` designed to simplify development and production workflows for the entire Turbine project. It acts as a process manager that can run all defined services concurrently for development and generate a `docker-compose.yml` file for production deployments.
|
|
|
|
### Configuration
|
|
|
|
The launchpad is configured via a `launchpad.toml` file in the project root. This file defines all the services, including how to run them in development and how to build them for production.
|
|
|
|
**`launchpad.toml` example:**
|
|
```toml
|
|
[[services]]
|
|
name = "gateway"
|
|
type = "go"
|
|
path = "./pkg/gateway"
|
|
[services.dev]
|
|
command = "go run ./main.go"
|
|
[services.prod]
|
|
dockerfile = "./pkg/gateway/Dockerfile"
|
|
image = "turbine/gateway:latest"
|
|
ports = ["8080:8080"]
|
|
|
|
[[services]]
|
|
name = "orders-api"
|
|
type = "dotnet"
|
|
path = "../turbine-dotnet-services/orders-api"
|
|
[services.dev]
|
|
command = "dotnet watch run"
|
|
[services.prod]
|
|
dockerfile = "../turbine-dotnet-services/orders-api/Dockerfile"
|
|
image = "turbine/orders-api:latest"
|
|
```
|
|
|
|
### Commands
|
|
|
|
To use the launchpad, run its `main.go` file with one of the following commands:
|
|
|
|
#### Development (`dev`)
|
|
Starts all services defined in `launchpad.toml` in development mode. Each service runs in a separate process, and their logs are streamed to the console with colored prefixes. A single `Ctrl+C` will gracefully shut down all services.
|
|
|
|
```bash
|
|
go run ./pkg/launchpad/main.go dev
|
|
```
|
|
|
|
#### Production Docker Compose Generation (`prod-gen`)
|
|
Generates a `docker-compose.yml` file in the project root based on the `prod` configuration of all services in `launchpad.toml`. This file can be used to build and run all services as Docker containers.
|
|
|
|
```bash
|
|
go run ./pkg/launchpad/main.go prod-gen
|
|
```
|
|
|
|
## Registrar
|
|
|
|
The Registrar is the service discovery system of the DysonNetwork.
|
|
Here are a port to the Golang in order to support other Golang services.
|
|
|
|
To use the system, try build with these API:
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"yourmodule/registry"
|
|
)
|
|
|
|
func main() {
|
|
endpoints := []string{"localhost:2379"}
|
|
|
|
registrar, err := registry.NewServiceRegistrar(endpoints)
|
|
if err != nil {
|
|
log.Fatalf("Error creating registrar: %v", err)
|
|
}
|
|
|
|
serviceName := "orders"
|
|
host := "10.0.0.5"
|
|
port := 5000
|
|
ttl := int64(30)
|
|
|
|
err = registrar.Register(serviceName, "http", "instance-1", host, port, ttl)
|
|
if err != nil {
|
|
log.Fatalf("Register error: %v", err)
|
|
}
|
|
log.Println("Service registered")
|
|
|
|
// Wait for termination
|
|
stop := make(chan os.Signal, 1)
|
|
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
|
|
<-stop
|
|
|
|
err = registrar.Deregister()
|
|
if err != nil {
|
|
log.Printf("Deregister error: %v", err)
|
|
} else {
|
|
log.Println("Service deregistered")
|
|
}
|
|
}
|
|
```
|
|
|
|
## Gateway
|
|
|
|
The gateway is the entry point for all requests. It uses the `registrar` to discover services in real-time from etcd and forwards requests to the appropriate service instances.
|
|
|
|
### Features
|
|
- **Service Discovery**: Automatically discovers `http` services from etcd.
|
|
- **Dynamic Routing**: Maintains an in-memory routing table that is automatically updated when services are added or removed.
|
|
- **Request Proxying**: Forwards incoming requests to the correct service instance based on the URL path (`/<service-name>/...`).
|
|
- **Load Balancing**: Implements round-robin load balancing across service instances.
|
|
- **Route Overrides**: Allows for custom routing rules to be defined in the configuration file.
|
|
|
|
### Configuration
|
|
|
|
The gateway is configured via a `settings.toml` file located in the same directory.
|
|
|
|
```toml
|
|
# The address the gateway will listen on
|
|
listen = ":8080"
|
|
|
|
# ETCD configuration for service discovery
|
|
[etcd]
|
|
endpoints = ["127.0.0.1:2379"]
|
|
# Set to true if your etcd server does not use TLS
|
|
insecure = true
|
|
|
|
# Custom route overrides
|
|
# The key is the incoming path prefix.
|
|
# The value is the destination in the format "/<service_name>/<path_prefix>"
|
|
[routes]
|
|
"/websocket" = "/chatter/ws"
|
|
```
|
|
|
|
## Config Service
|
|
|
|
The config service provides a centralized location for other services to fetch their configuration. This is useful for managing connection strings, feature flags, and other shared parameters without hardcoding them into each service.
|
|
|
|
### Usage
|
|
The config service reads a `shared_config.toml` file from its own directory (`pkg/config`) and serves it as a JSON object over a simple HTTP endpoint.
|
|
|
|
To retrieve the configuration, other services can make a GET request to the gateway at `/config`. The gateway will route the request to an available instance of the config service.
|
|
|
|
**Example with curl:**
|
|
```bash
|
|
curl http://localhost:8080/config
|
|
```
|
|
|
|
**Expected Response (JSON):**
|
|
```json
|
|
{
|
|
"database": {
|
|
"connection_string": "postgres://user:password@db-host:5432/mydatabase?sslmode=require"
|
|
},
|
|
"redis": {
|
|
"address": "redis-host:6379"
|
|
}
|
|
}
|
|
```
|
|
|