cloud Native Go - modrpc/info GitHub Wiki

Table of Contents

Overview

Delivering Continously

Docker and Dockerhub

[cjeong@plato ztmp]$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c04b14da8d14: Pull complete 
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

Wercker: CI (Continuous Integration)

Automatically building after every Git commit

Automatically deploying as part of CI pipeline

Building Microservices in Go

REST API

Resource Method Description
matches GET Queries a list of all available matches
mathces POST Creates and starts a new match
matches/{id} GET Queries the details for an individual match
  • Request
{
            "gridsize" : 19,
            "players" : [
            {
                "color" : "white",
                "name" : "bob"
            },
            {
                "color" : "black",
                "name" : "alfred"
            }
            ]
        }
  • Response:Header
          Location: /matches/5a003b78-409e-4452-b456-a6f0dcee05bd
    • Response:Body
{
                "id" : "5a003b78-409e-4452-b456-a6f0dcee05bd",
                "started_at": "2015-08-05T08:40:51.620Z",
                "gridsize" : 19,
                "turn" : 0,
                "players" : [
                    {
                        "color" : "white",
                        "name" : "bob",
                        "score" : 10
                    },
                    {
                        "color" : "black",
                        "name" : "alfred",
                        "score" : 22
                    }
                ]

            }

HTTP handler

func createMatchHandler(formatter *render.Render, repo matchRepository)
     http.HandlerFunc {
        return func(w http.ResponseWriter, req *http.Request) {
          payload, _ := ioutil.ReadAll(req.Body)
          var newMatchRequest newMatchRequest
          err := json.Unmarshal(payload, &newMatchRequest)
          if err != nil {
            formatter.Text(w, http.StatusBadRequest,
              "Failed to parse create match request")
            return
          }
          if !newMatchRequest.isValid() {
            formatter.Text(w, http.StatusBadRequest,
              "Invalid new match request")
            return
          }

          newMatch := gogo.NewMatch(newMatchRequest.GridSize,
            newMatchRequest.PlayerBlack, newMatchRequest.PlayerWhite)
          repo.addMatch(newMatch)
          w.Header().Add("Location", "/matches/"+newMatch.ID)
          formatter.JSON(w, http.StatusCreated,
            &newMatchResponse{ID: newMatch.ID,
                       GridSize: newMatch.GridSize,
                        PlayerBlack: newMatchRequest.PlayerBlack,
                       PlayerWhite: newMatchRequest.PlayerWhite})
        }
}

Using Backing Services

Designing service ecosystem

  • There are a group of service providers. A single workflow involves a subset of service providers through some call chains.

Late binding of service provider

  • Let host A uses service foo of host B
    • Hard coding of "B" in A's code is not good
    • We need to make it customizable
  • Example: Cloud Foundry-based method
 $ cf create-user-provided-service backing-fulfill -p <URL>
 $ cf push -o cloudnativego/backing-catalog

 # bind a service named backing-fulfill to an application named backing-catalog
 $ cf bind-service backing-catalog backing-fulfill

Service discovery

  • Service request can be sent to a "node" or to a "broker" (how to implement service discovery)
  • Example service registry server: Netflix's Eureka (Java-based)
docker run -p 8080:8080 netflixoss/eureka:1.3.1
import (
        "fmt"
        "github.com/hudl/fargo"
)

func main() {
  // For a real app, you'd bind a user-provided service with eureka
  // credentials and URL.
  c := fargo.NewConn("http://192.168.99.100:8080/eureka/v2")
  i := fargo.Instance{
        HostName:         "i-6543",
        Port:             9090,
        App:              "TESTAPP",
        IPAddr:           "127.0.0.10",
        VipAddress:       "127.0.0.10",
        SecureVipAddress: "127.0.0.10",
        DataCenterInfo:   fargo.DataCenterInfo{Name: fargo.MyOwn},
        Status:           fargo.UP,
  }
  c.RegisterInstance(&i)
  f, _ := c.GetApps()
  for key, theApp := range f {
        fmt.Println("App:", key, " First Host Name:", theApp.Instances[0].HostName)
  }
  app, _ := c.GetApp("TESTAPP")
  fmt.Printf("%v\n", app)
}

Creating a Data Service

Creating a repository in MongoDB

Updating Go service to use new repository

Event Sourcing and CQRS

ES (Event sourcing)

  • A node is a finite-state machine: S x Q -> S
  • eventual consistency
  • fire and forget

CQRS (Command Query Responsibility Segregation)

Building command handler service

  • RabbitMQ: implements AMQP
    • RabbitMQ uses OTP/Erlang
docker run -d --hostname my-rabbit --name some-rabbit -p 8080:15672-p 4369:4369 -p 5672:5672 rabbitmq:3-management

Building event processor

Building query handler service

Building Web Application with Go

Security in the Cloud

Working with WebSockets

Building Web Views with React

Creating UIs that Scale with Flux

Creating a Full Application -- World of FluxCraft

⚠️ **GitHub.com Fallback** ⚠️