snapshot of https://github.com/nats-io/nats-server.git (main, 2026-09-15; blobs > 131072B omitted)
Some checks failed
NATS Server Tests / Lint (push) Failing after 3s
NATS Server Tests / Build (Latest Go) (push) Has been skipped
NATS Server Tests / Build (Minimum Go) (push) Has been skipped
NATS Server Tests / Build (Minimum Go, windows-2022) (push) Has been skipped
NATS Server Tests / Build (Minimum Go, windows-2025) (push) Has been skipped
NATS Server Tests / Test Stores (push) Has been skipped
NATS Server Tests / Test JetStream (push) Has been skipped
NATS Server Tests / Test Raft (push) Has been skipped
NATS Server Tests / Test JetStream Consumers (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 1 (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 2 (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 3 (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 4 (push) Has been skipped
NATS Server Tests / Test JetStream Supercluster (push) Has been skipped
NATS Server Tests / Test No-Race 1 (push) Has been skipped
NATS Server Tests / Test No-Race 2 (push) Has been skipped
NATS Server Tests / Test MQTT (push) Has been skipped
NATS Server Tests / Test Message Tracing (push) Has been skipped
NATS Server Tests / Test JWT (push) Has been skipped
NATS Server Tests / Test Remaining Server Tests (push) Has been skipped
NATS Server Tests / Test Other Packages (push) Has been skipped
Vulnerability Scan / govulncheck (push) Failing after 12m2s
Some checks failed
NATS Server Tests / Lint (push) Failing after 3s
NATS Server Tests / Build (Latest Go) (push) Has been skipped
NATS Server Tests / Build (Minimum Go) (push) Has been skipped
NATS Server Tests / Build (Minimum Go, windows-2022) (push) Has been skipped
NATS Server Tests / Build (Minimum Go, windows-2025) (push) Has been skipped
NATS Server Tests / Test Stores (push) Has been skipped
NATS Server Tests / Test JetStream (push) Has been skipped
NATS Server Tests / Test Raft (push) Has been skipped
NATS Server Tests / Test JetStream Consumers (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 1 (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 2 (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 3 (push) Has been skipped
NATS Server Tests / Test JetStream Cluster 4 (push) Has been skipped
NATS Server Tests / Test JetStream Supercluster (push) Has been skipped
NATS Server Tests / Test No-Race 1 (push) Has been skipped
NATS Server Tests / Test No-Race 2 (push) Has been skipped
NATS Server Tests / Test MQTT (push) Has been skipped
NATS Server Tests / Test Message Tracing (push) Has been skipped
NATS Server Tests / Test JWT (push) Has been skipped
NATS Server Tests / Test Remaining Server Tests (push) Has been skipped
NATS Server Tests / Test Other Packages (push) Has been skipped
Vulnerability Scan / govulncheck (push) Failing after 12m2s
This commit is contained in:
185
server/benchmark_publish_test.go
Normal file
185
server/benchmark_publish_test.go
Normal file
@@ -0,0 +1,185 @@
|
||||
// Copyright 2022-2026 The NATS Authors
|
||||
// Licensed 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 server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand/v2"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
||||
"github.com/nats-io/nats.go"
|
||||
)
|
||||
|
||||
func BenchmarkPublish(b *testing.B) {
|
||||
|
||||
const (
|
||||
verbose = false
|
||||
minMessages = 10_000
|
||||
subject = "S"
|
||||
queue = "Q"
|
||||
)
|
||||
|
||||
const (
|
||||
KB = 1024
|
||||
MB = KB * KB
|
||||
)
|
||||
|
||||
type SubscriberType string
|
||||
const (
|
||||
Async SubscriberType = "Async"
|
||||
QueueAsync SubscriberType = "AsyncQueue"
|
||||
None SubscriberType = "None"
|
||||
)
|
||||
|
||||
benchmarksCases := []struct {
|
||||
messageSize int
|
||||
}{
|
||||
{0},
|
||||
{1},
|
||||
{32},
|
||||
{128},
|
||||
{512},
|
||||
{4 * KB},
|
||||
{32 * KB},
|
||||
{128 * KB},
|
||||
{512 * KB},
|
||||
{1 * MB},
|
||||
}
|
||||
|
||||
// All the cases above are run for each of the subscriber cases below
|
||||
subscribersCases := []struct {
|
||||
numSubs int
|
||||
subType SubscriberType
|
||||
}{
|
||||
{0, None},
|
||||
{1, Async},
|
||||
{1, QueueAsync},
|
||||
{10, Async},
|
||||
{10, QueueAsync},
|
||||
}
|
||||
|
||||
for _, bc := range benchmarksCases {
|
||||
bcName := fmt.Sprintf(
|
||||
"MsgSz=%db",
|
||||
bc.messageSize,
|
||||
)
|
||||
|
||||
b.Run(
|
||||
bcName,
|
||||
func(b *testing.B) {
|
||||
|
||||
for _, sc := range subscribersCases {
|
||||
|
||||
scName := fmt.Sprintf("Subs=%dx%v", sc.numSubs, sc.subType)
|
||||
if sc.subType == None {
|
||||
scName = fmt.Sprintf("Subs=%v", sc.subType)
|
||||
}
|
||||
|
||||
b.Run(
|
||||
scName,
|
||||
func(b *testing.B) {
|
||||
// Skip short runs, benchmark gets re-executed with a larger N
|
||||
if b.N < minMessages {
|
||||
b.ResetTimer()
|
||||
return
|
||||
}
|
||||
|
||||
if verbose {
|
||||
b.Logf("Running %s/%s with %d ops", bcName, scName, b.N)
|
||||
}
|
||||
|
||||
subErrors := uint64(0)
|
||||
handleSubError := func(_ *nats.Conn, _ *nats.Subscription, _ error) {
|
||||
atomic.AddUint64(&subErrors, 1)
|
||||
}
|
||||
|
||||
// Start single server (no JS)
|
||||
opts := DefaultTestOptions
|
||||
opts.Port = -1
|
||||
s := RunServer(&opts)
|
||||
defer s.Shutdown()
|
||||
|
||||
// Create subscribers
|
||||
for i := 0; i < sc.numSubs; i++ {
|
||||
subConn, connErr := nats.Connect(s.ClientURL(), nats.ErrorHandler(handleSubError))
|
||||
if connErr != nil {
|
||||
b.Fatalf("Failed to connect: %v", connErr)
|
||||
}
|
||||
defer subConn.Close()
|
||||
|
||||
var sub *nats.Subscription
|
||||
var subErr error
|
||||
|
||||
switch sc.subType {
|
||||
case None:
|
||||
// No subscription
|
||||
case Async:
|
||||
sub, subErr = subConn.Subscribe(subject, func(*nats.Msg) {})
|
||||
case QueueAsync:
|
||||
sub, subErr = subConn.QueueSubscribe(subject, queue, func(*nats.Msg) {})
|
||||
default:
|
||||
b.Fatalf("Unknow subscribers type: %v", sc.subType)
|
||||
}
|
||||
|
||||
if subErr != nil {
|
||||
b.Fatalf("Failed to subscribe: %v", subErr)
|
||||
}
|
||||
defer sub.Unsubscribe()
|
||||
// Do not drop messages due to slow subscribers:
|
||||
sub.SetPendingLimits(-1, -1)
|
||||
}
|
||||
|
||||
// Create publisher connection
|
||||
nc, err := nats.Connect(s.ClientURL())
|
||||
if err != nil {
|
||||
b.Fatalf("Failed to connect: %v", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
rng := rand.NewChaCha8([32]byte{42})
|
||||
message := make([]byte, bc.messageSize)
|
||||
var published, errors int
|
||||
|
||||
// Benchmark starts here
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
rng.Read(message)
|
||||
pubErr := nc.Publish(subject, message)
|
||||
if pubErr != nil {
|
||||
errors++
|
||||
} else {
|
||||
published++
|
||||
b.SetBytes(int64(bc.messageSize))
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark ends here
|
||||
b.StopTimer()
|
||||
|
||||
if published+errors != b.N {
|
||||
b.Fatalf("Something doesn't add up: %d + %d != %d", published, errors, b.N)
|
||||
} else if subErrors > 0 {
|
||||
b.Fatalf("Subscribers errors: %d", subErrors)
|
||||
}
|
||||
|
||||
b.ReportMetric(float64(errors)*100/float64(b.N), "%error")
|
||||
},
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user