Skip to content
This repository has been archived by the owner on Jul 4, 2024. It is now read-only.

Latest commit

 

History

History
619 lines (463 loc) · 16.9 KB

README.md

File metadata and controls

619 lines (463 loc) · 16.9 KB

Go Micro CLI

Go Micro CLI is the command line interface for developing Go Micro projects.

Getting Started

Download and install Go. Version 1.16 or higher is required.

Installation is done by using the go install command.

go install github.com/go-micro/cli/cmd/go-micro@latest

Let's create a new service using the new command.

go-micro new service helloworld

Follow the on-screen instructions. Next, we can run the program.

cd helloworld
make proto tidy
go-micro run

Finally we can call the service.

go-micro call helloworld Helloworld.Call '{"name": "John"}'

That's all you need to know to get started. Refer to the Go Micro documentation for more info on developing services.

Dependencies

You will need protoc for code generation.

You can either install it using your pacakge manager, or manually install it by downloading the protoc zip packages (protoc-$VERSION-$PLATFORM.zip) from https://github.com/protocolbuffers/protobuf/releases/latest and installing its contents.

Creating A Service

To create a new service, use the micro new service command, and provide either a bare service name, or a full GitHub repo module name.

$ go-micro new service github.com/<org>/<repo>/helloworld
...

or

$ go-micro new service helloworld
creating service helloworld

install requirements:

protoc is needed for code generation. You can either install it using your 
pacakge manager, or manually install it by downloading the protoc zip packages 
(protoc-$VERSION-$PLATFORM.zip) from https://github.com/protocolbuffers/protobuf/releases/latest 
and installing its contents.

compile the proto file helloworld-new.proto and install dependencies:

cd helloworld-new
make proto init update tidy

To create a new function, use the micro new function command. Functions differ from services in that they exit after returning.

$ go-micro new function helloworld
creating function helloworld

install requirements:

protoc is needed for code generation. You can either install it using your 
pacakge manager, or manually install it by downloading the protoc zip packages 
(protoc-$VERSION-$PLATFORM.zip) from https://github.com/protocolbuffers/protobuf/releases/latest 
and installing its contents.

compile the proto file test-func.proto and install dependencies:

cd test-func
make init proto update tidy

Jaeger

To create a new service with Jaeger integration, pass the --jaeger flag to the micro new service or micro new function commands. You may configure the Jaeger client using environment variables.

go-micro new service --jaeger helloworld

You may invoke trace.NewSpan(context.Context).Finish() to nest spans. For example, consider the following handler implementing a greeter.

handler/helloworld.go

package helloworld

import (
    "context"

    "go-micro.dev/v4/logger"

    "helloworld/greeter"
    pb "helloworld/proto"
)

type Helloworld struct{}

func (e *Helloworld) Call(ctx context.Context, req pb.CallRequest, rsp *pb.CallResponse) error {
    logger.Infof("Received Helloworld.Call request: %v", req)
    rsp.Msg = greeter.Greet(ctx, req.Name)
    return nil
}

greeter/greeter.go

package greeter

import (
    "context"
    "fmt"

    "go-micro.dev/v4/cmd/micro/debug/trace"
)

func Greet(ctx context.Context, name string) string {
    defer trace.NewSpan(ctx).Finish()
    return fmt.Sprint("Hello " + name)
}

gRPC Server/Client

By default, go-micro uses an JSON/HTTP RPC server. Many microservice use cases require a gRPC server or client, therefore, go-micro offers a gRPC server built in.

To create a new service with a gRPC server pass the --grpc flag to the micro new service or micro new function commands.

go-micro new service --grpc helloworld

Tern - Postgres Migrations

Tern can be used to create and manage Postgres migrations. Go-micro can set the service up to use Tern SQL migrations.

To create a new service with Tern pass the --tern flag to the micro new service or micro new function commands.

To locally run tern migrate it is recommended to create a .env file with connection details as shown below, and manually run source .env, as these environment variables will also be picked up by pgx.

PGHOST=localhost
PGUSER=helloworld
PGDATABASE=helloworld
PGPASSWORD=<empty for localhost>

Setting the --tern flag in combination with any of the Kubernetes flags will also create a InitContainer in the deployment manifest to automatically apply all migrations upon deployment. You will need to create a helloworld-postgres-env secret with a PGPASSWORD to allow tern to connect to your database instance.

The default database address used is postgres.database.svc, and the user and database are set to the service name. To specify a different database address use the --postgresaddress="my.namespace.svc" flag

If you are also using Kustomize to manage your Kubernetes resources, be aware that you will have to manually add every migration to resouces/base/kustomization.yaml. And that you will have to pass the --load-restrictor LoadRestrictionsNone flag to kustomize build, to allow Kustomize to access resources outside of the base folder. Tilt and Skaffold will do this for you automatically.

