Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
November 13, 2022 07:51 am GMT

Interpretation of Open Source Go HTTP Framework | Service Registration Extension Implementation

Foreword

During the development iterations of the Hertz framework, I became more and more familiar with Hertz's main library. In the next few articles, I will analyze Hertz's service registration, service discovery and load balancing expansion respectively, and finally use the etcd expansion adapted to Hertz for actual combat. Welcome everyone to pay attention.

Hertz

Hertz is an ultra-large-scale enterprise-level microservice HTTP framework, featuring high ease of use, easy expansion, and low latency etc.

Hertz uses the self-developed high-performance network library Netpoll by default. In some special scenarios, Hertz has certain advantages in QPS and latency compared to go net.

In internal practice, some typical services, such as services with a high proportion of frameworks, gateways and other services, after migrating Hertz, compared to the Gin framework, the resource usage is significantly reduced, CPU usage is reduced by 30%-60% with the size of the traffic.

For more details, see cloudwego/hertz.

Service registration extension

Hertz supports custom registration modules. Users can extend and integrate other registries by themselves. The extension is defined under pkg/app/server/registry.

Extended interface and Info

Service registration interface definition and implementation

The interface definition of service registration is similar to the interface definition of implementing service registration and the implementation of most service registrations. It contains two methods, one for service registration and the other for service deregistration.

// Registry is extension interface of service registry.type Registry interface {        Register(info *Info) error        Deregister(info *Info) error}

These two methods are implemented in subsequent code in register.go.

// NoopRegistrytype noopRegistry struct{}func (e noopRegistry) Register(*Info) error {        return nil}func (e noopRegistry) Deregister(*Info) error {        return nil}

An empty Registry implementation is also provided in register.go, the default for service registration in the Hertz configuration.

// NoopRegistry is an empty implement of Registryvar NoopRegistry Registry = &noopRegistry{}

It is also the default value for service registration in Hertz configuration.

func NewOptions(opts []Option) *Options {    options := &Options{        // ...        Registry: registry.NoopRegistry,    }    options.Apply(opts)    return options}

Registration Info

The definition of registration information is provided in registry.go. When using WithRegistry for configuration service registration, the registration information will be initialized and passed to the Register method for subsequent logic execution. These fields are only suggestions, and the exact usage depends on your design.

// Info is used for registry.// The fields are just suggested, which is used depends on design.type Info struct {        // ServiceName will be set in hertz by default        ServiceName string        // Addr will be set in hertz by default        Addr net.Addr        // Weight will be set in hertz by default        Weight int        // extend other infos with Tags.        Tags map[string]string}

Timing of service registration

We run initOnRunHooks every time the Spin method is called, and initOnRunHooks contains the timing of our service registration.

func (h *Hertz) initOnRunHooks(errChan chan error) {        // add register func to runHooks        opt := h.GetOptions()        h.OnRun = append(h.OnRun, func(ctx context.Context) error {                go func() {                        // delay register 1s                        time.Sleep(1 * time.Second)                        if err := opt.Registry.Register(opt.RegistryInfo); err != nil {                                hlog.SystemLogger().Errorf("Register error=%v", err)                                // pass err to errChan                                errChan <- err                        }                }()                return nil        })}

When calling initOnRunHooks, we will add the anonymous function registered by the service to runHooks. In this function, we first start a goroutine. Here we will delay one second through time.Sleep. When asynchronous registration, the service will not necessarily start, so there will be a delay of one second to wait for the service to start. After this call Register and pass in the Info from the configuration. If there is an error during registration, pass the error to errChan.

Timing of service deregistration

When receiving a signal that the program exits, Hertz will perform a graceful exit and call the Shutdown method, in which the service will be unregistered. First execute executeOnShutdownHooks concurrently and wait for them until the wait times out or finishes execution. Then it will check whether there is a registered service, and if so, call Deregister to deregister the service.

func (engine *Engine) Shutdown(ctx context.Context) (err error) {   if atomic.LoadUint32(&engine.status) != statusRunning {      return errStatusNotRunning   }   if !atomic.CompareAndSwapUint32(&engine.status, statusRunning, statusShutdown) {      return   }   ch := make(chan struct{})   // trigger hooks if any   go engine.executeOnShutdownHooks(ctx, ch)   defer func() {      // ensure that the hook is executed until wait timeout or finish      select {      case <-ctx.Done():         hlog.SystemLogger().Infof("Execute OnShutdownHooks timeout: error=%v", ctx.Err())         return      case <-ch:         hlog.SystemLogger().Info("Execute OnShutdownHooks finish")         return      }   }()   if opt := engine.options; opt != nil && opt.Registry != nil {      if err = opt.Registry.Deregister(opt.RegistryInfo); err != nil {         hlog.SystemLogger().Errorf("Deregister error=%v", err)         return err      }   }   // call transport shutdown   if err := engine.transport.Shutdown(ctx); err != ctx.Err() {      return err   }   return}

Summary

In this article we learned about Hertz's implementation of highly customizable service registry extensions, and analyzed how Hertz integrates it into the core of the framework.

Finally, if the article is helpful to you, please like and share, thank you!

Reference


Original Link: https://dev.to/llance_24/interpretation-of-open-source-go-http-framework-service-registration-extension-implementation-1j1i

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To