Skip to content

Releases: zeromicro/go-zero

v1.9.3

16 Nov 12:44
75941ae

Choose a tag to compare

We are excited to announce the release of go-zero v1.9.3! This release brings several important enhancements and bug fixes that improve the framework's reliability, performance, and alignment with industry best practices.

🎉 Highlights

  • Consistent Hash Load Balancing: New gRPC load balancer for session affinity
  • gRPC Best Practices: Changed NonBlock default to align with gRPC recommendations
  • Improved Distributed Tracing: Fixed gateway trace header propagation
  • ORM Improvements: Fixed zero value scanning for pointer destinations

✨ New Features

Consistent Hash Balancer Support (#5246)

Contributor: @zhoushuguang

A new consistent hash load balancer has been added to the zRPC package, enabling session affinity for gRPC services.

Key Features:

  • Hash-based request routing to maintain session affinity
  • Distributes requests based on a hash key from context
  • Minimal request redistribution on node changes
  • Built on go-zero's existing core/hash/ConsistentHash implementation

Usage Example:

// Set hash key in context
ctx := zrpc.SetHashKey(ctx, "user_123")

// Requests with the same key will be routed to the same backend
resp, err := client.SomeMethod(ctx, req)

Configuration:

c := zrpc.RpcClientConf{
    Endpoints: []string{"localhost:8080", "localhost:8081"},
    BalancerName: "consistent_hash",  // Use consistent hash balancer
}

Benefits:

  • Enables stateful service interactions
  • Improves cache hit rates on backend services
  • Reduces session data synchronization overhead
  • Maintains load distribution while supporting affinity

🐛 Bug Fixes

Fixed Gateway Trace Headers (#5256, #5248)

Contributor: @kevwan

Fixed an issue where OpenTelemetry trace propagation headers were not being properly forwarded through the gateway to upstream gRPC services, breaking distributed tracing.

Problem:
The gateway was not forwarding critical W3C Trace Context headers (traceparent, tracestate, baggage) to gRPC metadata, causing trace context to be lost at the gateway boundary.

Solution:

  • Enhanced ProcessHeaders function to forward trace propagation headers
  • Headers are now properly converted to lowercase per gRPC metadata conventions
  • Maintains distributed tracing across HTTP → gRPC boundaries

Impact:

  • End-to-end tracing now works correctly through the gateway
  • Improved observability for microservice architectures
  • Better debugging and performance analysis capabilities

Technical Details:

// Trace headers now properly forwarded
var traceHeaders = map[string]bool{
    "traceparent": true,  // W3C Trace Context
    "tracestate":  true,  // Additional trace state
    "baggage":     true,  // W3C Baggage propagation
}

Fixed Multiple Trace Initialization (#5244)

Contributor: @kevwan

Problem:
When running multiple services (e.g., REST + RPC) in the same process, the trace agent could be initialized multiple times, potentially causing resource leaks or unexpected behavior.

Solution:

  • Used sync.Once to ensure trace agent is initialized only once
  • Aligned with similar patterns used in prometheus.StartAgent and logx.SetUp
  • Added sync.OnceFunc for shutdown to prevent double cleanup

Code Changes:

var (
    once           sync.Once
    shutdownOnceFn = sync.OnceFunc(func() {
        if tp != nil {
            _ = tp.Shutdown(context.Background())
        }
    })
)

func StartAgent(c Config) {
    if c.Disabled {
        return
    }

    once.Do(func() {
        if err := startAgent(c); err != nil {
            logx.Error(err)
        }
    })
}

Benefits:

  • Prevents resource conflicts in multi-server processes
  • Ensures single global tracer provider instance
  • Safer concurrent initialization
  • Proper cleanup on shutdown

Fixed ORM Zero Value Scanning for Pointer Destinations (#5270)

Contributor: @lerity-yao (first contribution! 🎊)

Problem:
When scanning database results into struct fields with pointer types, zero values (0, false, empty string) were not being properly distinguished from NULL values. This caused nil pointers to be set to zero values incorrectly.

Solution:
Enhanced the getValueInterface function to properly initialize nil pointers before scanning, ensuring the SQL driver can correctly populate them with zero or non-zero values.

Code Changes:

func getValueInterface(value reflect.Value) (any, error) {
    if !value.CanAddr() || !value.Addr().CanInterface() {
        return nil, ErrNotReadableValue
    }

    // Initialize nil pointer before scanning
    if value.Kind() == reflect.Pointer && value.IsNil() {
        baseValueType := mapping.Deref(value.Type())
        value.Set(reflect.New(baseValueType))
    }

    return value.Addr().Interface(), nil
}

Impact:

type User struct {
    Name    string   `db:"name"`      // Always set
    Age     *int     `db:"age"`       // Can distinguish NULL vs 0
    Active  *bool    `db:"active"`    // Can distinguish NULL vs false
}

// Before: age=0 and age=NULL both resulted in nil pointer
// After:  age=0 → *int(0), age=NULL → nil pointer ✓

Benefits:

  • Correct handling of NULL vs zero values
  • Better semantic representation of optional fields
  • Prevents unexpected nil pointer dereferences
  • Aligns with Go's SQL scanning best practices

🔄 Breaking Changes (With Backward Compatibility)

Changed NonBlock Default to True (#5259)

Contributor: @kevwan

Motivation:
Aligned with gRPC official best practices which discourage blocking dials.

Change:

// zrpc/config.go
type RpcClientConf struct {
    // Before: NonBlock bool `json:",optional"`
    // After:
    NonBlock bool `json:",default=true"`  // Now defaults to true
}

Why This Matters:

  1. Blocking dials are deprecated: grpc.WithBlock() is an anti-pattern
  2. Connection state is dynamic: Being connected at dial time doesn't guarantee future connectivity
  3. RPCs handle waiting: All RPCs automatically wait until connection or deadline
  4. Simpler code: No need to check "ready" state before making calls

Migration Guide:

For most users, no action required - the new default is the recommended behavior.

If you explicitly need blocking behavior (not recommended):

// Option 1: Configuration
c := zrpc.RpcClientConf{
    NonBlock: false,  // Explicit blocking
}

// Option 2: Client option (deprecated)
client := zrpc.MustNewClient(c, zrpc.WithBlock())

Backward Compatibility:

  • Existing configs with NonBlock: false continue to work
  • New WithBlock() option available (marked deprecated)
  • No changes needed for services already using NonBlock: true

Documentation:
See GRPC_NONBLOCK_CHANGE.md for detailed migration guide and rationale.


👥 New Contributors

We're thrilled to welcome new contributors to the go-zero community! 🎉

Thank you for your contributions! We look forward to your continued involvement in the project.


📦 Installation & Upgrade

Install

go get -u github.com/zeromicro/[email protected]

Update

# Update go.mod
go get -u github.com/zeromicro/[email protected]
go mod tidy

🔗 Links


📝 Detailed Changes

Core Enhancements

Load Balancing

  • Added consistent hash balancer for gRPC (zrpc/internal/balancer/consistenthash)
  • Context-based hash key API: SetHashKey() and GetHashKey()
  • Configurable replica count and hash function
  • Comprehensive test coverage

Distributed Tracing

  • Fixed trace header propagation in gateway
  • Proper handling of W3C Trace Context headers
  • Case-insensitive header matching per gRPC conventions
  • Single initialization with sync.Once pattern

ORM/Database

  • Fixed pointer field scanning for zero values
  • Proper NULL vs zero value distinction
  • Enhanced getValueInterface() with nil pointer initialization
  • Support for sql.Null* types

gRPC Client

  • Changed NonBlock default to true
  • Added deprecated WithBlock() option for compatibility
  • Explicit handling of both blocking and non-blocking modes
  • Updated client initialization logic

Testing & Quality

  • Added comprehensive test coverage for all changes
  • Edge case handling in ORM tests
  • Gateway trace header test cases
  • Consistent hash balancer benchmarks

🙏 Acknowledgments

Special thanks to all contributors, issue reporters, and community members who made this release possible. Your feedback and contributions continue to make go-zero better!


💬 Feedback

If you encounter any issues or have suggestions for future releases, please:

Happy coding with go-zero! 🚀

goctl/v1.9.2

12 Oct 05:33
80c320b

Choose a tag to compare

What's Changed

  • Swagger Improvements:

    • Fix swagger path generation: remove trailing slash for root routes with prefix #5212 (@Copilot)
    • Fix swagger generation: info block and server tags not included #5215 (@Copilot)
    • Restore API summaries in swagger generation #5237 (@kevwan)
  • Other Fixes:

New Contributors


Full Changelog: tools/goctl/v1.9.1...tools/goctl/v1.9.2

v1.9.2

11 Oct 08:36
bbe5bbb

Choose a tag to compare

Overview

This release is solely focused on addressing a critical problem related to the go-redis dependency. Previous versions of go-redis were retracted, which could cause build failures, dependency resolution issues, or unexpected behavior for downstream projects relying on stable releases.

What's Fixed

  • go-redis Version Issue: The only change in this release is updating go-redis to circumvent the retracted versions. This ensures that consumers of this library can continue to build and use it reliably without encountering problems from retracted dependencies.
    • Chore: update go-redis for the retracted versions (#5235) by @kevwan

Impact

  • No Functional Changes: There are no new features, bug fixes, or breaking changes in this release. Functionality remains the same as the previous version.
  • Dependency Stability: Users should upgrade to this release if they are experiencing issues related to go-redis retractions or want to ensure their dependency tree remains stable.

New Contributors

While this release only addresses the go-redis issue, we'd like to acknowledge recent first-time contributors to the project:

Changelog

For a full list of changes between v1.9.1 and v1.9.2, see the changelog.


Upgrade Recommendation:
If you depend on redis, it is strongly recommended to upgrade to this release to avoid issues caused by the retracted versions.

v1.9.1

02 Oct 14:34
ce6d0e3

Choose a tag to compare

Highlights

  • Logging enhancements:
    • Customize log key names to fit your log schema and downstream tooling.
    • Prefer json.Marshaler over fmt.Stringer when emitting JSON logs, improving correctness and structure.
  • REST/SSE stability and operability:
    • Fix SSE handler blocking and reduce noisy logs by downgrading SetWriteDeadline errors to debug.
    • Add SetSSESlowThreshold to help detect slow clients and long writes.
  • Diagnostics and performance:
    • Improved mapreduce panic stacktraces for faster root-cause analysis.
    • Optimized machine performance data reading to reduce runtime overhead.

Detailed Changes

Logging

  • Support customizing log keys so you can align emitted fields (e.g., time, level, caller, message) to your organization’s conventions or ingestion pipeline requirements.
    PR: feat: support customize of log keys by @WqyJh (@5103)
  • Prefer json.Marshaler over fmt.Stringer when generating JSON logs, ensuring structured fields are serialized using their explicit JSON representations rather than ad-hoc strings.
    PR: feat: prefer json.Marshaler over fmt.Stringer for JSON log output by @WqyJh (@5117)

REST/SSE

  • Fix SSE handler blocking behavior that could stall responses under certain conditions.
    PR: fix: SSE handler blocking by @wuqinqiang (@5181)
  • Reduce log noise for transient I/O conditions by downgrading SetWriteDeadline errors to debug level in REST SSE.
    PR: fix(rest): change SSE SetWriteDeadline error log to debug level by @wuqinqiang (@5162)
  • Add sseSlowThreshold to surface slow SSE writes, enabling better observability about backpressure or slow clients.
    PR: feat(handler): add sseSlowThreshold by @wuqinqiang (@5196)

MapReduce

  • Improve panic stacktrace reporting in mapreduce, making error contexts clearer and debugging faster.
    PR: optimize: mapreduce panic stacktrace by @kevwan (@5168)

Performance and Runtime

  • Optimize machine performance data reading to lower collection overhead and reduce runtime impact.
    PR: opt: optimization of machine performance data reading by @wanwusangzhi (@5174)

Bug Fixes

  • Fix gRPC → HTTP mapping issue in gateway.
    PR: fix: issue-5110 by @guonaihong (@5113)

Migration and Usage Notes

  • Logging key customization:
    • If you rely on specific field names in log pipelines, consider setting the new custom key configuration to preserve schema consistency.
  • JSON log output:
    • If your types implement json.Marshaler, expect more accurate JSON in logs. If you previously depended on stringified representations, review downstream consumers to ensure compatibility.
  • SSE tuning:
    • Consider using SetSSESlowThreshold to flag slow clients or network conditions in environments sensitive to latency.
    • The SetWriteDeadline log level change reduces noise; adjust logger settings if you still want to surface these events.

Acknowledgements

Full Changelog

goctl/v1.9.1

02 Oct 14:53
60128c2

Choose a tag to compare

Highlights

  • Code generation ergonomics:
    • Add code generation headers to safe-to-edit files for clearer ownership and customization boundaries.
    • Fix array type generation issues to ensure accurate code output.
  • API developer experience:
    • Add complete test scaffolding for API projects via the --test flag.
  • Swagger/OpenAPI correctness:
    • Correct $ref placement in array definitions when useDefinitions is enabled.
  • Stability and optimizations:
    • Fix SSE handler blocking.
    • Optimize slice lookups and Unquote utility function performance.

Detailed Changes

Code Generation

  • Add code generation headers in safe-to-edit files to clarify which files are intended for user modifications while keeping generated segments intact.
    PR: feat: add code generation headers in safe to edit files by @kevwan (@5136)
  • Fix array type generation error to produce correct types in generated code.
    PR: fix array type generation error by @kesonan (@5142)

API/CLI

  • Add complete test scaffolding support for API projects using the --test flag, enabling quicker setup of testable services.
    PR: Add complete test scaffolding support with --test flag for API projects by @Copilot (@5176)

Swagger/OpenAPI

  • Fix $ref placement in array definitions when useDefinitions is enabled to align with the OpenAPI/Swagger schema expectations.
    PR: fix(goctl/swagger): correct $ref placement in array definitions when useDefinitions is enabled by @Copilot (@5199)

Stability

  • Fix SSE handler blocking behavior that could stall event delivery under certain conditions.
    PR: fix: SSE handler blocking by @wuqinqiang (@5181)

Performance and Utilities

  • Optimize slice find routines and the Unquote function for better runtime efficiency.
    PR: update: optimize slice find and Unquote func by @me-cs (@5108)

Upgrade Notes

  • Swagger regeneration: If you rely on useDefinitions, regenerate your Swagger/OpenAPI specs to pick up the corrected $ref placement.
  • Codegen headers: Newly generated safe-to-edit files will include headers clarifying edit expectations; no action required, but helpful for code review and maintenance.

Acknowledgements

  • Thanks to all contributors in this release: @kevwan, @kesonan, @me-cs, @wuqinqiang, and first-time contributor @Copilot. Your improvements enhance correctness, stability, and developer productivity for goctl users.

Full Changelog

goctl/v1.9.0

31 Aug 15:37
894e8b1

Choose a tag to compare

What's Changed

  • fear: add uuid:varchar to p2m by @hoshi200 in #5022
  • feat: support sse in api files by @kevwan in #5074
  • feat: supported sse generation by @kesonan in #5082
  • feat: Support projectPkg template variables in config, handler, logic, main, and svc template files by @geekeryy in #4939
  • feat: support goctl --module to set go module by @kevwan in #5135

New Contributors

Full Changelog: tools/goctl/v1.8.5...tools/goctl/v1.9.0

goctl/v1.9.0-alpha

17 Aug 15:20
20d20ef

Choose a tag to compare

What's Changed

New Contributors

Full Changelog: tools/goctl/v1.8.5...tools/goctl/v1.9.0-alpha

v1.9.0

17 Aug 04:02
a5d42e2

Choose a tag to compare

What's Changed

  • feat: support masking sensitive data in logx by @kevwan in #5003
  • feat: add field tag (-) skip logic in unwrapFields in sqlx by @charmfocus in #5010
  • feat: upgrade to mongo-driver v2, and move v1 to zero-contrib by @me-cs in #4687
  • feat: add generic Set with 2x performance boost and compile-time by @codeErrorSleep in #4888
  • feat: add custom middleware support with onion model in gateway by @DengY11 in #5035
  • feat: redis support consumer groups by @jk2K in #4912
  • feat: ignore unknown fields in gateway request parsing by @guonaihong in #5058
  • fix: issue with etcd key disappearing and unable to auto-re-register by @guonaihong in #4960
  • fix: SSE timeout will affected by http.Server's WriteTimeout by @csbzy in #5024
  • fix: unmarshal problem on env vars for type env string by @kevwan in #5037
  • fix: large memory usage on detail logging post requests by @kevwan in #5039
  • fix: Resolve HTML escaping issue during JSON serialization in httpx by @Disdjj in #5032
  • fix: resolve concurrent get may lead to empty result in ImmutableResource by @sunhao1296 in #5065
  • optimize: logging with fields by @kevwan in #5066

New Contributors

Detailed Release Notes: https://go-zero.dev/en/reference/releases/v1.9.0
Full Changelog: v1.8.5...v1.9.0

goctl/v1.8.5

13 Jul 13:32
12e03c8

Choose a tag to compare

What's Changed

  • Bug Fix: Fix for issue #4943 — fix goctl api swagger error (@kesonan)
  • Bug Fix: Fixed goctl api swagger panic with nil pointer when there is a wrong field tag in the API file (#4936)
  • Bug Fix: Resolved issue where timeout: 0s was not working in API files (#4932, @kevwan)
  • Bug Fix: Corrected PostgreSQL numeric type mapping in goctl model generation (#4992, @AnlynnLee)
  • Enhancement: Improved POST JSON parameter determination logic in goctl API Swagger and added unit tests (#4997, @Twilikiss)

New Contributors

Full Changelog: tools/goctl/v1.8.4...tools/goctl/v1.8.5

v1.8.5

12 Jul 16:21
c9ff6a1

Choose a tag to compare

Features

  • SQL Read/Write Splitting: Introduced SQL read/write splitting for improved database performance and scalability (#4976, #4990, #5000).
  • Serverless Support in REST: Added support for serverless use in REST services (#5001).

Bug Fixes & Improvements

  • Fixed HTTP SSE method timeout not working when timeout is set by server (#4932)
  • Fixed timeout 0s not working in API files (#4932)
  • Fixed panic caused by time.Duration type with numerical values (#4944)
  • Fixed duration type comparison in environment variable processing (#4979)

New Contributors

Full Changelog: v1.8.4...v1.8.5