background
In 2021, our company will focus on the stability of production. In the early stage, deobject community service was a single application built by PHP language, supporting millions of daily users. With the rapid development, the performance and business have gradually failed to meet the future needs and planning. In the first stage, the community and architecture team provided PHP + YAF, Java + Spring Cloud, Go + GRPC + K8S technology selection scheme, considering the service performance and migration cost, The final selection of Go + GRPC + K8S as the first choice of this project sets a milestone for the construction of community microservices.
Along with the development of the business, the stability of demand is higher and higher, in order to enhance the autonomy of business service ability, improve the stability of the cluster and controllability, access and the lowest cost is considered, at the same time considering community and trading system (Dubbo technology stack) have extensive relationship, eventually hope to be able to complete two cluster system easily, Therefore, the application layer framework dubo-Go is selected to implement the registration and discovery of Golang service.
Golang micro-service architecture, you may be familiar with Go Micro and Go Kit (and Gizmo). Indeed, Go Micro has more than 18K GitHub stars, but there is no choice here, mainly because Go Micro provides a lot of functions. Out of the box, but flexibility is limited; Go Kit is popular, but we are not relaunching The Golang service. The application layer framework is too restrictive, and the cost of code migration will be very high. Considering the above difficulties, dubbo-Go was eventually chosen while still in its formative years.
Dubbo – go
Dubbo Eco-Go is one of the most popular projects of Dubbo multi-language ecology. It has joined the Apache Foundation with Dubbo Eco-Go. Up to now, it has been used by many first and second-tier Internet companies (Dingding, Ctrip, Doodle, Kaikaiba, etc.). Have a fast version iteration speed that fits the requirements of the development.Graph one *
Dubbo-go main project, mainly based on Dubbo layered code design, the above is dubbo-Go code layer, basically the same as the Java version of Dubbo existing layer, so Dubbo-Go also inherited some of the best features of Dubbo. Such as clean code architecture, easy to extend, complete service governance capabilities.
Currently has achieved Dubbo Dubbo – go commonly used functions (such as pob, cluster strategy, service version, service registry agreement release, generalization calls, service drop fuse, etc.), including the service registry found already supported zookeeper/etcd/consul/nacos mainstream registry. I won’t go into details here.
Plan implementation
According to the background of existing projects using gRPC as service invocation, considering the degree of intrusion into business code and the compatibility with the normal use of the original scheme, the two sets of gRPC implementation can be switched freely, so as to achieve the real-time and controllable switching of Rpc governance framework in production environment and reduce the risk of production environment. Therefore, dubbo-Go itself supports gRPC protocol to meet the above requirements. The registry is selected as Nacos, which is consistent with the existing middleware and meets the requirements of some configuration items.Figure 2 *
Here, we need to think about two issues first. One is how to integrate Dubbo-Go with the original gRPC scheme and keep the two schemes supporting online production at the same time. The second is how to achieve real-time switching between the two SETS of GRPCS.
compatibility
GRPC is an open-source RPC framework designed for mobile and HTTP/2. The content exchange format uses ProtoBuf(Google Protocol Buffers), which has been open source for a long time. Provides a flexible, efficient, automatic serialization structure data mechanism, function and XML, Json similar, but the use of binary, (anti) serialization speed, high compression efficiency, transmission protocol using HTTP2, performance than HTTP1.1 improved a lot.
According to the gRPC features, gRPC has solved the problems of coDEC and Transport. Combining the figure, from the cluster layer up, there is no gRPC related area. It can be seen from Figure 1 that gRPC related adaptation needs to be done. The protocol layer is most appropriate. We can extend a gRPCProtocol like DubboProtocol. This gRPCProtocol is basically an Adapter. Combine the underlying gRPC implementation with our own Dubo-Go.FIG. 3 *
Based on the above, Dubbo-Go helped us solve the gRPC integration, essentially wrapping the Dubbo-Go governance layer on top of gRPC. We started with the ProtoBuf modification of gRPC. Dubbo-go official defines the protobuf custom logic code used by Dubbo-Go gRPC based on the Google Protobuf extension.
// HelloWorldServiceClientImpl is the client API for HelloWorldService service.
type HelloWorldServiceClientImpl struct {
SayHello func(ctx context.Context, in *SayHelloReq, out *SayHelloResp) error
/ /...
}
// service Reference
func (c *HelloWorldServiceClientImpl) Reference(a) string {
return "helloWorldServiceImpl"
}
// GetDubboStub
func (c *HelloWorldServiceClientImpl) GetDubboStub(cc *grpc.ClientConn) HelloWorldServiceClient {
return NewHelloWorldServiceClient(cc)
}
// Server interface
type HelloWorldServiceProviderBase struct {
proxyImpl protocol.Invoker
}
// set invoker proxy
func (s *HelloWorldServiceProviderBase) SetProxyImpl(impl protocol.Invoker) {
s.proxyImpl = impl
}
// get invoker proxy
func (s *HelloWorldServiceProviderBase) GetProxyImpl(a) protocol.Invoker {
return s.proxyImpl
}
Copy the code
Real time switch
Real-time switch, at first is for the sake of environment and convenient in the pressure test of two sets of different implementation gRPC scheme can real-time switch do pressure test data collection, the late is holding the fear of the attitude of the production, in production just access Dubbo – will go in the Rpc framework support services, free switch switch, from stability, the selective switch measurement service stability state.
The access of this requirement also starts from the modification of gRPC’s ProtoBuf, and based on the implementation of Nacos configuration center, we encapsulate the original CLIENT call of gRPC and the client call of Dubbo-Go into a unified instantiation portal (referred to as ClinetDubbo). A concrete implementation of inheriting ClinetDubbo (generated by the unified script of protobuf extension plug-in) is added for all methods of clients. The implementation content is roughly to obtain two sets of gRPC clients in ClinetDubbo. At this time, the client opened by the configuration center is obtained through Nacos configuration. Use a specific gRPC link based on your judgment.FIG. 4 *
GRPC link on the left and Dubo-Go governance model link on the right
// ClientDubbo
type HelloWorldServiceClientDubbo struct {
GrpcClient HelloWorldServiceClient
DubboClient *HelloWorldServiceClientImpl
Open bool
Caller string
}
// Specific method implementation
func (c *HelloWorldServiceClientDubbo) SayHello(ctx context.Context, req *SayHelloReq, opts ... grpc.CallOption) (*SayHelloResp, error) {
serverName := c.DubboClient.Reference()
// Get the nacOS configuration source data
serverCfg := nacosCfg.GetServerCfg()
if! c.Open { c.Open = serverCfg.AllOpen } cfg := serverCfg.ServiceCfg// Determine the call link
if! c.Open && ! cfg[serverName].Open && (cfg[serverName].Consumers ==nil| |! cfg[serverName].Consumers[c.Caller]) && ! cfg[serverName].Method["SayHello"].Open &&
(cfg[serverName].Method["SayHello"].Consumer == nil| |! cfg[serverName].Method["SayHello"].Consumer[c.Caller]) {
// Original gRPC link
return c.GrpcClient.SayHello(ctx, req, opts...)
}
// Dubo-go governance link
out := new(SayHelloResp)
err := c.DubboClient.SayHello(ctx, req, out)
return out, err
}
Copy the code
Project integration
Here is an example of integrating the Dubo-Go framework based on an existing project structure:
provider
type HelloWorldService struct {
*pb.UnimplementedHelloWorldServiceServer
*pb.HelloWorldServiceClientImpl
*pb.HelloWorldServiceProviderBase
}
func NewHelloWorldService(a) *HelloWorldService {
return &HelloWorldService{
HelloWorldServiceProviderBase: &pb.HelloWorldServiceProviderBase{},
}
}
Copy the code
Add dubo-Go extension to provide service registration based on the original service.
consumer
/ / the original Grpc
var HelloWorldCli HelloWorldServiceClient
//Dubbo-go
var HelloWorldProvider = &HelloWorldServiceClientImpl{}
func GetHelloWorldCli(a) HelloWorldServiceClient {
if HelloWorldCli == nil {
HelloWorldCli = NewHelloWorldClient(grpc_client.GetGrpcClient(...))
}
return &HelloWorldServiceClientDubbo{
GrpcClient: HelloWorldCli,
DubboClient: HelloWorldProvider,
Caller: dubboCfg.Caller,
Open: false,}}Copy the code
Simple GetHelloWorldCli () encapsulates the client calls, this method returns the HelloWorldServiceClientDubbo structure method finally, Initiated the client calls to HelloWorldServiceClientDubbo implementation of specific methods, execute specific gRPC call link by its configuration items.
Main
func main(a) {
//provider
config.SetProviderService(rpc.NewHelloWorldService(), ...)
// Set up the service consumerconfig.SetConsumerService(api... ,...)./ / load dubbo
config.Load()
}
Copy the code
The above is the overall idea and scheme of community service integration Dubo-Go. We will find that the amount of code that needs to be changed in the existing project is very small, and there is no intrusion into the code of the business side.
summary
Dubo-go integration enhances the governance ability of gRPC invocation process of business services. Based on cluster, the fault-tolerant ability of service cluster is increased, and the configurable fault-tolerant ability of application services is realized. Complete and unify the whole link monitoring and service index monitoring alarm of original new and old architecture service of community service; It enhances the transparency and controllability of business partners to the services in the cluster, and provides more reference information for the overall link sorting after encountering problems.
Based on the overall ecology of Dubbo, it can easily support the communication between Golang and Java Rpc, and achieve cross-language Rpc calls.Figure 5 *
The last
Dubbo-go, as a micro-service framework, contains its own governance capabilities. How to integrate these capabilities with K8S?
K8S provides the pod/endpoint/ Service layer 3 resources. You can listen to the events of the POD /endpoint/ Service layer 3 resources to make reasonable processing to achieve the purpose of service governance. There is no need to introduce additional components. Get pod list through K8S Apiserver, just use ETCD’s service registration and service notification capabilities through Apiserver, other service governance capabilities continue to use Dubbo-Go, simple model, no additional modules need to be implemented, almost no changes to Dubbo.
Article | xiao ke
Pay attention to the object technology, hand in hand to the cloud of technology