How ASF Simplifies gRPC‑to‑Go Migration and Boosts Service Governance

This article explains the AutoHome Service Framework (ASF), its architecture, how it enables seamless migration from gRPC to Go services, the added Dubbo‑go support, configuration optimizations, advanced load‑balancing strategies, observability enhancements, and future plans for adaptive balancing and zero‑downtime deployments.

HomeTech
HomeTech
HomeTech
How ASF Simplifies gRPC‑to‑Go Migration and Boosts Service Governance

What is ASF

ASF (AutoHome Service Framework) is a micro‑service platform that provides service registration, discovery, governance, observability, and dynamic configuration for Java and Go applications. ASF 2.0 adds native Dubbo‑go support, unifying service governance for both languages.

Architecture Overview

The core functions are highlighted in the blue dashed box of the architecture diagram; upcoming features are shown in the green box.

Migration from gRPC to ASF‑go

ASF enables near‑zero‑change migration from a traditional gRPC server to an ASF‑go server. Business logic remains unchanged; only ASF configuration needs to be added.

const (
    port = ":50051"
)

type SpecialService struct {
    pb.UnimplementedSpecialServer
}

func (s *SpecialService) Call(ctx context.Context, req *pb.SpecialRequest) (reply *pb.SpecialReply, err error) {
    fmt.Printf("req: %v
", req)
    return &pb.SpecialReply{Message: "Hello ASF Go : " + port}, nil
}

func main() {
    lis, err := net.Listen("tcp", port)
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    protobuf.RegisterGreeterServer(s, &SpecialService{})
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

ASF‑go server requires the Dubbo‑go protobuf plugin:

go get -u github.com/apache/dubbo-go/protocol/grpc/[email protected]
func init() {
    config.SetProviderService(NewSpecialService())
}

type SpecialService struct {
    *pb.SpecialProviderBase
}

func NewSpecialService() *SpecialService {
    return &SpecialService{SpecialProviderBase: &pb.SpecialProviderBase{}}
}

func (s *SpecialService) Call(ctx context.Context, req *pb.SpecialRequest) (reply *pb.SpecialReply, err error) {
    fmt.Printf("req: %v
", req)
    return &pb.SpecialReply{Message: "Hello ASF Go : " + port}, nil
}
services:
  "specialProvider":
    version: 1
    group: "demo"
    protocol: "grpc"
    interface: "asf.smc.cloud.base.special"
    cluster: failover
    loadbalance: random

Dubbo‑go Configuration Optimization

Dubbo‑go 1.5.7 requires separate provider and consumer YAML files, which duplicates common settings. ASF introduces CompositeConfig to aggregate provider, consumer, services, and references into a single configuration object.

type CompositeConfig struct {
    ProviderConfig  *ProviderConfig  `yaml:"provider" json:"provider,omitempty" property:"provider"`
    ConsumerConfig  *ConsumerConfig  `yaml:"consumer" json:"consumer,omitempty" property:"consumer"`
    Services        map[string]*ServiceConfig   `yaml:"services" json:"services,omitempty" property:"services"`
    References      map[string]*ReferenceConfig `yaml:"references" json:"references,omitempty" property:"references"`
}

Configuration can be supplied via environment variables, command‑line flags, or a ConfigPostProcessor hook.

export CONF_PROVIDER_FILE_PATH="../profiles/dev/server.yml"
export CONF_CONSUMER_FILE_PATH="../profiles/dev/server.yml"
export APP_LOG_CONF_FILE="../profiles/dev/log.yml"
# Provider
go run . -proConf ../profiles/dev/server.yml -logConf ../profiles/dev/log.yml
# Consumer
go run . -conConf ../profiles/dev/client.yml -logConf ../profiles/dev/log.yml
config.LoadWithConfig(&common.AsfConfig{
    CompositeConf: "./asf-grpc/server/server.yml",
    Level: "debug",
})

Fluent API Bootstrap

providerExportedHook := config.NewProviderExportedHook(func(event observer.Event) {
    logger.Infof("provider exported %s", event.GetTimestamp().Format("2006-01-02 15:04:05"))
})

consumerReferencedHook := config.NewConsumerReferencedHook(func(event observer.Event) {
    logger.Infof("consumer referenced %s", event.GetTimestamp().Format("2006-01-02 15:04:05"))
})

bootstrap := config.NewAsfBootstarp().
    AddProviderExportedHook(providerExportedHook).
    AddConsumerReferencedHook(consumerReferencedHook).
    ConfigPath("./asf-grpc/server/server.yml").
    LoadConfig().
    DelayExport(true).
    Start()

Service Contract Alignment

ASF aligns Dubbo‑go metadata with Dubbo, enabling service query, mock, and testing capabilities via the console.

Service Governance

High‑Availability Registry

ASF uses Zookeeper as the registry and adopts a multi‑service + partition + learner deployment combined with Dubbo’s multiple‑registry mechanism to improve write throughput and cross‑region availability.

Zone‑Aware Load Balancing

Requests are preferentially routed to instances in the same Availability Zone (AZ). If the instance ratio of an AZ falls below 30 %, traffic is routed across the whole region to avoid avalanche failures.

Service Disable

The console allows manual disabling of overloaded instances, which can be re‑enabled once load normalizes.

Observability

ASF redesigns Dubbo‑go’s Prometheus metrics: it replaces Summary with a Histogram that has 72 buckets ranging from 1 ms to 60 s (based on Micrometer’s PercentileHistogramBuckets). Collected metrics include response time (RT), QPS, success/failure ratios, saturation, and TP99 latency.

Future Plans

Adaptive Load Balancing

Post‑cloud environments exhibit heterogeneous node performance. ASF plans to implement a Pick‑Two‑Random‑Choices (P2C) algorithm with EWMA‑based latency and availability metrics, avoiding herd effects and supporting automatic fault removal.

type NodeMetrics struct {
    active               int     // in‑flight requests
    cpuLoadAverage       float64 // CPU load
    weight               int     // static weight
    latency              float64 // EWMA latency
    availabilityPercent  float64 // EWMA success rate
}

Zero‑Downtime Deployment

By delaying service exposure until readiness probes succeed, ASF can achieve lossless rollouts without external QoS settings.

bootstrap := config.NewAsfBootstarp().
    AddProviderExportedHook(providerExportedHook).
    AddConsumerReferencedHook(consumerReferencedHook).
    ConfigPath("./asf-grpc/server/server.yml").
    LoadConfig().
    DelayExport(true).
    Start()

time.Sleep(time.Second * 5) // warm‑up
bootstrap.StartProvider() // expose service

ASF will continue collaborating with the Dubbo‑go community to become a stable, high‑performance micro‑service governance platform.

Architecture diagram
Architecture diagram
Service contract view
Service contract view
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

MicroservicesObservabilityload balancingConfigurationGodubbo-goservice governance
HomeTech
Written by

HomeTech

HomeTech tech sharing

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.