The author | cao victory Apache Dubbo PMC
The stereotype of Dubbo as a high-performance Java RPC framework has long been deeply rooted in people’s minds. In terms of Cloud Native architecture selection, Spring Cloud may be the industry’s preferred choice. In fact, Dubbo has quietly evolved into Cloud Native infrastructure, not only inheriting the glory of the RPC era of the past, but also perfecting the lack of existing infrastructure. Since container and K8s appeared on the stage, it brought great challenges to the original RPC field. This article mainly describes the problems encountered in RPC field, and some thoughts on how RPC can embrace K8s.
K8s introduction
Kubernetes is an open source application for managing containerized applications on multiple hosts in the cloud platform. The goal of Kubernetes is to make deployment containerized applications simple and efficient. Kubernetes provides a mechanism for application deployment, planning, updating, and maintenance. Kubernetes is K8s for short.
In Kubernetes, the smallest management element is not individual containers, but pods. The Pod lifecycle requires the following considerations:
- Containers and applications can be killed at any time;
- Pod Ip and hostname may change (unless customized using StatefulSet);
- A file written to a local disk may disappear, and a storage volume is required if it is not invalidated.
The relationship between application container and Pod
- Applications are deployed in containers. Generally, an application is deployed in only one container.
- A Pod can contain one or more containers. It is generally recommended to deploy only one container per Pod. Except in the following scenarios:
- Side car;
- A container runs with another container locally. For example, one container is responsible for downloading data, and another container is responsible for providing services.
Service
If some Pods provide some functionality for other Pods to use, how is it implemented in a Kubernete cluster to keep track of these endpoints? Answer: Service.
Kubernete Service is a policy abstraction that defines a set of pods that are marked by the Service, typically via label Selector. Service abstracts access to a Pod.
The default Service gets A Record from A cluster IP address. Sometimes, however, you need to return a list of all Pod IP addresses that meet the criteria, and you can use Headless Services directly.
Reference: kubernetes. IO /
Recommended book: Kubernetes in Action
Introduction and analysis of RPC
With the popularity of microservices, there are enough mature solutions for communication between applications.
- Dubbo became open source in 2011 and has been adopted by a large number of small and medium-sized companies;
- After the launch of Spring Boot, Spring gradually showed a second Spring, and then Spring Cloud came out and gradually occupied the market. In the Chinese market, it fought against Dubbo Chamber.
- GRPC is an end-to-end communication tool based on Http2 launched by Google, and gradually occupies a dominant position in the K8s market, such as ETCD, Istio, etc., all use gRPC as a communication tool;
- Service Mesh was conceptually hot from the beginning and is now maturing.
- Istio + other Sidecars gradually begin to take the stage.
App Developer perspective
From the functional level, the functions that are perceived to the developer are:
- The service implementation
- Service exposure (annotation or configuration)
- Service invocation (annotations or configuration)
- Service governance, etc.
From the perspective of selection, the following points will be paid attention to:
- Ease of use (development ease and out of the box)
- performance
- function
- extensibility
Framework Developer perspective
Key processes:
- Services available
- The service registry
- Service discovery
- The service call
- Service governance
Key points:
- serialization
- Network communication
- Service routing
- Load balancing
- Service current limiting
- fusing
- Service governance such as downgrade
Mainstream technology implementation
Dubbo / HSF
- Dubbo provides interface – oriented remote method invocation. Application developers define interfaces, write services and expose them;
- The Client invokes through an interface.
- The dimension of Dubbo registration service is the interface dimension, each interface will write a piece of data in the registry;
- Dubbo supports conditional routing, script routing, Tag routing, and more. These routing rules are strongly IP address-dependent.
Note: Most of the mechanisms of Dubbo and HSF are similar, so Dubbo is discussed below as a solution.
SpringCloud
Spring Cloud makes network calls through Rest. Application developers can write their own exposed Rest services, such as springmvc.
The service registry in The Spring Cloud is an application dimension (Eureka), where the Client and Server communicate by convention.
Spring Cloud provides a standard API, of which Netflix is the best. The implementation of this API makes it possible for most developers to rely on And use Netflix directly. So Netflix provides the core of Spring Cloud. But as a commercial company, the commitment to open source is often variable, as Eureka has maintained.
gRPC
GRPC is an RPC framework designed based on HTTP/2 protocol, which uses Protobuf as IDL. GRPC as an end – to – end communication scheme can solve the present multi – language problem.
GRPC itself does not provide service registration and service governance functions. But now gRpc has ambitions to expand in this direction.
K8s
There is no fair communication framework in K8s system, gRPC is generally recommended as RPC framework.
By default, the IP address of a Pod is changed, so there are several ways to communicate with a Pod:
- Service+DNS: Create a Service, which can be selected to a list of PODS by label. This Service corresponds to a constant cluster IP address. The Client accesses the cluster IP address through DNS or directly. This cluster IP address is equivalent to implementing load balancing (IPtable mode).
- Headless Service: The difference between a Headless service and the preceding services is that it does not provide cluster IP addresses. Instead, it obtains a list of IP addresses in the form of a host name. The Client decides which Pod to access.
Istio + Envoy
Istio’s control layer requests and listens for POD information, service information and other information from K8s Api Server. In this way, Istio has complete information about pods, services, and so on in the K8s cluster. If information changes in the K8s cluster, Istio can also be notified and updated.
Envoy is one of the most common implementations of proxies, described briefly in terms of envoys. Envoy dynamically finds resources by querying files or managing servers. The corresponding discovery service and its corresponding Api are called xDS. The protocol includes LDS, RDS, CDS and so on.
References:
Introduction to Service Mesh: www.infoq.cn/article/pat… Istio routing rules: istio. IO /docs/ Tasks /…
Note: The above knowledge is obtained through consulting materials (Istio official website) and communicating with Service Mesh students in the group. If you have any questions, please point out.
summary
Problems and challenges encountered
Symbiosis between Spring Cloud and Dubbo
Dubbo is based on TCP communication by default, while Spring Cloud is largely based on Rest requests. In the process of alibaba Cloud commercialization, it was found that a large number of companies needed Spring Cloud applications to communicate with Dubbo, and the community mainly relied on adding a layer of gateway on Dubbo to solve the problem.
Is there a solution for uniform service registry discovery, as well as service invocation?
Basic theories can be referred to:
Yq.aliyun.com/articles/58…
Dubbo’s challenge in the K8s scenario
The IP of Pod under K8s is variable (default) and Dubbo’s service governance is highly dependent on IP.
Service registration of K8s is completed through Pod definition. Service discovery is actually the process of finding Pod. Pod has some correspondence with the application and does not match the service registration discovery model of the interface dimension in Dubbo.
Dubbo living space in the Service Mesh scenario
Dubbo needs to be tailored. Most functions of Dubbo can be performed by sidecar (Proxy).
If your company is already deploying an RPC framework, is there a good transition plan for implementing Service Mesh?
Problem of comb
The service definition
How do you define a service? You need to look at defining services from an application developer’s perspective.
The service responds to a function in the functional dimension, such as querying details of purchased orders. In Dubbo, corresponding to a method under an interface; Spring Cloud and gRPC correspond to an HTTP request.
From a function-oriented programming perspective, a service is a function. In the Java language, class is the foundation of all programming, so aggregating certain services along certain dimensions into an interface creates an interface that contains many services.
Dubbo is interface oriented programming for remote communication, so Dubbo is service oriented programming. If you want to call a service, you have to introduce it through the interface, and then call a service in the interface. The service query capability provided in Dubbo Ops does not actually query individual services, but rather obtains specific methods (services) by querying interfaces (service sets).
In the world of Spring Cloud, the service provider will register its application information (Ip+port) as an instance of the application, and the service consumer and service provider will make Rest requests in the form of convention. Each request corresponds to a service.
And Service in K8s
Service in K8s corresponds to a pod+port list, which is closely related to DNS. In plain English: Maintains a relational mapping of pod collections. And the service mentioned above are two concepts that belong to different scenarios.
By defining services in this way, the granularity of service governance is actually service granularity, with timeouts set for each service, routing rules set, and so on. But what does the granularity of service registration have to do with services?
Service registration Granularity
One application contains many interfaces, and one interface contains many services (Dubbo); Or an application that includes many services (Spring Cloud). Analyze the advantages and disadvantages of application dimension registration and interface dimension registration. There will be a separate article explaining the solution for applying dimension registration.
Interface dimension registration
Advantages:
- Service query according to the interface dimension query is very convenient, low difficulty;
- When the application is split or merged, the Client (consumer) does not care, so the user does not feel.
Disadvantages:
- The model correspondence with K8s and other mainstream platforms does not match;
- The amount of registered data is very large and has certain performance risks.
Application of dimension
Advantages:
- Consistent with K8s, Spring Cloud and other models;
- Performance can be greatly alleviated.
Disadvantages:
- When an application is split or merged, the Client needs to be aware of it (if not, the framework developer needs to maintain a store of interfaces and application mappings).
- If you want to keep the original Dubbo interface dimension query for users, it needs more work to ensure;
- There is less transparency for users and some additional tools need to be provided on OPS. For example, the provider developer can see if a particular IP provides a service, and so on.
Dubbo and Spring Cloud
Goal:
- Dubbo and Spring Cloud service discovery unification;
- Dubbo and Spring Cloud can call each other.
Service discovery unification
Dubbo transforms service registries into application dimensions. (The details will not be expanded, as explained in the following article)
To call
In the Dubbo implementation, support will be exposed as Rest protocols and recognized by Spring Cloud.
Dubbo + K8s
As explained in K8s, the following also assumes that an application is deployed in a container and a container is deployed in a POD.
The discussion of the following schemes is actually related to each other. For example, service governance may affect the discovery of service registration, and service query cannot depend on the content of service registration. The whole design process is a process of continuous optimization. Dubbo is an example of what is said below.
Service governance
In the original system of Dubbo, service governance is strongly dependent on IP. When a set of service governance rules are configured, they are based on one or more IP addresses.
After going to K8s system, it is important to consider that Pod IP is not fixed. Therefore, the current routing rules cannot meet the requirements and generate a lot of rule garbage data. In K8s system, Pod is searched through service based on label selector. Managing pods through Deployment is also based on Pod label selectors. So pod label selector is a fairly common solution in K8s exercises.
For example, a new routing rule, label routing, needs to be supported. After matching certain conditions, locate the result to the Pod list queried by label selector instead of the original IP list.
To support label routing, the client needs to obtain its own Pod Label information and the label information of each Pod in the Server Pod list.
Applies how to get information about the current Pod
-
Pod defines environment variables and applies them to fetch; Dubbo supports reading environment variables. Pod information needs to be set according to environment variables defined by Dubbo.
-
Delivers Pod information through THE PROGRAM API; Dubbo needs to provide the line of Downward reading, and the CORRESPONDING configuration of Downward customization is required in THE Pod.
-
Get data through API Server; The most powerful way, but the application needs to be strongly dependent on the API Server.
Apply how to get information from other pods
-
By calling the services of other pods; Dependent applications can obtain their own Pod information and expose their Pod information as services (REST or DuBBO protocols). The client obtains complete information about the corresponding Pod by calling the corresponding Pod.
-
Get data through Api Server; Powerful, but with increased dependency on Api Server.
Service registration and discovery
In the K8s system, RPC services can be discovered in the following ways:
-
Registration mechanism: IP is written to the registry, using heartbeat to maintain the connection; When the heartbeat stops, it is removed from the registry.
-
Use Service+DNS: create a Service that can be selected to a list of PODS by label. This Service corresponds to a constant cluster IP address. The Client accesses the cluster IP address through DNS or directly. This cluster IP address is equivalent to implementing load balancing (IPtable mode).
-
Using headless Service (DNS) : The difference between headless service and the preceding service is that it does not provide cluster IP, but obtains a list of IP addresses in the form of a host name. The Client decides which Pod to access.
-
API Server: The Client requests the API Server directly and gets the pod list. The Client decides to access the POD logic. At the same time, add watch when obtaining, API Server will synchronize the change information of POD to Client.
By getting the IP address or host of the Server, the Client can initiate HTTP or other protocol requests.
The following are possible solutions for Dubbo:
1. Dubbo + Zookeeper pod cluster (HSF+CS cluster)
This is the easiest way and the Dubbo itself does not require any modifications. The problem is that the maintenance of Zookeeper is increased, and this solution is not cloud native, and has nothing to do with K8s system.
Brain storm
ZooKeeper is used as the registry. Can we use service in K8s as the registry? Set up a service for each interface in Dubbo, update the Endpoint information during the startup of each application instance, and set up the relationship between Service-> Endpoint-> IP list.
In this scheme, the definition of K8s Service is modified, and too many services are defined. Service maintenance and management is a difficult problem.
K8s-based scenario
In the traditional RPC world, services are divided into service registry and service discovery. In the field of K8s, THE relationship between POD and application is one-to-one. K8s itself provides POD search capability, so to some extent, service registration actually does not exist, but only service discovery is needed. But this actually requires a premise:
Dubbo needs to transform the granularity of service registry discovery into an application dimension. > At the o&M level, write app= XXX (application name) to the POD label.
2. Dubbo + K8s DNS
If the K8s service provides the cluster IP, Dubbo only calls the cluster IP, leaving the routing and load balancing logic to K8s proxies. This reduces Dubbo’s core capabilities. Next we discuss the capabilities provided by the Headless Service.
By request.. svc.. IN A request is sent to obtain the IP address list, but polling is required to obtain the updated IP address list.
Service governance related functions need to be supported independently in the service governance section above.
Reference: github.com/kubernetes/…
3. Dubbo + Api Server
For Dubbo applications deployed in Pod containers, the service registration process can be directly deleted. The service discovery function obtains Pod and Service information through interaction with Api Server, and meanwhile watches changes of Pod and Service. In this way, service governance-related information can also be accessed directly through Api Server.
4. Dubbo + Istio + Envoy
Dubbo can directly invoke the same POD Envoy (or possibly the same Node Envoy) by specifying an IP + port. Dubbo handed functions such as routing rules, load balancing and circuit breakers to Istio and Envoy. Envoy needs to support the Dubbo protocol for forwarding.
So Dubbo needs to do two things: local IP direct connection (existing) and redundant feature tailoring (not yet implemented).
5. Dubbo + Istio
- Dubbo applications no longer rely on Envoy as sidecar, but interact directly with Istio as a registry, as a configuration center for service governance;
- Dubbo needs to provide a similar xDS protocol to convert service instance into Dubbo’s protocol format in pilot.
- Dubbo also needs to accommodate istio features such as health checks and security-related logic. For specific implementations, see Envoy’s implementation.
6. Coexistence of Dubbo and Istio in THE K8s system there are many alternatives. I offer two ideas for you to consider:
-
All service registration is done through the K8S mechanism and all service discovery is done through the Headless Service. When creating a SIDecar, update the original K8s service.
-
Nacos acts as a registry for Dubbo and requires partial transfer of data in K8s. Dubbo application, register service with Nacos in application dimension, Istio Pilot needs to identify Nacos data; The operation mechanism of Istio is basically unchanged. Data of K8s service instance needs to be written to NACOS for Dubbo to call.
7. Coexistence of on-cloud and off-cloud environments & On-cloud multi-cluster environments
Istio provides cross-cluster and on-cloud cloud-to-cloud solutions, and kubeFed can also play a role as a cross-cluster solution for K8s.
The complexity of this topic is higher, I have some answers in mind, I hope you can also think about it through the above.
Service query
Here are three ways to think about it.
Dubbo’s original way
Dubbo’s original service queries are queries for interfaces, each with a version number and group. The interface name + version number + group identifies a unique service set with corresponding service providers and service consumers (interface-level dependencies). The service provider is an IP +port list, and the service consumer is also an IP +port list.
As an application level service registration or direct use of K8s’s Pod discovery mechanism, some modifications need to be made, which, as mentioned above, will be explained separately in another article.
Only application queries are supported
Similar to Spring Cloud, application dimension queries are supported. After an application is queried, the IP and port list is displayed under application details. Each IP and port is an application instance. Click open an application instance to view detailed information about each application, including the services provided by the instance.
Interface + Application Query balancing
A step is added to support application query. The list of applications corresponding to an interface is supported. Most interfaces belong to only one application.
Click on the specific application under the app list, and you’ll jump to the app details.
conclusion
The above is an open source solution, so there is relatively little historical baggage. Support for large companies that want to switch from RPC to cloud native requires more compatibility and performance considerations, and more cost.
The cloud native trend is overwhelming, and it’s too early to tell which solution will ultimately win out in RPC. I believe both Service Mesh and traditional RPC (Dubbo/ gRPC) will have their place. Time will tell.
“Alibaba cloudnative wechat public account (ID: Alicloudnative) focuses on micro Service, Serverless, container, Service Mesh and other technical fields, focuses on cloudnative popular technology trends, large-scale implementation of cloudnative practice, and becomes the technical public account that most understands cloudnative developers.”