update for tech summit workshop
This commit is contained in:
+25
@@ -0,0 +1,25 @@
|
|||||||
|
FROM golang:1.14-alpine AS builder
|
||||||
|
WORKDIR /agentx-loadtest-lunchandlearn
|
||||||
|
COPY . .
|
||||||
|
WORKDIR /agentx-loadtest-lunchandlearn/cmd/api
|
||||||
|
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install -mod mod
|
||||||
|
|
||||||
|
FROM alpine:latest AS release
|
||||||
|
|
||||||
|
RUN apk add curl
|
||||||
|
|
||||||
|
WORKDIR /go/bin
|
||||||
|
|
||||||
|
COPY --from=builder /go/bin .
|
||||||
|
|
||||||
|
RUN apk add -U tzdata && \
|
||||||
|
apk add --update --no-cache ca-certificates
|
||||||
|
|
||||||
|
# Run commands as non-root user
|
||||||
|
RUN adduser -S summit
|
||||||
|
USER summit
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
CMD "./api"
|
||||||
@@ -34,6 +34,17 @@ func (s *Server) setLimit(w http.ResponseWriter, r *http.Request) {
|
|||||||
s.RateLimiter = rl
|
s.RateLimiter = rl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) handleClick(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Sleep for a random amount of time up to 100 milliseconds.
|
||||||
|
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
|
||||||
|
t := r.Context().Value("rate-limit-token").(*Token)
|
||||||
|
s.RateLimiter.Release(t)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) getData(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) getData(w http.ResponseWriter, r *http.Request) {
|
||||||
data := []struct {
|
data := []struct {
|
||||||
Item1 string
|
Item1 string
|
||||||
@@ -42,7 +53,7 @@ func (s *Server) getData(w http.ResponseWriter, r *http.Request) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Item1: "books",
|
Item1: "books",
|
||||||
Item2: "hotdogs",
|
Item2: "hot dogs",
|
||||||
Item3: "trinkets",
|
Item3: "trinkets",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -53,8 +64,8 @@ func (s *Server) getData(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sleep for a random amount of time up to 5 seconds.
|
// Sleep for a random amount of time up to 1 seconds.
|
||||||
time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond)
|
time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
|
||||||
|
|
||||||
w.Write(bytes)
|
w.Write(bytes)
|
||||||
|
|
||||||
|
|||||||
@@ -20,5 +20,12 @@ func (s *Server) BuildRoutes() http.Handler {
|
|||||||
r.Get("/", s.getData)
|
r.Get("/", s.getData)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
r.Route("/click", func(r chi.Router) {
|
||||||
|
r.Use(s.rateLimiter)
|
||||||
|
r.Use(s.faulty)
|
||||||
|
|
||||||
|
r.Post("/", s.handleClick)
|
||||||
|
})
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|||||||
Executable
BIN
Binary file not shown.
+1
-1
@@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rl, err := http.NewMaxConcurrencyRateLimiter(10)
|
rl, err := http.NewMaxConcurrencyRateLimiter(50)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
version: '3.1'
|
||||||
|
|
||||||
|
services:
|
||||||
|
api:
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import http from 'k6/http';
|
||||||
|
import { sleep } from 'k6';
|
||||||
|
import { Rate, Trend } from 'k6/metrics';
|
||||||
|
|
||||||
|
const successRate = new Rate('OK');
|
||||||
|
const dataTrend = new Trend('DataTrend');
|
||||||
|
const clickTrend = new Trend('ClickTrend');
|
||||||
|
|
||||||
|
export const options = {
|
||||||
|
scenarios: {
|
||||||
|
ramp_to_current: {
|
||||||
|
executor: 'ramping-arrival-rate',
|
||||||
|
startRate: 0,
|
||||||
|
preAllocatedVUs: 200,
|
||||||
|
maxVUs: 250,
|
||||||
|
stages: [
|
||||||
|
{ duration: '4m', target: 50, },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
maintain_current: {
|
||||||
|
executor: 'constant-arrival-rate',
|
||||||
|
rate: 50,
|
||||||
|
timeUnit: '1s',
|
||||||
|
startTime: '4m',
|
||||||
|
duration: '1m',
|
||||||
|
preAllocatedVUs: 200,
|
||||||
|
maxVUs: 250,
|
||||||
|
},
|
||||||
|
ramp_to_expected: {
|
||||||
|
executor: 'ramping-arrival-rate',
|
||||||
|
startRate: 50,
|
||||||
|
startTime: '5m',
|
||||||
|
preAllocatedVUs: 600,
|
||||||
|
maxVUs: 750,
|
||||||
|
stages: [
|
||||||
|
{ duration: '4m', target: 150, },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
maintain_future: {
|
||||||
|
executor: 'constant-arrival-rate',
|
||||||
|
rate: 150,
|
||||||
|
timeUnit: '1s',
|
||||||
|
startTime: '9m',
|
||||||
|
duration: '1m',
|
||||||
|
preAllocatedVUs: 600,
|
||||||
|
maxVUs: 750,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
thresholds: {
|
||||||
|
ClickTrend: ['p(90)<100','p(95)<200'],
|
||||||
|
DataTrend: ['p(90)<1000','p(95)<1500'],
|
||||||
|
OK: ['rate==1'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the test case that should be executed.
|
||||||
|
*
|
||||||
|
* @param {any} data the data returned by setup
|
||||||
|
*/
|
||||||
|
export default function makeAPIRequest(data) {
|
||||||
|
const dataRes = http.get('http://localhost:8080/data');
|
||||||
|
const clickRes = http.post('http://localhost:8080/click');
|
||||||
|
|
||||||
|
successRate.add(dataRes.status < 300 || clickRes.status < 300);
|
||||||
|
dataTrend.add(dataRes.timings.duration);
|
||||||
|
clickTrend.add(clickRes.timings.duration);
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import http from 'k6/http';
|
||||||
|
import { sleep } from 'k6';
|
||||||
|
import { Rate, Counter, Gauge, Trend } from 'k6/metrics';
|
||||||
|
|
||||||
|
const successRate = new Rate('success_rate');
|
||||||
|
const failureCount = new Counter('failures');
|
||||||
|
const lastStatusCode = new Gauge('status_code');
|
||||||
|
const responseTime = new Trend('response_time', true);
|
||||||
|
|
||||||
|
export const options = {
|
||||||
|
scenarios: {
|
||||||
|
ramp_to_current: {},
|
||||||
|
maintain_current: {},
|
||||||
|
ramp_to_expected: {},
|
||||||
|
maintain_expected: {},
|
||||||
|
},
|
||||||
|
thresholds: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the test case that should be executed.
|
||||||
|
*
|
||||||
|
* @param {any} data the data returned by setup
|
||||||
|
*/
|
||||||
|
export default function makeAPIRequest(data) {
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user