go-micro new service --tern helloworld

sqlc - SQL Code Generation

Sqlc can compile SQL queries into boilerplate Go code that allows you to easily create and manage your database layer. Go-micro can set your service up for use with sqlc, and used Postgres as a default backend. Sqlc works well in combination with Tern.

Place your SQL queries in postgres/queries/*.sql and run make sqlc to compile. Be sure you have your SQL schema defined in postgres/migrations/*.sql, as can be done with Tern.

After compilation, you can create your database layer in postgres/*.go with the sqlc connector. An example is provided in postgres/postgres.go.

To create a new service with sqlc pass the --sqlc flag to the micro new service or micro new function commands.

go-micro new service --sqlc helloworld

Docker BuildKit

Docker BuildKit is a new container build engine that provides new useful features, such as the ability to cache specific directories across builds. This can prevent Go from having to re-download modules every build.

To create a new service with the BuildKit engine pass the --buildkit flag to the micro new service or micro new function commands.

go-micro new service --buildkit helloworld

Private Git Repository

If you plan on hosting the service in a private Git repository, the docker file needs some tweaks to allow Go to access and clone private repositories.

For this, SSH Git access needs to be set up, and an SSH agent needs to be running, with the Git SSH key added. You can manually start an SSH agent and add the SSH key by running:

$ eval $(ssh-agent) && ssh-add <optional: path to ssh key, default: ~/.shh/id_rsa>

Alternatively, you can use the generated Tiltfile to let Tilt set one up for you.

To create a new service with a private Git repository pass the --privaterepo flag to the micro new service or micro new function commands. This implies the --buildkit flag.

go-micro new service --privaterepo helloworld

Kubernetes

Micro can automatically generate Kubernetes manifests for a service template.

To create a new service with Kubernetes resources pass the --kubernetes flag to the micro new service or micro new function commands.

go-micro new service --kubernetes helloworld

Kustomize - Kubernetes Resource Management

Kustomize can be used to manage more complex Kubernetes manifests for various deployments, such as a development and production environment.

To create a new service with Kubernetes resources organized in a Kustomize structure pass the --kustomize flag to the micro new service or micro new function commands.

go-micro new service --kustomize helloworld

gRPC Health Protocol - Kubernetes Probes

Since Kubernetes 1.24, probes can make use of the gRPC Health Protocol. This allows you to directly probe the go-micro service in a Kubernetes container if it implements the health protocol.

By passing the --health flag the gRPC protocol will be implemented, and if Kubernetes manifests are generated through any of the flags, it will add probes to the deployment manifest.

To use this feature, the GRPCContainerProbe feature gate needs to be enabled inside your cluster. In version 1.24 this is enabled by default, in version 1.23 you need to manually enable the feature gate.

To create a new service with the gRPC health protocol implemented, pass the --health flag to the micro new service or micro new function commands. This implies the --grpc flag.

go-micro new service --health helloworld

Kubernetes Options

Namespace

Kubernetes manifests and Kustomize files set an explicit namespace by default. The default Kubernetes namespace is default. You can manually specify a different namespace during service creation.

go-micro new service --kustomize --namespace=custom helloworld

Postgres Address

If you create the service with the --tern flag, the default Postgres address used is postgres.database.svc. To specify a different address use the --postgresaddress flag

go-micro new service --kustomize --tern --postgresaddress="my.namespace.svc" helloworld

Tilt - Kubernetes Deployment

Tilt can be used to set up a local Kubernetes deployment pipeline.

To create a new service with a Tiltfile file, pass the --tilt flag to the micro new service or micro new function commands.

This implies the --kubernetes flag.

go-micro new service --tilt helloworld

Skaffold - Kubernetes Deployment

Skaffold can be used to locally deploy a service.

To create a new service with Skaffold files, pass the --skaffold flag to the micro new service or micro new function commands.

This implies the --kubernetes flag.

go-micro new service --skaffold helloworld

Advanced

Some patterns will often occur in more complex services. Such as the need to gracefully shutdown go routines, and pass down a context to provide the cancelation
signal.

To prevent you from having to rewrite them for every service, you can pass the --advanced flag. This will generate a waitgroup, context, and define functions for BeforeStart, BeforeStop and AfterStop.

go-micro new service --advanced helloworld

Complete

With so many possible flags to create a service, the --complete flag will set the following flags to true:

go-micro new service --jaeger --health --grpc --sqlc --tern --buildkit --kustomize --tilt --advanced

Running A Service

To run a service, use the micro run command to build and run your service continuously.

$ go-micro run
2021-08-20 14:05:54  [email protected]/service.go:199 level=info Starting [service] helloworld
2021-08-20 14:05:54  file=server/rpc_server.go:820 level=info Transport [http] Listening on [::]:34531
2021-08-20 14:05:54  file=server/rpc_server.go:840 level=info Broker [http] Connected to 127.0.0.1:44975
2021-08-20 14:05:54  file=server/rpc_server.go:654 level=info Registry [mdns] Registering node: helloworld-45f43a6f-5fc0-4b0d-af73-e4a10c36ef54

With Docker

To run a service with Docker, build the Docker image and run the Docker container.

$ make docker
$ docker run helloworld:latest
2021-08-20 12:07:31  [email protected]/service.go:199 level=info Starting [service] helloworld
2021-08-20 12:07:31  file=server/rpc_server.go:820 level=info Transport [http] Listening on [::]:36037
2021-08-20 12:07:31  file=server/rpc_server.go:840 level=info Broker [http] Connected to 127.0.0.1:46157
2021-08-20 12:07:31  file=server/rpc_server.go:654 level=info Registry [mdns] Registering node: helloworld-31f58714-72f5-4d12-b2eb-98f66aea7a34

With Skaffold

When you've created your service using the --skaffold flag, you may run the Skaffold pipeline using the skaffold command.

skaffold dev

With Tilt

When you've created your service using the --tilt flag, you may run the Tilt pipeline using the tilt command.

tilt up --stream

If you don't want to stream logs, but do want to exit on errors, you can run

tilt ci

Creating A Client

To create a new client, use the micro new client command. The name is the service you'd like to create a client project for.

$ go-micro new client helloworld
creating client helloworld
cd helloworld-client
make tidy

You may optionally pass the fully qualified package name of the service you'd like to create a client project for.

$ go-micro new client github.com/auditemarlow/helloworld
creating client helloworld
cd helloworld-client
make tidy

Running A Client

To run a client, use the micro run command to build and run your client continuously.

$ go-micro run
2021-09-03 12:52:23  file=helloworld-client/main.go:33 level=info msg:"Hello John"

Generating Files

To generate Go Micro project template files after the fact, use the micro generate command. It will place the generated files in the current working directory.

$ go-micro generate skaffold
skaffold project template files generated

Listing Services

To list services, use the micro services command.

$ go-micro services
helloworld

Describing A Service

To describe a service, use the micro describe service command.

$ go-micro describe service helloworld
{
  "name": "helloworld",
  "version": "latest",
  "metadata": null,
  "endpoints": [
    {
      "name": "Helloworld.Call",
      "request": {
        "name": "CallRequest",
        "type": "CallRequest",
        "values": [
          {
            "name": "name",
            "type": "string",
            "values": null
          }
        ]
      },
      "response": {
        "name": "CallResponse",
        "type": "CallResponse",
        "values": [
          {
            "name": "msg",
            "type": "string",
            "values": null
          }
        ]
      }
    }
  ],
  "nodes": [
    {
      "id": "helloworld-9660f06a-d608-43d9-9f44-e264ff63c554",
      "address": "172.26.165.161:45059",
      "metadata": {
        "broker": "http",
        "protocol": "mucp",
        "registry": "mdns",
        "server": "mucp",
        "transport": "http"
      }
    }
  ]
}

You may pass the --format=yaml flag to output a YAML formatted object.

$ go-micro describe service --format=yaml helloworld
name: helloworld
version: latest
metadata: {}
endpoints:
- name: Helloworld.Call
  request:
    name: CallRequest
    type: CallRequest
    values:
    - name: name
      type: string
      values: []
  response:
    name: CallResponse
    type: CallResponse
    values:
    - name: msg
      type: string
      values: []
nodes:
- id: helloworld-9660f06a-d608-43d9-9f44-e264ff63c554
  address: 172.26.165.161:45059
  metadata:
    broker: http
    protocol: mucp
    registry: mdns
    server: mucp
    transport: http

Calling A Service

To call a service, use the micro call command. This will send a single request and expect a single response.

$ go-micro call helloworld Helloworld.Call '{"name": "John"}'
{"msg":"Hello John"}

To call a service's server stream, use the micro stream server command. This will send a single request and expect a stream of responses.

$ go-micro stream server helloworld Helloworld.ServerStream '{"count": 10}'
{"count":0}
{"count":1}
{"count":2}
{"count":3}
{"count":4}
{"count":5}
{"count":6}
{"count":7}
{"count":8}
{"count":9}

To call a service's bidirectional stream, use the micro stream bidi command. This will send a stream of requests and expect a stream of responses.

$ go-micro stream bidi helloworld Helloworld.BidiStream '{"stroke": 1}' '{"stroke": 2}' '{"stroke": 3}'
{"stroke":1}
{"stroke":2}
{"stroke":3}