commit
3c826c123f
12 changed files with 379 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||||
|
golang-fasthttp |
||||
|
|
||||
@ -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/ |
||||
|
|
||||
@ -0,0 +1,5 @@ |
|||||
|
module itix.fr/golang-http-benchmark/golang-fasthttp |
||||
|
|
||||
|
go 1.14 |
||||
|
|
||||
|
require github.com/valyala/fasthttp v1.15.1 |
||||
@ -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") |
||||
|
} |
||||
@ -0,0 +1,2 @@ |
|||||
|
golang-net-http |
||||
|
|
||||
@ -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/ |
||||
@ -0,0 +1,3 @@ |
|||||
|
module itix.fr/golang-http-benchmark/golang-net-http |
||||
|
|
||||
|
go 1.14 |
||||
@ -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()) |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
jmeter.log |
||||
|
results-* |
||||
|
report-* |
||||
@ -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("${scenario}" == "golang-net-http",)}</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("${scenario}" == "golang-fasthttp",)}</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> |
||||
@ -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 |
||||
@ -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…
Reference in new issue