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.
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:
- https://golang.org/doc/faq#What_is_the_purpose_of_the_project
- https://talks.golang.org/2012/splash.article
- statically compiled (one fat binary with all dependencies)
- Garbage Collected
- Strong types
- Functions as first class citizens
- Object Oriented (but without inheritance and classes)
- easy deployment (no dependencies, single binary statically linked)
- no more code style wars -
gofmt
- integrated package downloader
go get
- integrated code validation
go vet
andgolint
(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 ...
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.
For recent installation instructions please refer to Golang installation guide
You'll need git
to be installed
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.
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
go get github.com/exu/go-workshops
cd $GOPATH/src/github.com/exu/go-workshops
- go test - included testing framework
- go fmt - code formater - only one valid coding standard - fmt library website
- go vet - code validator and fixer - vet library website
- go oracle - dependencies analyser (can be integrated in editor) oracle web site
- godoc - great documentation generator and viewer
- gocode - autocomplete service - gocode library website
- IntelliJ Go plugin https://plugins.jetbrains.com/plugin/9568-go
- GoLand - https://www.jetbrains.com/go/
- Emacs - go-mode
- Vim - vim-go
- Visual Studio Code (really great UX)
- LiteIDE
- SublimeText
- Atom
- 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.
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.
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"
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
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.
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 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
-
Check
echo $GO111MODULE
first - if value isoff
orauto
you need to set it toon
-
go mod init
initialize modules in project directory -
go mod tidy
cleans your unused modules -
go mod download
downloads modules to cache -
go mod vendor
vendoring modules from cache -
go build
,go test
,go run
downloads modules automatically so you don't need to do it -
go run -mod vendor
using vedored modules
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
In go variables can be declared and assigned in one simple way a := 1
, compiler will detect type of variable based on its value.
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.
Functions in Go are "First class citizen".
- function definition
- multiple returns
- named multiple returns
- deferred calls
- variadic functions
func init() {}
is responsible for package initialisation, it's called only once when import statement for given package is called.
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
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.
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:
- https://blog.golang.org/slices
- https://github.com/golang/go/wiki/SliceTricks
- https://blog.golang.org/go-slices-usage-and-internals
- http://research.swtch.com/godata
- http://blog.golang.org/go-slices-usage-and-internals
- http://www.dotnetperls.com/slice-go
In go there is only one loop keyword: for
. It's often used with range
keyword to iterate over array like elements.
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.
There is no README.md for Basics Overriding Internal Types use (code for: Basics Overriding Internal Types) link to follow code examples
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.
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
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)
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)
Kompozycja taki pattern chyba znacie ?
(code for: Basics Struct Composition)
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)
There is no README.md for Basics Anonymous Structs use (code for: Basics Anonymous Structs) link to follow code examples
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 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.
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:
- https://blog.golang.org/errors-are-values
- http://blog.golang.org/error-handling-and-go
- http://davidnix.io/post/error-handling-in-go/
- Used when we want to stop the program.
- We can check if there was a
panic
occurence in function defer chain
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
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, <-.
In go we can get packages to our $GOPATH with use of go get
command.
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)
There is no README.md for Basics Pointers use (code for: Basics Pointers) link to follow code examples
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
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.
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.
- 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)
Go has very powerful standard library, first and one of awesome library are is Date time.
(code for: Stdlib Os Processes)
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
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.
bufio
examples- directory traversal
- merging files with use of
buffers
Go has basic logging package to log what's happening in your program.
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)
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)
There is no README.md for Stdlib Encoding Json use (code for: Stdlib Encoding Json) link to follow code examples
There is no README.md for Stdlib Encoding Xml use (code for: Stdlib Encoding Xml) link to follow code examples
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.
There is no README.md for Stdlib Math use (code for: Stdlib Math) link to follow code examples
There is no README.md for Stdlib Regexp use (code for: Stdlib Regexp) link to follow code examples
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.
There is no README.md for Stdlib Sort use (code for: Stdlib Sort) link to follow code examples
There is no README.md for Stdlib Signal use (code for: Stdlib Signal) link to follow code examples
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
gorm have some nice converntions to start with new project
full documentation is on http://gorm.io/docs/
If you need some lighter abstraction on SQL driver (than full-fledged ORM)
https://github.com/go-gorp/gorp
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
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)
Why rethink here? I think it'll be worth to point out one of it's nice feature - collection changes.
#@ Dockerizing
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
docker run --name some-app --link some-rethink:rdb -d application-that-uses-rdb
(code for: Databases Rethinkdb)
There is no README.md for Databases Redis use (code for: Databases Redis) link to follow code examples
There is no README.md for Databases Bolt use (code for: Databases Bolt) link to follow code examples
There is no README.md for Databases Postgresql use (code for: Databases Postgresql) link to follow code examples
There is no README.md for Testing Unit Task use (code for: Testing Unit Task) link to follow code examples
There is no README.md for Testing Unit Examples use (code for: Testing Unit Examples) link to follow code examples
There is no README.md for Testing Unit Dependencies use (code for: Testing Unit Dependencies) link to follow code examples
There is no README.md for Testing Http Handler use (code for: Testing Http Handler) link to follow code examples
There is no README.md for Testing Http Server use (code for: Testing Http Server) link to follow code examples
There is no README.md for Testing Benchmarking use (code for: Testing Benchmarking) link to follow code examples
There is no README.md for Testing Parallel Benchmark use (code for: Testing Parallel Benchmark) link to follow code examples
There is no README.md for Patterns Pipeline use (code for: Patterns Pipeline) link to follow code examples
There is no README.md for Patterns Glow Map Reduce use (code for: Patterns Glow Map Reduce) link to follow code examples
There is no README.md for Fullstack Html And Angular use (code for: Fullstack Html And Angular) link to follow code examples
There is no README.md for Fullstack Rest Angular Resource use (code for: Fullstack Rest Angular Resource) link to follow code examples
There is no README.md for Fullstack Json Event Stream use (code for: Fullstack Json Event Stream) link to follow code examples
There is no README.md for Fullstack Websockets use (code for: Fullstack Websockets) link to follow code examples
There is no README.md for Fullstack Wiki use (code for: Fullstack Wiki) link to follow code examples
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
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)
There is no README.md for Libs Beep use (code for: Libs Beep) link to follow code examples
autoreload of your services on file change
go get -u github.com/Unknwon/bra
bra init
bra run
There is no README.md for Libs Slack use (code for: Libs Slack) link to follow code examples
There is no README.md for Libs Vegeta use (code for: Libs Vegeta) link to follow code examples
https://github.com/chzyer/readline
There is no README.md for Libs Termbox use (code for: Libs Termbox) link to follow code examples
There is no README.md for Libs Http Echo use (code for: Libs Http Echo) link to follow code examples
There is no README.md for Libs Http Iris use (code for: Libs Http Iris) link to follow code examples
There is no README.md for Libs Jobrunner use (code for: Libs Jobrunner) link to follow code examples
There is no README.md for Libs Cron use (code for: Libs Cron) link to follow code examples
There is no README.md for Libs Gographviz use (code for: Libs Gographviz) link to follow code examples
There is no README.md for Libs Fasthttp use (code for: Libs Fasthttp) link to follow code examples
There is no README.md for Libs Uiprogress use (code for: Libs Uiprogress) link to follow code examples
There is no README.md for Libs Termui use (code for: Libs Termui) link to follow code examples
There is no README.md for Libs Emoji use (code for: Libs Emoji) link to follow code examples
There is no README.md for Libs Go Rpm use (code for: Libs Go Rpm) link to follow code examples
There is no README.md for Libs Grpc use (code for: Libs Grpc) link to follow code examples
There is no README.md for Libs Logrus use (code for: Libs Logrus) link to follow code examples
There is no README.md for Libs Consul use (code for: Libs Consul) link to follow code examples
There is no README.md for Libs Language Bindings use (code for: Libs Language Bindings) link to follow code examples
There is no README.md for Libs Bigcache use (code for: Libs Bigcache) link to follow code examples
There is no README.md for Libs Complete use (code for: Libs Complete) link to follow code examples
There is no README.md for Libs Prometheus use (code for: Libs Prometheus) link to follow code examples
https://aws.amazon.com/blogs/compute/announcing-go-support-for-aws-lambda/
GOOS=linux GOARCH=amd64 go build -o main main.go
zip main.zip main
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
There is no README.md for How To Run On Production use (code for: How To Run On Production) link to follow code examples
Load balancer with hot reloading
(code for: Load Balancing Traefik)
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.
-
Install kubectl and minikube
-
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
-
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).
-
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
inkubernetes
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 exposingNow 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
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)
https://github.com/derekparker/delve/tree/master/Documentation
https://itnext.io/debug-a-go-application-in-kubernetes-from-ide-c45ad26d8785
There is no README.md for Debugging Expvar use (code for: Debugging Expvar) link to follow code examples
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
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
There is no README.md for New Project use (code for: New Project) link to follow code examples
There is no README.md for Shooting Yourself In The Foot use (code for: Shooting Yourself In The Foot) link to follow code examples