Skip to content

Commit 05bb3a5

Browse files
MattDodsonEnglishppcanomstoykov
authored
[Feat] add example to split logic across VUs (#1179)
- fixes #750 Co-authored-by: Pepe Cano <[email protected]> Co-authored-by: Mihail Stoykov <[email protected]>
1 parent ee675b5 commit 05bb3a5

File tree

2 files changed

+170
-0
lines changed

2 files changed

+170
-0
lines changed

src/data/doc-examples/links.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,12 @@
131131
"description": "How to instantly increase the number of VUs or iterations",
132132
"url": "",
133133
"to": "/examples/instant-load-increase/"
134+
},
135+
{
136+
"title": "Distribute workloads across VUs",
137+
"description": "How to configure different amounts of traffic for different VU behaviors",
138+
"url": "",
139+
"to": "/examples/distribute-workloads/"
134140
}
135141
],
136142
"tutorials": [
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
---
2+
title: Distribute workloads across VUs
3+
excerpt: How to configure different amounts of traffic for different VU behaviors
4+
slug: /examples/distribute-workloads
5+
---
6+
7+
k6 can schedule different load patterns for different VU functions.
8+
A test with multiple workloads might better simulate traffic in the real world, where user behavior is rarely uniform.
9+
For example, most traffic to an e-commerce site might come from users who only search for items and read reviews. A small percentage of users might actively shop, performing actions that involve writes to the database and calls to different APIs.
10+
11+
12+
The following sections provide examples of how to structure k6 scripts to split logic across VUs.
13+
To inspect the results for a certain behavior, you can [create a custom metric](/using-k6/metrics/create-custom-metrics) or use [Tags](/using-k6/tags-and-groups) to filter by scenario, code block, or individual request.
14+
15+
<Blockquote mod="note" title="Aim for simplicity">
16+
17+
These techniques can create very complex configurations.
18+
However, more complexity creates more ambiguity in result interpretation
19+
20+
</Blockquote>
21+
22+
23+
## Split logic across scenarios
24+
25+
<Blockquote mod="note" title="">
26+
27+
In this context, _workload_ refers to the traffic pattern simulated by a scenario.
28+
29+
</Blockquote>
30+
31+
32+
One way to distribute traffic is to use scenarios to schedule different workloads for different functions.
33+
1. Define multiple scenarios in your [options](/using-k6/options).
34+
1. Use the scenario `exec` property to execute different VU functions with a workload.
35+
36+
For example, imagine a social media site that typically receives 100 concurrent users.
37+
Of those, 80 might visit their contacts page, and 20 might view the news.
38+
To configure such a distribution, make two scenarios with different throughput or VUs:
39+
40+
41+
```javascript
42+
import http from "k6/http";
43+
44+
export const options = {
45+
//scenario to view contacts
46+
scenarios: {
47+
contacts: {
48+
executor: "shared-iterations",
49+
exec: "contacts",
50+
vus: 80,
51+
iterations: 100,
52+
},
53+
//scenario to view news
54+
news: {
55+
executor: "shared-iterations",
56+
exec: "news",
57+
vus: 20,
58+
iterations: 100,
59+
},
60+
},
61+
};
62+
63+
//use the exec property to run different scenarios for different functions
64+
65+
export function contacts() {
66+
http.get("https://test.k6.io/contacts.php");
67+
}
68+
69+
export function news() {
70+
http.get("https://test.k6.io/news.php");
71+
}
72+
```
73+
74+
To view granular results for a specific scenario, you can filter by the built-in scenario [tag](/using-k6/tags-and-groups).
75+
76+
## Distribute logic by VU ID
77+
78+
In some cases, writing a scenario for each behavior might be inconvenient or impractical.
79+
As an alternative, you can distribute logic across a range of VUs with the [execution context variables](/using-k6/execution-context-variables) from the [`k6/execution`](https://k6.io/docs/javascript-api/k6-execution/) module.
80+
With the `exec` object, you can scope logic to a specific instance, scenario, or across all VUs.
81+
82+
For example, this statement assigns behavior to the first 25 VUs in a test.
83+
84+
```bash
85+
if (exec.vu.idInTest <= 25) {
86+
//do something;
87+
}
88+
```
89+
90+
91+
For more flexibility, you can use modulo expressions distribute VUs according to percentages.
92+
For example, the following script distributes logic according to different user profiles:
93+
- 40 percent of users check the news.
94+
- 60 percent play a coinflip game.
95+
- Half bet `heads` and half bet `tails`.
96+
97+
<CodeGroup labels={["behavior-based-on-exec-context.js"]} lineNumbers={[true]} showCopyButton={[true]}>
98+
99+
```javascript
100+
import http from "k6/http";
101+
import exec from "k6/execution";
102+
103+
export const options = {
104+
scenarios: {
105+
quickRamp: {
106+
executor: "ramping-arrival-rate",
107+
startRate: 0,
108+
timeUnit: "1s",
109+
preAllocatedVUs: 100,
110+
stages: [
111+
{ target: 10, duration: "10s" },
112+
{ target: 10, duration: "15s" },
113+
{ target: 0, duration: "5s" },
114+
],
115+
},
116+
},
117+
};
118+
119+
export default function () {
120+
if (exec.vu.idInTest % 10 < 4) {
121+
// 0-3 range, read the news
122+
http.get("http://test.k6.io/news");
123+
} else if (exec.vu.idInTest % 10 < 7) {
124+
// 4-6 range, bet heads
125+
http.get("http://test.k6.io/flip_coin.php?bet=heads");
126+
} else {
127+
// 7-9 range, bet tails
128+
http.get("http://test.k6.io/flip_coin.php?bet=tails");
129+
}
130+
}
131+
132+
```
133+
134+
To view results for a specific request or group, you can define [tags](/using-k6/tags-and-groups).
135+
136+
</CodeGroup>
137+
138+
139+
## Randomize behavior
140+
141+
To add a degree of random behavior, consider one of the randomizing functions from the [k6 utils](https://k6.io/docs/javascript-api/jslib/utils/).
142+
143+
For example, this script randomly assigns one behavior to happen one-third of the time, and another to happen all other times.
144+
145+
<CodeGroup labels={["random-behavior.js"]} lineNumbers={[]} showCopyButton={[true]}>
146+
147+
```javascript
148+
import { sleep } from "k6";
149+
import { randomIntBetween } from "https://jslib.k6.io/k6-utils/1.2.0/index.js";
150+
151+
export default function () {
152+
if (randomIntBetween(1, 3) % 3 > 1) {
153+
console.log("1 in 3 times");
154+
} else {
155+
console.log("2 in 3 times");
156+
}
157+
}
158+
159+
```
160+
161+
</CodeGroup>
162+
163+
For a more sophisticated example of randomizing, read this [forum post](https://community.k6.io/t/how-to-distribute-vus-across-different-scenarios-with-k6/49/17).
164+

0 commit comments

Comments
 (0)