Skip to content
Snippets Groups Projects
Commit dc2d0b83 authored by fangyincheng's avatar fangyincheng
Browse files

Merge remote-tracking branch 'upstream/develop' into develop

parents f925991b 060e765c
No related branches found
No related tags found
No related merge requests found
package main
import (
"context"
"errors"
"flag"
"fmt"
log "github.com/AlexStocks/log4go"
hessian "github.com/dubbogo/hessian2"
"github.com/montanaflynn/stats"
"sync"
"sync/atomic"
"time"
)
import (
_ "github.com/dubbo/go-for-apache-dubbo/protocol/dubbo"
_ "github.com/dubbo/go-for-apache-dubbo/registry/protocol"
_ "github.com/dubbo/go-for-apache-dubbo/filter/imp"
_ "github.com/dubbo/go-for-apache-dubbo/cluster/loadbalance"
_ "github.com/dubbo/go-for-apache-dubbo/cluster/support"
"github.com/dubbo/go-for-apache-dubbo/config/support"
_ "github.com/dubbo/go-for-apache-dubbo/registry/zookeeper"
)
// they are necessary:
// export CONF_CONSUMER_FILE_PATH="xxx"
// export APP_LOG_CONF_FILE="xxx"
var concurrency = flag.Int("c", 1, "concurrency")
var total = flag.Int("n", 1, "total requests for all clients")
var survivalTimeout int = 10e9
func main() {
flag.Parse()
conc, tn, err := checkArgs(*concurrency, *total)
if err != nil {
log.Info("err: %v", err)
return
}
n := conc
m := tn / n
log.Info("concurrency: %d\nrequests per client: %d\n\n", n, m)
var wg sync.WaitGroup
wg.Add(n * m)
log.Info("sent total %d messages, %d message per client", n*m, m)
hessian.RegisterJavaEnum(Gender(MAN))
hessian.RegisterJavaEnum(Gender(WOMAN))
hessian.RegisterPOJO(&User{})
conMap, _ := support.Load()
if conMap == nil {
panic("conMap is nil")
}
time.Sleep(3e9)
var startWg sync.WaitGroup
startWg.Add(n)
var trans uint64
var transOK uint64
d := make([][]int64, n, n)
//it contains warmup time but we can ignore it
totalT := time.Now().UnixNano()
for i := 0; i < n; i++ {
dt := make([]int64, 0, m)
d = append(d, dt)
go func(i int) {
defer func() {
if r := recover(); r != nil {
log.Info("Recovered in f", r)
}
}()
//warmup
for j := 0; j < 5; j++ {
user := &User{}
err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser(context.TODO(), []interface{}{"A003"}, user)
if err != nil {
fmt.Println(err)
}
}
startWg.Done()
startWg.Wait()
for j := 0; j < m; j++ {
t := time.Now().UnixNano()
user := &User{}
err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser(context.TODO(), []interface{}{"A003"}, user)
t = time.Now().UnixNano() - t
d[i] = append(d[i], t)
if err == nil && user.Id != "" {
atomic.AddUint64(&transOK, 1)
}
if err != nil {
log.Error("The benchmark request is err , err is %v", err.Error())
}
atomic.AddUint64(&trans, 1)
wg.Done()
}
}(i)
}
wg.Wait()
totalT = time.Now().UnixNano() - totalT
log.Info("took %f ms for %d requests\n", float64(totalT)/1000000, n*m)
totalD := make([]int64, 0, n*m)
for _, k := range d {
totalD = append(totalD, k...)
}
totalD2 := make([]float64, 0, n*m)
for _, k := range totalD {
totalD2 = append(totalD2, float64(k))
}
mean, _ := stats.Mean(totalD2)
median, _ := stats.Median(totalD2)
max, _ := stats.Max(totalD2)
min, _ := stats.Min(totalD2)
p99, _ := stats.Percentile(totalD2, 99.9)
log.Info("sent requests : %d\n", n*m)
log.Info("received requests : %d\n", atomic.LoadUint64(&trans))
log.Info("received requests_OK : %d\n", atomic.LoadUint64(&transOK))
log.Info("throughput (TPS) : %d\n", int64(n*m)*1000000000/totalT)
log.Info("mean: %.f ns, median: %.f ns, max: %.f ns, min: %.f ns, p99.9: %.f ns\n", mean, median, max, min, p99)
log.Info("mean: %d ms, median: %d ms, max: %d ms, min: %d ms, p99: %d ms\n", int64(mean/1000000), int64(median/1000000), int64(max/1000000), int64(min/1000000), int64(p99/1000000))
}
// checkArgs check concurrency and total request count.
func checkArgs(c, n int) (int, int, error) {
if c < 1 {
log.Info("c < 1 and reset c = 1")
c = 1
}
if n < 1 {
log.Info("n < 1 and reset n = 1")
n = 1
}
if c > n {
return c, n, errors.New("c must be set <= n")
}
return c, n, nil
}
package main
import (
"context"
"fmt"
"strconv"
"time"
)
import (
"github.com/dubbogo/hessian2"
)
import (
"github.com/dubbo/go-for-apache-dubbo/config/support"
)
type Gender hessian.JavaEnum
func init() {
support.SetConService(new(UserProvider))
}
const (
MAN hessian.JavaEnum = iota
WOMAN
)
var genderName = map[hessian.JavaEnum]string{
MAN: "MAN",
WOMAN: "WOMAN",
}
var genderValue = map[string]hessian.JavaEnum{
"MAN": MAN,
"WOMAN": WOMAN,
}
func (g Gender) JavaClassName() string {
return "com.ikurento.user.Gender"
}
func (g Gender) String() string {
s, ok := genderName[hessian.JavaEnum(g)]
if ok {
return s
}
return strconv.Itoa(int(g))
}
func (g Gender) EnumValue(s string) hessian.JavaEnum {
v, ok := genderValue[s]
if ok {
return v
}
return hessian.InvalidJavaEnum
}
type User struct {
// !!! Cannot define lowercase names of variable
Id string
Name string
Age int32
Time time.Time
Sex Gender // 注意此处,java enum Object <--> go string
}
func (u User) String() string {
return fmt.Sprintf(
"User{Id:%s, Name:%s, Age:%d, Time:%s, Sex:%s}",
u.Id, u.Name, u.Age, u.Time, u.Sex,
)
}
func (User) JavaClassName() string {
return "com.ikurento.user.User"
}
type UserProvider struct {
GetUser func(ctx context.Context, req []interface{}, rsp *User) error
GetUser1 func(ctx context.Context, req []interface{}, rsp *User) error
}
func (u *UserProvider) Service() string {
return "com.ikurento.user.UserProvider"
}
func (u *UserProvider) Version() string {
return ""
}
......@@ -71,7 +71,7 @@ func initProfiling() {
ip, err = gxnet.GetLocalIP()
if err != nil {
panic("cat not get local ip!")
panic("can not get local ip!")
}
addr = ip + ":" + strconv.Itoa(support.GetProviderConfig().Pprof_Port)
log.Info("App Profiling startup on address{%v}", addr+PprofPath)
......
......@@ -51,7 +51,7 @@ services:
protocols:
- name: "dubbo"
ip : "192.168.56.1"
ip : "127.0.0.1"
port : 20000
#- name: "jsonrpc"
# ip: "127.0.0.1"
......
package main
import (
"context"
"errors"
"flag"
"fmt"
"github.com/dubbo/go-for-apache-dubbo/config/support"
"github.com/montanaflynn/stats"
"log"
"sync"
"sync/atomic"
"time"
)
import (
_ "github.com/dubbo/go-for-apache-dubbo/protocol/jsonrpc"
_ "github.com/dubbo/go-for-apache-dubbo/registry/protocol"
_ "github.com/dubbo/go-for-apache-dubbo/filter/imp"
_ "github.com/dubbo/go-for-apache-dubbo/cluster/loadbalance"
_ "github.com/dubbo/go-for-apache-dubbo/cluster/support"
_ "github.com/dubbo/go-for-apache-dubbo/registry/zookeeper"
)
// they are necessary:
// export CONF_CONSUMER_FILE_PATH="xxx"
// export APP_LOG_CONF_FILE="xxx"
var concurrency = flag.Int("c", 1, "concurrency")
var total = flag.Int("n", 1, "total requests for all clients")
func main() {
flag.Parse()
conc, tn, err := checkArgs(*concurrency, *total)
if err != nil {
log.Printf("err: %v", err)
return
}
n := conc
m := tn / n
log.Printf("concurrency: %d\nrequests per client: %d\n\n", n, m)
var wg sync.WaitGroup
wg.Add(n * m)
log.Printf("sent total %d messages, %d message per client", n*m, m)
conMap, _ := support.Load()
if conMap == nil {
panic("conMap is nil")
}
time.Sleep(3e9)
var startWg sync.WaitGroup
startWg.Add(n)
var trans uint64
var transOK uint64
d := make([][]int64, n, n)
//it contains warmup time but we can ignore it
totalT := time.Now().UnixNano()
for i := 0; i < n; i++ {
dt := make([]int64, 0, m)
d = append(d, dt)
go func(i int) {
defer func() {
if r := recover(); r != nil {
log.Print("Recovered in f", r)
}
}()
//warmup
for j := 0; j < 5; j++ {
user := &JsonRPCUser{}
err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser(context.TODO(), []interface{}{"A003"}, user)
if err != nil {
fmt.Println(err)
}
}
startWg.Done()
startWg.Wait()
for j := 0; j < m; j++ {
t := time.Now().UnixNano()
user := &JsonRPCUser{}
err := conMap["com.ikurento.user.UserProvider"].GetRPCService().(*UserProvider).GetUser(context.TODO(), []interface{}{"A003"}, user)
t = time.Now().UnixNano() - t
d[i] = append(d[i], t)
if err == nil && user.ID != "" {
atomic.AddUint64(&transOK, 1)
}
if err != nil {
log.Print(err.Error())
}
atomic.AddUint64(&trans, 1)
wg.Done()
}
}(i)
}
wg.Wait()
totalT = time.Now().UnixNano() - totalT
log.Printf("took %f ms for %d requests\n", float64(totalT)/1000000, n*m)
totalD := make([]int64, 0, n*m)
for _, k := range d {
totalD = append(totalD, k...)
}
totalD2 := make([]float64, 0, n*m)
for _, k := range totalD {
totalD2 = append(totalD2, float64(k))
}
mean, _ := stats.Mean(totalD2)
median, _ := stats.Median(totalD2)
max, _ := stats.Max(totalD2)
min, _ := stats.Min(totalD2)
p99, _ := stats.Percentile(totalD2, 99.9)
log.Printf("sent requests : %d\n", n*m)
log.Printf("received requests : %d\n", atomic.LoadUint64(&trans))
log.Printf("received requests_OK : %d\n", atomic.LoadUint64(&transOK))
log.Printf("throughput (TPS) : %d\n", int64(n*m)*1000000000/totalT)
log.Printf("mean: %.f ns, median: %.f ns, max: %.f ns, min: %.f ns, p99.9: %.f ns\n", mean, median, max, min, p99)
log.Printf("mean: %d ms, median: %d ms, max: %d ms, min: %d ms, p99: %d ms\n", int64(mean/1000000), int64(median/1000000), int64(max/1000000), int64(min/1000000), int64(p99/1000000))
}
// checkArgs check concurrency and total request count.
func checkArgs(c, n int) (int, int, error) {
if c < 1 {
log.Printf("c < 1 and reset c = 1")
c = 1
}
if n < 1 {
log.Printf("n < 1 and reset n = 1")
n = 1
}
if c > n {
return c, n, errors.New("c must be set <= n")
}
return c, n, nil
}
package main
import (
"context"
"fmt"
)
import (
"github.com/AlexStocks/goext/time"
)
import (
"github.com/dubbo/go-for-apache-dubbo/config/support"
)
func init() {
support.SetConService(new(UserProvider))
}
type JsonRPCUser struct {
ID string `json:"id"`
Name string `json:"name"`
Age int64 `json:"age"`
Time int64 `json:"time"`
Sex string `json:"sex"`
}
func (u JsonRPCUser) String() string {
return fmt.Sprintf(
"User{ID:%s, Name:%s, Age:%d, Time:%s, Sex:%s}",
u.ID, u.Name, u.Age, gxtime.YMDPrint(int(u.Time), 0), u.Sex,
)
}
type UserProvider struct {
GetUser func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error
GetUser1 func(ctx context.Context, req []interface{}, rsp *JsonRPCUser) error
}
func (u *UserProvider) Service() string {
return "com.ikurento.user.UserProvider"
}
func (u *UserProvider) Version() string {
return ""
}
......@@ -6,6 +6,7 @@ require (
github.com/AlexStocks/log4go v1.0.2
github.com/dubbogo/hessian2 v0.0.0-20190410112310-f093e4436e31
github.com/juju/errors v0.0.0-20190207033735-e65537c515d7
github.com/montanaflynn/stats v0.5.0
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
github.com/stretchr/testify v1.3.0
github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment