Skip to content

exu/go-workshops

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Golang Training Resources

This repository contains files needed for managing Go language workshop - it's some kind of quite complete walk-through of Go language. Feel free to look on the code, there are many comments which could be useful for beginners and semi-intermediate Go developers.

About Go

Who designed Go language?

  • Rob Pike (Unix, UTF-8)
  • Ken Thompson (Unix author, UTF-8, B lang)
  • Robert Griesemer (V8, Java Hotspot (Oracle Java), GFS)

but those above are only ignitors of whole contributions: https://golang.org/AUTHORS

Why go was developed by Google? They have a lot of problems in C/Python/Java codebases:

  • speed up development
  • speed up compiling
  • multicore systems

sources:

Go language characteristics

  • statically compiled (one fat binary with all dependencies)
  • Garbage Collected
  • Strong types
  • Functions as first class citizens
  • Object Oriented (but without inheritance and classes)

Why it's worth of your time?

  • easy deployment (no dependencies, single binary statically linked)
  • no more code style wars - gofmt
  • integrated package downloader go get
  • integrated code validation go vet and golint (github.com/golang/lint)
  • nice playground (https://play.golang.org/)
  • gocode intellisense server - you don't need fat IDE to write go code, you can use now editor which you love (Sublime, Atom, Vim, Emacs, VSCode)
  • very fast compilation - if you're going from JAVA world you'll be really surprised
  • quite complete standard library - template/html, performant www servers, json, xml, streams, io, buffers, first class citizen concurrency
  • easy to use cross-compilation (x64, ARM, 386, Mac, Windows)
  • easy start, bunch of editors, all things simply work
  • http2 in core
  • testing included
  • benchmarking of code included
  • very low entry barrier
  • hype, one of fastest growing language, many new projects are in Go recently
  • concurrency
  • great documentation generator
  • and many many more ...

Workshop prerequisites

You can install golang and docker using your preferred way i.e. your OS package manager (brew, pacman, apt, snap or other) or you can simply follow installation instruction on go and docker sites.

Golang installation

For recent installation instructions please refer to Golang installation guide

You'll need git to be installed

Docker install

Docker is the company driving the container movement and the only container platform provider to address every application across the hybrid cloud. Today’s businesses are under pressure to digitally transform but are constrained by existing applications and infrastructure while rationalizing an increasingly diverse portfolio of clouds, datacenters and application architectures. Docker enables true independence between applications and infrastructure and developers and IT ops to unlock their potential and creates a model for better collaboration and innovation.

For recent docker installation please follow Docker installation guide for your OS.

Docker is needed for some parts of workshops for running databases or other needed dependencies. Also will be needed to complete homework.

Docker Compose Installation

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.

To install docker compose please follow Docker compose installation guide

Init workshops to play on your machine with code

go get github.com/exu/go-workshops
cd $GOPATH/src/github.com/exu/go-workshops

Go Tools

Included

IDEs

Auto reload

  • BRA (Brilliant Ridiculous Assistant) https://github.com/Unknwon/bra - it's good to setup it when you're working on some webservers to auto reload your app when changes in code are made.

Github style - project structure

In go, idiomatic way is to organise code in "github style", so part of the path is looking like server address to library. Of course if you want you don't need to do this, but whole ecosystem works that way.

src/
    github.com
        exu
            mysuperproject
    ioki.com.pl
            mnmel
                 nmelinium
bin/
    superappbinary
pkg/
    compiled packages

Environment variable $GOPATH is responsible for path to the root dir of src, bin and pkg directories.

Packages and Importing

package in go is in form of files with directive package package_name on top of each file. Package by default is imported as full path to package.

import "github.com/exu/go-workshops/010-basics-importing/sub"

Getting and installing external packages

To get external package we need to run go install which will get sources and binaries and put them to src/bin/pkg directories

go install external.package.com/uri/to/package

sub example package

As we can see our sub package is in directory sub (obvious) and have two files; sub1.go and sub2.go each of them also have package sub directive which tells compiler that they are in one package.

(code for: Basics Importing)

Package managers

Currently most advanced in go ecosystem is gomod https://blog.golang.org/using-go-modules

You can init your project:

$ go mod init myapp
$ ls
go.mod go.sum

(code for: Package Management)

Modules

Modules are quite new in Go (begins in 1.11 as experimental feature) in 1.12 they are in auto mode what means that if you are in GOPATH they will be disabled and when you'll be out of GOPATH they will be enabled

In incoming 1.13 version modules will be enabled by default which means that no more github style code organisation will be needed

Commands

  1. Check echo $GO111MODULE first - if value is off or auto you need to set it to on

  2. go mod init initialize modules in project directory

  3. go mod tidy cleans your unused modules

  4. go mod download downloads modules to cache

  5. go mod vendor vendoring modules from cache

  6. go build, go test, go run downloads modules automatically so you don't need to do it

  7. go run -mod vendor using vedored modules

Tools

As in middle 2019 editors have still issues with new modules, you need to install proper gocode or can use gopls (language server) for autocompletition

(code for: Modules)

Variables

In go variables can be declared and assigned in one simple way a := 1, compiler will detect type of variable based on its value.

(code for: Basics Variables)

Constants

Use const to define new constant, mechanics looks like in other languages. What is worth to mention that we have iota keyword which could be used as some kind of iterator in constant definition.

(code for: Basics Constants)

Funkcje

Functions in Go are "First class citizen".

  • function definition
  • multiple returns
  • named multiple returns
  • deferred calls
  • variadic functions

(code for: Basics Functions)

Packages initialisation

func init() {} is responsible for package initialisation, it's called only once when import statement for given package is called.

(code for: Basics Init)

Closures aka anonymous functions

Go supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.

Functions in Go are first class citizens so it can be:

  • passed as parameters
  • created as types
  • assigned as values to variables
  • called anonymously

(code for: Basics Closures)

Data structures: Arrays

In Go, an array is a numbered sequence of elements of a specific length. Arrays are "low level" data structures with slices over them which simplifies creating and managing.

(code for: Basics Arrays)

Slices

Slices are a key data type in Go, giving a more powerful interface to sequences than arrays.

Unlike arrays, slices are typed only by the elements they contain (not the number of elements). To create an empty slice with non-zero length, use the builtin make. Here we make a slice of strings of length 3 (initially zero-valued).

sources:

(code for: Basics Slices)

Loops

In go there is only one loop keyword: for. It's often used with range keyword to iterate over array like elements.

(code for: Basics Loops)

Data structures: Maps

One of the most useful data structures in computer science is the hash table. Many hash table implementations exist with varying properties, but in general they offer fast lookups, adds, and deletes. Go provides a built-in map type that implements a hash table.

(code for: Basics Maps)

Basics Overriding Internal Types

There is no README.md for Basics Overriding Internal Types use (code for: Basics Overriding Internal Types) link to follow code examples

make and new keywords

new(T) allocates zeroed storage for a new item of type T and returns its address. In Go terminology, it returns a pointer to a newly allocated zero value of type T.

make(T) For slices, maps, and channels, make initializes the internal data structure and prepares the value for use.

make

Things you can do with make that you can't do any other way:

  • Create a channel
  • Create a map with space preallocated
  • Create a slice with space preallocated or with len != cap

new

It's a little harder to justify new. The main thing it makes easier is creating pointers to non-composite types. The two functions below are equivalent. One's just a little more concise:

func newInt1() *int { return new(int) }

func newInt2() *int {
    var i int
    return &i
}

Go has multiple ways of memory allocation and value initialization:

&T{...}, &someLocalVar, new, make

Allocation can also happen when creating composite literals.

new can be used to allocate values such as integers, &int is illegal:

new(Point)
&Point{}      // OK
&Point{2, 3}  // Combines allocation and initialization

new(int)
&int          // Illegal

// Works, but it is less convenient to write than new(int)
var i int
&i

In terms of channels there you can use make and new

p := new(chan int)   // p has type: *chan int
c := make(chan int)  // c has type: chan int

(code for: Basics New And Make)

Struktury

A struct is a sequence of named elements, called fields, each of which has a name and a type. Field names may be specified explicitly (IdentifierList) or implicitly (EmbeddedField). Within a struct, non-blank field names must be unique.

(code for: Basics Structs Defining)

Struktury - Kompoozycja

Kompozycja taki pattern chyba znacie ?

(code for: Basics Struct Composition)

Struct tags (annotations like)

A tag for a field allows you to attach meta-information to the field which can be acquired using reflection. Usually it is used to provide transformation info on how a struct field is encoded to or decoded from another format (or stored/retrieved from a database), but you can use it to store whatever meta-info you want to, either intended for another package or for your own use.

(code for: Basics Struct Tags)

Basics Anonymous Structs

There is no README.md for Basics Anonymous Structs use (code for: Basics Anonymous Structs) link to follow code examples

Interface'y

Go have "implicit interfaces". To implement an interface in Go, we just need to implement all the methods in the interface.

So what is an interface? An interface is two things: it is a set of methods, but it is also a type.

The interface{} type

The interface{} type, the empty interface, is the source of much confusion. The interface{} type is the interface that has no methods. Since there is no implements keyword, all types implement at least zero methods, and satisfying an interface is done automatically, all types satisfy the empty interface. That means that if you write a function that takes an interface{} value as a parameter, you can supply that function with any value. So this function:

func DoSomething(v interface{}) {
// ...
}

will accept any parameter whatsoever.

Type assertions

(code for: Basics Interfaces)

Error handling

There is no exceptions in Go, errors are returned by value, or aggregated in intermediate objects. In go error is simply value which should be handled programatically as quick as possible.

Sources:

(code for: Basics Errors)

Panics

  • Used when we want to stop the program.
  • We can check if there was a panic occurence in function defer chain

(code for: Basics Panics)

Strings

In Go, a string is in effect a read-only slice of bytes.

It's important to state right up front that a string holds arbitrary bytes. It is not required to hold Unicode text, UTF-8 text, or any other predefined format. As far as the content of a string is concerned, it is exactly equivalent to a slice of bytes.

More on https://blog.golang.org/strings

(code for: Basics Strings)

Go routines

A goroutine is a lightweight thread of execution.

Goroutines run in the same address space, so access to shared memory must be synchronized. The sync package provides useful primitives, although you won't need them much in Go as there are other primitives (channels).

Channels are a typed conduit through which you can send and receive values with the channel operator, <-.

(code for: Basics Goroutines)

Using 3rd parties

In go we can get packages to our $GOPATH with use of go get command.

DEP

go dep init

dep is fully-fledged dependency manager. It downloads all dependencies source code to vendor directory and then compilator includes those code during compilation process.

(code for: Basics 3rd Party Packages)

Basics Pointers

There is no README.md for Basics Pointers use (code for: Basics Pointers) link to follow code examples

Other concurrency patterns

You've lerned about channels primitive on previous chapter of this workshops, now it's time to learn about some other ways of creating concurrent programs in go.

We'll be doing some code with:

  • data races errors
  • atomic counters
  • mutexes
  • wait groups

(code for: Concurrency Other)

Channels

Channels are a typed conduit through which you can send and receive values with the channel operator, <-.

ch <- v    // Send v to channel ch.
v := <-ch  // Receive from ch, and
        // assign value to v.

(The data flows in the direction of the arrow.)

Like maps and slices, channels must be created before use:

eventsChannel := make(chan int)

By default, sends and receives block until the other side is ready. This allows goroutines to synchronize without explicit locks or condition variables.

Buffered Channels

Channels can be buffered. Provide the buffer length as the second argument to make to initialize a buffered channel:

ch := make(chan int, 100)

Sends to a buffered channel block only when the buffer is full. Receives block when the buffer is empty.

In this workshops you'll learn about:

  • channels mechanics
  • receiving data from channel
  • channels length
  • buffers
  • channel closing
  • generate data with channels
  • timers, tickers with channels
  • worker pool
  • rate limiting with channels
  • selecting proper channel stream
  • pipeline and fan-in/fan-out patterns

Feel free to browse channels chapter source code

(code for: Concurrency Channels)

Date time

Go has very powerful standard library, first and one of awesome library are is Date time.

(code for: Stdlib Date Time)

Running commands in shell

(code for: Stdlib Os Processes)

Args and flags

One of important thing when runnein your program is to get some arguments from user.

in Go you can easily get those data using os.Args slice or more powerful package flags.

Additionally you can get environment variables from os.Getenv function in os package

(code for: Stdlib Args)

Streams

Streams in go are very powerful feature, very large part of standard library is written as some kind of stream reader or stream writer.

Go have two basic interfaces shaping all world of data streams io.Reader and io.Writer.

In this section of workhops we'll try to cover some of use cases for each of them.

(code for: Stdlib Streams)

Basic IO operations

  • bufio examples
  • directory traversal
  • merging files with use of buffers

(code for: Stdlib Io)

Stdlib Logging package

Go has basic logging package to log what's happening in your program.

(code for: Stdlib Logging)

HTTP library

Package http provides HTTP client and server implementations.

HTTP is one of fundamental lib in programming. Go has implemented very powerful HTTP primitives which allows creation of full-fledged HTTP powered servers.

Info: there is no routing in stdlib so you need to implement your own or use third party libraries (Gorilla mux, Gin, Echo are ones who can help you)

(code for: Stdlib Http)

HTTP Middlewares

Go is using the term middleware, but each language/framework calls the concept differently. NodeJS and Rails calls it middleware. In the Java EE (i.e. Java Servlet), it’s called filters. C# calls it delegate handlers.

Essentially, the middleware performs some specific function on the HTTP request or response at a specific stage in the HTTP pipeline before or after the user defined controller. Middleware is a design pattern to eloquently add cross cutting concerns like logging, handling authentication, or gzip compression without having many code contact points.

(code for: Stdlib Http Middlewares)

Stdlib Encoding Json

There is no README.md for Stdlib Encoding Json use (code for: Stdlib Encoding Json) link to follow code examples

Stdlib Encoding Xml

There is no README.md for Stdlib Encoding Xml use (code for: Stdlib Encoding Xml) link to follow code examples

Templates

In programming we need often some meta templates who help us with interoperability between our code and many output formats. One example could be template engine for generating HTML files for web sites.

In Go there are template engines (yes plural!) implemented in stdlib!

We'll go in this chapter by some html and text template engines.

(code for: Stdlib Templates)

Stdlib Math

There is no README.md for Stdlib Math use (code for: Stdlib Math) link to follow code examples

Stdlib Regexp

There is no README.md for Stdlib Regexp use (code for: Stdlib Regexp) link to follow code examples

Context package

Context is very powerful package, in this section i've implemented HTTP client and server which handles cancelling both sides when client e.g. press Ctrl+C during request.

(code for: Stdlib Context)

Stdlib Sort

There is no README.md for Stdlib Sort use (code for: Stdlib Sort) link to follow code examples

Stdlib Signal

There is no README.md for Stdlib Signal use (code for: Stdlib Signal) link to follow code examples

MySQL

Install instructions to run this section:

cd docker/mysql
docker-compose up
mysql -uroot -proot -P7701 -h127.0.0.1 < init.sql
mysql -uroot -proot -P7701 -h127.0.0.1

(code for: Databases Mysql)

ORMs in Go

GORM the most popular Go ORM.

gorm have some nice converntions to start with new project

full documentation is on http://gorm.io/docs/

GORP - Go Object Relational Persistence

If you need some lighter abstraction on SQL driver (than full-fledged ORM)

https://github.com/go-gorp/gorp

(code for: Databases Orm)

MongoDB examples

to use this examples you'll need to run MongoDB server. you can do this using prepared docker-compose file.

cd docker/mongo
docker-compose up
mongo localhost:7702

(code for: Databases Mongodb)

Examples of Mongodb official driver

During writing this workshop (mid 2018) driver looks like not completed yet. So I think the best option would be fork of mgo from globalsign https://github.com/globalsign/mgo

(code for: Databases Mongodb Official)

RethinkDB

Why rethink here? I think it'll be worth to point out one of it's nice feature - collection changes.

#@ Dockerizing

run rethink db as container

docker run --name some-rethink -v "$PWD:/data" -d rethinkdb

mozemy również zmapować porty do lokalnej maszynki

docker run --name rethink -p 28015:28015 -v "$PWD/data:/data" -d rethinkdb

wtedy instacja kontenera będzie widoczna pod adresem localhost:28015

Zlinkuj go w swojej aplikacji

docker run --name some-app --link some-rethink:rdb -d application-that-uses-rdb

(code for: Databases Rethinkdb)

Databases Redis

There is no README.md for Databases Redis use (code for: Databases Redis) link to follow code examples

Databases Bolt

There is no README.md for Databases Bolt use (code for: Databases Bolt) link to follow code examples

Databases Postgresql

There is no README.md for Databases Postgresql use (code for: Databases Postgresql) link to follow code examples

Testing Unit Task

There is no README.md for Testing Unit Task use (code for: Testing Unit Task) link to follow code examples

Testing Unit Examples

There is no README.md for Testing Unit Examples use (code for: Testing Unit Examples) link to follow code examples

Testing Unit Dependencies

There is no README.md for Testing Unit Dependencies use (code for: Testing Unit Dependencies) link to follow code examples

Testing Http Handler

There is no README.md for Testing Http Handler use (code for: Testing Http Handler) link to follow code examples

Testing Http Server

There is no README.md for Testing Http Server use (code for: Testing Http Server) link to follow code examples

Testing Benchmarking

There is no README.md for Testing Benchmarking use (code for: Testing Benchmarking) link to follow code examples

Testing Parallel Benchmark

There is no README.md for Testing Parallel Benchmark use (code for: Testing Parallel Benchmark) link to follow code examples

Patterns Pipeline

There is no README.md for Patterns Pipeline use (code for: Patterns Pipeline) link to follow code examples

Patterns Glow Map Reduce

There is no README.md for Patterns Glow Map Reduce use (code for: Patterns Glow Map Reduce) link to follow code examples

Fullstack Html And Angular

There is no README.md for Fullstack Html And Angular use (code for: Fullstack Html And Angular) link to follow code examples

Fullstack Rest Angular Resource

There is no README.md for Fullstack Rest Angular Resource use (code for: Fullstack Rest Angular Resource) link to follow code examples

Fullstack Json Event Stream

There is no README.md for Fullstack Json Event Stream use (code for: Fullstack Json Event Stream) link to follow code examples

Fullstack Websockets

There is no README.md for Fullstack Websockets use (code for: Fullstack Websockets) link to follow code examples

Fullstack Wiki

There is no README.md for Fullstack Wiki use (code for: Fullstack Wiki) link to follow code examples

Beego

Bee init script - inicjuje podstawową strukturę katalogów. hot compile.

go get github.com/astaxie/beego
go get github.com/beego/bee
bee new hello
cd hello
bee run hello

(code for: Fullstack Beego)

Perks for Go (golang.org)

Perks contains the Go package quantile that computes approximate quantiles over an unbounded data stream within low memory and CPU bounds.

(code for: Libs Quantile Percentiles)

Libs Beep

There is no README.md for Libs Beep use (code for: Libs Beep) link to follow code examples

BRA

autoreload of your services on file change

Install first

go get -u github.com/Unknwon/bra

bra init
bra run

(code for: Libs Bra)

Libs Slack

There is no README.md for Libs Slack use (code for: Libs Slack) link to follow code examples

Libs Vegeta

There is no README.md for Libs Vegeta use (code for: Libs Vegeta) link to follow code examples

go readline implementation

https://github.com/chzyer/readline

(code for: Libs Readline)

Libs Termbox

There is no README.md for Libs Termbox use (code for: Libs Termbox) link to follow code examples

Caddy webserver

(code for: Libs Caddy)

Libs Http Echo

There is no README.md for Libs Http Echo use (code for: Libs Http Echo) link to follow code examples

Libs Http Iris

There is no README.md for Libs Http Iris use (code for: Libs Http Iris) link to follow code examples

Libs Jobrunner

There is no README.md for Libs Jobrunner use (code for: Libs Jobrunner) link to follow code examples

Libs Cron

There is no README.md for Libs Cron use (code for: Libs Cron) link to follow code examples

Validator package

(code for: Libs Validator)

Libs Gographviz

There is no README.md for Libs Gographviz use (code for: Libs Gographviz) link to follow code examples

Libs Fasthttp

There is no README.md for Libs Fasthttp use (code for: Libs Fasthttp) link to follow code examples

Libs Uiprogress

There is no README.md for Libs Uiprogress use (code for: Libs Uiprogress) link to follow code examples

Libs Termui

There is no README.md for Libs Termui use (code for: Libs Termui) link to follow code examples

Libs Emoji

There is no README.md for Libs Emoji use (code for: Libs Emoji) link to follow code examples

Libs Go Rpm

There is no README.md for Libs Go Rpm use (code for: Libs Go Rpm) link to follow code examples

Libs Grpc

There is no README.md for Libs Grpc use (code for: Libs Grpc) link to follow code examples

Libs Logrus

There is no README.md for Libs Logrus use (code for: Libs Logrus) link to follow code examples

Libs Consul

There is no README.md for Libs Consul use (code for: Libs Consul) link to follow code examples

Libs Language Bindings

There is no README.md for Libs Language Bindings use (code for: Libs Language Bindings) link to follow code examples

Libs Bigcache

There is no README.md for Libs Bigcache use (code for: Libs Bigcache) link to follow code examples

Libs Complete

There is no README.md for Libs Complete use (code for: Libs Complete) link to follow code examples

Libs Prometheus

There is no README.md for Libs Prometheus use (code for: Libs Prometheus) link to follow code examples

AWS Lambda Golang

https://aws.amazon.com/blogs/compute/announcing-go-support-for-aws-lambda/

Remember to build your handler executable for Linux!

GOOS=linux GOARCH=amd64 go build -o main main.go
zip main.zip main

Deploying

https://docs.aws.amazon.com/lambda/latest/dg/deploying-lambda-apps.html

aws lambda create-function \
--region us-west-1 \
--function-name HelloFunction \
--zip-file fileb://./main.zip \
--runtime go1.x \
--tracing-config Mode=Active \
--role arn:aws:iam::<account-id>:role/<role> \
--handler main

aws lambda create-function --region us-west-1 --function-name HelloFunction --zip-file fileb://./deployment.zip --runtime go1.x --tracing-config Mode=Active --role arn:aws:iam::270605981035:role/ --handler main

(code for: Lambda Simple)

How To Run On Production

There is no README.md for How To Run On Production use (code for: How To Run On Production) link to follow code examples

Traefik

Load balancer with hot reloading

(code for: Load Balancing Traefik)

Kubernetes deployment on local machine

We'll try now put our code in working Kubernetes cluster with use of Kubernetes and Minikube on our local machine.

Kubernetes looks great but doing quick developemnt flow could be plain in the ass, if you don't have access to infrastructure of AWS or GCE with prepared pipelines to pass your code to valid infrastructure.

What if we want do develop our containers on local machine? I did'n found the out-of-the box solution but there is quite nice workaround for managing your own registry in Sharing a local registry with minikube article.

Getting started

  1. Install kubectl and minikube

  2. using docker registry runned on minikube cluster + proxy (source)

         ❯ kubectl create -f kubernetes/kube-registry.yaml
    
         # forwarding ports is temporary
         ❯ kubectl port-forward --namespace kube-system \
         $(kubectl get po -n kube-system | grep kube-registry-v0 | \
         awk '{print $1;}') 5000:5000
    
  3. Now it's time to build our app. New docker have ability to build multi-stage builds.

    We don't need go in our system, this two step build docker will build binary in one step and put it in second step in small container without dependency.

         ❯ docker build -t localhost:5000/goapp:latest .
         ❯ docker push localhost:5000/goapp
    

    Our app is now ready to go in our local registry (on our cluster).

  4. Now it's time to deploy! We'll use declarative method of managing kubernetes cluster with use of yml files.

    First step: create deployment (i've created file deployment.yml in kubernetes directory):

        apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
        kind: Deployment
        metadata:
        name: goapp-deployment
        spec:
        selector:
            matchLabels:
            app: goapp
        replicas: 2 # tells deployment to run 2 pods matching the template
        template: # create pods using pod definition in this template
            metadata:
            labels:
                app: goapp
            spec:
            containers:
            - name: goapp
                image: localhost:5000/goapp:latest
                ports:
                - containerPort: 8080

    I've used NodePort method for exposing

    Now if our deployment is prepared (image: from our local repository), we're ready do sync our definition with kubernetes cluster:

     ❯ kubectl create -f kubernetes/deployment.yml
    

Play a little with our cluster

our deployment is ready, we can play a little with it.

- get pods:

        ❯ kubectl get pods -l app=goapp

        NAME                               READY     STATUS    RESTARTS   AGE
        goapp-deployment-684d96ff7-27hct   1/1       Running   0          1h
        goapp-deployment-684d96ff7-ltl7h   1/1       Running   0          1h

- get deployments

        ❯  kubectl get deployments -l app=goapp
        NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
        goapp-deployment   2         2         2            2           1h

- exec something on pod

        ❯ kubectl exec -it goapp-deployment-684d96ff7-27hct sh
        /app # ps aux
        PID   USER     TIME   COMMAND
            1 root       0:00 /bin/sh -c ./goapp
            5 root       0:00 ./goapp
        61 root       0:00 sh
        65 root       0:00 ps aux
        /app #

    Yeah! there is my goapp running, but **its network is exposed only inside Kubernetes cluster**. Now it's time to expose it outside cluster.

- expose as Service (`NodePort`) - use mapping of some port on cluster node to external cluster ip.

    Now create our service definition file (`kubernetes/servicey.yml`)

    ```yml
        apiVersion: v1
        kind: Service
        metadata:
        name: goapp
        labels:
            app: goapp
        spec:
        type: NodePort
        ports:
            - port: 8080
            nodePort: 30080
        selector:
            app: goapp
    ```

    And synchronise our cluster:

        ❯ kubectl create -f kubernetes/service.yml

    After that we can check if our service is created correctly:

        ❯ kubectl get service goapp
        NAME      TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
        goapp     NodePort   10.106.164.215   <none>        8080:30080/TCP   26m

    `30080` is our port which will be visible outside cluster


    Next we need to get somehow ip address of kubernetes cluster. I'm using minikube so it's quite simple

        ❯ minikube ip
        # we assign to env variable
        ❯ IP=$(minikube ip)


    When we have external cluster IP now we can access our service on given port.

        ❯ IP=$(minikube ip)
        ❯ curl $IP:30080
        Hello World! 2018-03-19 19:15:47.543450202 +0000 UTC from goapp-deployment-684d96ff7-ltl7h

    Yeah it's working.

(code for: How To Run On Kubernetes Cluster)

Debugging with Delve

https://github.com/derekparker/delve/tree/master/Documentation

Debugging in Kuberbetes

https://itnext.io/debug-a-go-application-in-kubernetes-from-ide-c45ad26d8785

(code for: Debugging Delve)

Debugging Expvar

There is no README.md for Debugging Expvar use (code for: Debugging Expvar) link to follow code examples

Profilowanie

Command

Profilowanie standardowego programu

import (
	"runtime/pprof"
)

var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

func init() {
	flag.Parse()
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
	}
}

func main() {
	defer pprof.StopCPUProfile()

Następnie budujemy binarkę i odpalamy ją z flagą cpuprofile

go build command.go && ./command -cpuprofile=data.prof

po czym możemy włączyć nasz profiler

go tool pprof command data.prof

Możemy do naszego programu dodać memory profile

var memprofile = flag.String("memprofile", "", "write memory profile to this file")


func memProfile() {
	if *memprofile != "" {
		f, err := os.Create(*memprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.WriteHeapProfile(f)
		f.Close()
		return
	}
}

informacje o pamięci zbierane są zbierane na końcu więc dorzucamy do defer list

func main() {
    defer memProfile()

Teraz możemy zbierać informacje o obu profilach

go build command.go && ./command -cpuprofile=cpu.prof -memprofile=mem.prof

go tool pprof command cpu.prof

go tool pprof command mem.prof

Web

package main

import (
	"fmt"
	"net/http"
	_ "net/http/pprof"
)

func handler(w http.ResponseWriter, r *http.Request) {
	for i := 0; i < 100000000; i++ {
		w.Write([]byte(fmt.Sprintf("%d - %d, ", i, i)))
	}
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

run in shell:

go tool pprof http://localhost:8080/debug/pprof/profile

(code for: Profiling)

New Project

There is no README.md for New Project use (code for: New Project) link to follow code examples

Shooting Yourself In The Foot

There is no README.md for Shooting Yourself In The Foot use (code for: Shooting Yourself In The Foot) link to follow code examples