Today I invite you to do a hands-on exercise and check out how PGO works in Golang.
This demo is based on this repo, which I encourage you to clone: fira.curie/go-pgo-app.
Prerequisites
You would need the following tools installed on your machine:
- Docker or Podman - if you’re using podman, you need to enable insecure registry (see below).
- kind to provision a local k8s cluster in a container.
- Helm - for deploying our app, Pyroscope, and optionally Grafana.
- ohayou - for simulating production load.
- profilecli - for collecting profile data from the app.
Assumptions
I assume that you know how to work with git, bash, kubernetes, helm, and docker. If you don’t, you can check out the official documentation and helm documentation.
I also assume that you have a basic understanding of how Go works and what is PGO. If not - see further reading section.
The purpose of this workshop is to give you a hands-on experience with PGO in Go and create a playground to experiment with different types of loads.
If you have any questions or encounter any problems, feel free to email me!
Let’s go!
Setup cluster
Create kind(kubernetes in docker) cluster and create a registry container for storing and deploying local images.
|
|
Deploy Pyroscope (optionally with Grafana)
Add helm chart
|
|
If you’re using podman instead of docker
You need to explicitly enable insecure registry
First iteration of the Go app
For the purposes of this demonstration, we are going to use /render
http handler, but you can add your own kind of workload here.
First of all we need to build our app.
- You can notice that we have set an argument for PGO_FILE in the Dockerfile.
- By default go looks for default.pgo file, but it also accepts
off
as a parameter to disable PGO. - BUILD_VERSION is used as a tag for the image in order to track the changes of the certain version in Pyroscope. You could do this at runtime as well.
|
|
Push the image to the local registry we deployed previously in a docker container and deploy the app with helm.
Simulate production load
We need some workload on our server. Let’s send some .md files its way.
|
|
Don’t forget to save this data for comparison.
Collect profile data
Check pyroscope UI where you can see the traces of the requests.
Collect the profile data from the app for the optimized build into a file named go-pgo-app-v1.0.0.pgo
.
You could also notice that we are passing the same version in iteration parameter as we did in the BUILD_VERSION.
|
|
This will create a file named go-pgo-app-v1.0.0.pgo
in your current directory containing trace data for the first iteration of the app.
Second optimized iteration of the Go app
Now let’s rebuild the app with the collected profile data. As you can see we are passing the PGO_FILE as an argument to create an optimized build. Also we should increment BUILD_VERSION and image tag to track the new app traces.
Now we can either upgrade the helm chart with the new image or deploy the new version alongside. Set the image tag to the new version.
Check the results
Now compare the two runs.