blob: 987041f4d825582c1315d368d9e7786c05b049d6 [file] [log] [blame]
// Licensed to Apache Software Foundation (ASF) under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Apache Software Foundation (ASF) licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package main
import (
"flag"
"fmt"
"io"
"log"
"math"
"net"
"net/http"
"net/http/pprof"
"os"
"time"
"github.com/gin-gonic/gin"
_ "github.com/apache/skywalking-go"
)
var providerAddress = flag.String("provider", "", "provider address")
var netTransport = &http.Transport{
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 2 * time.Minute,
}).DialContext,
MaxIdleConns: 0,
MaxIdleConnsPerHost: math.MaxInt,
IdleConnTimeout: 90 * time.Second,
ExpectContinueTimeout: 10 * time.Second,
}
var customClient = http.Client{
Timeout: time.Second * 10,
Transport: netTransport,
}
const rpcCount = 3
func main() {
flag.Parse()
if *providerAddress == "" {
panic("provider address is empty")
}
startPprof()
engine := gin.New()
engine.Handle("GET", "/consumer", func(context *gin.Context) {
for i := 0; i < rpcCount; i++ {
v := mockBusinessCode()
resp, err := customClient.Get(fmt.Sprintf("%s?v=%f", *providerAddress, v))
if err != nil {
log.Printf("send provider request error: %v", err)
_ = context.AbortWithError(500, err)
return
}
_, err = io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error:", err)
return
}
_ = resp.Body.Close()
}
context.String(200, "success")
})
engine.Handle("GET", "/kill", func(context *gin.Context) {
os.Exit(0)
})
_ = engine.Run(":8080")
}
func mockBusinessCode() float64 {
iterations := 35_000
var res float64
for i := 0; i < iterations; i++ {
res += math.Log(math.MaxFloat64 - float64(i))
}
return res
}
func startPprof() {
mux := http.NewServeMux()
mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
svr := &http.Server{
Addr: ":6060",
ReadHeaderTimeout: 3 * time.Second,
Handler: mux,
}
go func() {
if err := svr.ListenAndServe(); err != nil {
log.Printf("starting profile server failure: %v", err)
}
}()
}