Browse Source

initial commit

master
Nicolas Massé 5 years ago
commit
3c826c123f
  1. 2
      golang-fasthttp/.gitignore
  2. 18
      golang-fasthttp/build-and-deploy.sh
  3. 5
      golang-fasthttp/go.mod
  4. 26
      golang-fasthttp/main.go
  5. 2
      golang-net-http/.gitignore
  6. 17
      golang-net-http/build-and-deploy.sh
  7. 3
      golang-net-http/go.mod
  8. 32
      golang-net-http/main.go
  9. 3
      jmeter/.gitignore
  10. 243
      jmeter/golang-http-benchmark.jmx
  11. 18
      jmeter/run.sh
  12. 10
      jmeter/user.properties

2
golang-fasthttp/.gitignore

@ -0,0 +1,2 @@
golang-fasthttp

18
golang-fasthttp/build-and-deploy.sh

@ -0,0 +1,18 @@
#!/bin/sh
if [ $# -ne 1 ]; then
echo "Usage: $0 user@target.hostname"
exit 1
fi
set -xe
#go generate
GOOS=linux GOARCH=arm GOARM=5 go build -o golang-fasthttp
ssh $1 start-stop-daemon -x /usr/local/bin/golang-fasthttp -b -K || true
ssh $1 mkdir -p /usr/local/bin/
scp golang-fasthttp $1:/usr/local/bin/golang-fasthttp
ssh $1 start-stop-daemon -x /usr/local/bin/golang-fasthttp -b -S
ssh $1 pgrep golang-fasthttp
curl http://$1:8002/

5
golang-fasthttp/go.mod

@ -0,0 +1,5 @@
module itix.fr/golang-http-benchmark/golang-fasthttp
go 1.14
require github.com/valyala/fasthttp v1.15.1

26
golang-fasthttp/main.go

@ -0,0 +1,26 @@
package main
import (
"fmt"
"time"
"github.com/valyala/fasthttp"
)
type HelloWorldHandler struct {
}
func fastHTTPHandler(ctx *fasthttp.RequestCtx) {
fmt.Fprintln(ctx, "Hello, World!")
}
func main() {
s := &fasthttp.Server{
Handler: fastHTTPHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
IdleTimeout: 10 * time.Second,
}
fmt.Println("Listening for requests on port 8002...")
s.ListenAndServe(":8002")
}

2
golang-net-http/.gitignore

@ -0,0 +1,2 @@
golang-net-http

17
golang-net-http/build-and-deploy.sh

@ -0,0 +1,17 @@
#!/bin/sh
if [ $# -ne 1 ]; then
echo "Usage: $0 user@target.hostname"
exit 1
fi
set -xe
#go generate
GOOS=linux GOARCH=arm GOARM=5 go build -o golang-net-http
ssh $1 start-stop-daemon -x /usr/local/bin/golang-net-http -b -K || true
ssh $1 mkdir -p /usr/local/bin/
scp golang-net-http $1:/usr/local/bin/golang-net-http
ssh $1 start-stop-daemon -x /usr/local/bin/golang-net-http -b -S
ssh $1 pgrep golang-net-http
curl http://$1:8001/

3
golang-net-http/go.mod

@ -0,0 +1,3 @@
module itix.fr/golang-http-benchmark/golang-net-http
go 1.14

32
golang-net-http/main.go

@ -0,0 +1,32 @@
package main
import (
"fmt"
"log"
"net/http"
"time"
)
type HelloWorldHandler struct {
}
func (h *HelloWorldHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("Hello, World!"))
}
func main() {
h := &HelloWorldHandler{}
s := &http.Server{
Addr: ":8001",
Handler: h,
ReadTimeout: 10 * time.Second,
ReadHeaderTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
IdleTimeout: 10 * time.Second,
}
fmt.Println("Listening for requests on port 8001...")
log.Fatal(s.ListenAndServe())
}

3
jmeter/.gitignore

@ -0,0 +1,3 @@
jmeter.log
results-*
report-*

243
jmeter/golang-http-benchmark.jmx

@ -0,0 +1,243 @@
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.3">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="golang-http-benchmark" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="Global Variables" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="server_hostname" elementType="Argument">
<stringProp name="Argument.name">server_hostname</stringProp>
<stringProp name="Argument.value">seagate-goflex.itix.fr</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="scenario" elementType="Argument">
<stringProp name="Argument.name">scenario</stringProp>
<stringProp name="Argument.value">${__P(scenario,golang-net-http)}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</Arguments>
<hashTree/>
<kg.apc.jmeter.threads.UltimateThreadGroup guiclass="kg.apc.jmeter.threads.UltimateThreadGroupGui" testclass="kg.apc.jmeter.threads.UltimateThreadGroup" testname="5 Virtual User" enabled="true">
<collectionProp name="ultimatethreadgroupdata">
<collectionProp name="-368223173">
<stringProp name="53">5</stringProp>
<stringProp name="48">0</stringProp>
<stringProp name="1567">10</stringProp>
<stringProp name="48687">120</stringProp>
<stringProp name="1567">10</stringProp>
</collectionProp>
</collectionProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<intProp name="LoopController.loops">-1</intProp>
</elementProp>
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
</kg.apc.jmeter.threads.UltimateThreadGroup>
<hashTree>
<LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="Loop" enabled="true">
<boolProp name="LoopController.continue_forever">true</boolProp>
<intProp name="LoopController.loops">-1</intProp>
</LoopController>
<hashTree>
<DebugSampler guiclass="TestBeanGUI" testclass="DebugSampler" testname="Debug" enabled="false">
<boolProp name="displayJMeterProperties">false</boolProp>
<boolProp name="displayJMeterVariables">true</boolProp>
<boolProp name="displaySystemProperties">false</boolProp>
</DebugSampler>
<hashTree/>
<IfController guiclass="IfControllerPanel" testclass="IfController" testname="If golang-net-http" enabled="true">
<stringProp name="IfController.condition">${__jexl3(&quot;${scenario}&quot; == &quot;golang-net-http&quot;,)}</stringProp>
<boolProp name="IfController.evaluateAll">false</boolProp>
<boolProp name="IfController.useExpression">true</boolProp>
</IfController>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="golang-net-http" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain">${server_hostname}</stringProp>
<stringProp name="HTTPSampler.port">8001</stringProp>
<stringProp name="HTTPSampler.protocol">http</stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path">/</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
<stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree/>
</hashTree>
<IfController guiclass="IfControllerPanel" testclass="IfController" testname="If golang-fasthttp" enabled="true">
<stringProp name="IfController.condition">${__jexl3(&quot;${scenario}&quot; == &quot;golang-fasthttp&quot;,)}</stringProp>
<boolProp name="IfController.evaluateAll">false</boolProp>
<boolProp name="IfController.useExpression">true</boolProp>
</IfController>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="golang-fasthttp" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain">${server_hostname}</stringProp>
<stringProp name="HTTPSampler.port">8002</stringProp>
<stringProp name="HTTPSampler.protocol">http</stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path">/</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
<stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree/>
</hashTree>
</hashTree>
</hashTree>
<kg.apc.jmeter.vizualizers.CorrectedResultCollector guiclass="kg.apc.jmeter.vizualizers.ResponseTimesOverTimeGui" testclass="kg.apc.jmeter.vizualizers.CorrectedResultCollector" testname="Response Times Over Time" enabled="false">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<sentBytes>true</sentBytes>
<url>true</url>
<threadCounts>true</threadCounts>
<idleTime>true</idleTime>
<connectTime>true</connectTime>
</value>
</objProp>
<stringProp name="filename">response-time.csv</stringProp>
<longProp name="interval_grouping">500</longProp>
<boolProp name="graph_aggregated">false</boolProp>
<stringProp name="include_sample_labels"></stringProp>
<stringProp name="exclude_sample_labels"></stringProp>
<stringProp name="start_offset"></stringProp>
<stringProp name="end_offset"></stringProp>
<boolProp name="include_checkbox_state">false</boolProp>
<boolProp name="exclude_checkbox_state">false</boolProp>
</kg.apc.jmeter.vizualizers.CorrectedResultCollector>
<hashTree/>
<kg.apc.jmeter.vizualizers.CorrectedResultCollector guiclass="kg.apc.jmeter.vizualizers.TransactionsPerSecondGui" testclass="kg.apc.jmeter.vizualizers.CorrectedResultCollector" testname="Transactions per Second" enabled="false">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<sentBytes>true</sentBytes>
<url>true</url>
<threadCounts>true</threadCounts>
<idleTime>true</idleTime>
<connectTime>true</connectTime>
</value>
</objProp>
<stringProp name="filename">tps.csv</stringProp>
<longProp name="interval_grouping">1000</longProp>
<boolProp name="graph_aggregated">false</boolProp>
<stringProp name="include_sample_labels"></stringProp>
<stringProp name="exclude_sample_labels"></stringProp>
<stringProp name="start_offset"></stringProp>
<stringProp name="end_offset"></stringProp>
<boolProp name="include_checkbox_state">false</boolProp>
<boolProp name="exclude_checkbox_state">false</boolProp>
</kg.apc.jmeter.vizualizers.CorrectedResultCollector>
<hashTree/>
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="false">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>true</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<sentBytes>true</sentBytes>
<url>true</url>
<threadCounts>true</threadCounts>
<idleTime>true</idleTime>
<connectTime>true</connectTime>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</jmeterTestPlan>

18
jmeter/run.sh

@ -0,0 +1,18 @@
#!/bin/sh
set -e # Do not continue if jmeter fails
: ${JMETER:=jmeter}
export HEAP="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m"
date="$(date +%F-%H-%M-%S)"
for scenario in golang-net-http golang-fasthttp; do
echo
echo "================================================================================"
echo "Running scenario $scenario..."
echo "================================================================================"
echo
export JVM_ARGS="-Djmeter.reportgenerator.report_title=$scenario"
$JMETER -n -t golang-http-benchmark.jmx -l "results-$date-$scenario.csv" -e -o "report-$date-$scenario" -Jscenario=$scenario
sleep 2
done

10
jmeter/user.properties

@ -0,0 +1,10 @@
# Aggregate metrics over the second (rather than the minute)
jmeter.reportgenerator.overall_granularity=1000
# Keep alive timeouts
httpclient4.idletimeout=10000
httpclient4.time_to_live=60000
httpclient4.validate_after_inactivity=10000
# Enable this if your HTTP sampler is not enclosed in a loop
#httpclient.reset_state_on_thread_group_iteration=false
Loading…
Cancel
Save