This is the 12th day of my participation in the August Challenge

[toc] Dubbo official website address: dubbo.apache.org/zh-cn/index… . GitHub address: github.com/apache/dubb… The Dubbo story is longer, and there are examples of calls in the Demo, so the examples won’t be added, and I have some examples in my Gitee repository to refer to. Here is a summary of the latest version 2.7.7. In addition, about Dubbo, out for so many years, many people are more concerned about Dubbo dynamic proxy, the underlying Netty protocol and other issues. But I think it’s more important to focus on what Dubbo does and thinks about in the service invocation scenario than writing Dubbo by hand. This relationship is like the difference between architects and programmers. It’s not that architects write better code than programmers, but that architects can take into account various situations and combine them into systematic solutions to real problems.

Dubbo overview

Features on the official website:

  1. High-performance RPC invocation for interface proxy: Provides high-performance proxy-based remote invocation capabilities. Services are interface-granular and shield developers from the low-level details of remote invocation.
  2. Intelligent load balancing: Multiple load balancing policies are built in to intelligently sense the health status of downstream nodes, significantly reducing call delay and improving system throughput.
  3. Automatic service registration and discovery: Supports multiple registry services and real-time awareness of service instances.
  4. Highly extensible ability: follow the principle of the design of the micro kernel + plug-in, all core capabilities such as Protocol, Transport, Serialization is designed as extension points, equal treatment to internal and third parties.
  5. Traffic scheduling during the running period: Built-in routing policies such as conditions and scripts. By configuring different routing rules, functions such as grayscale distribution and priority in the same machine room can be easily realized.
  6. Visual service governance and O&M: Rich service governance and O&M tools are provided to query service metadata at any time. Service health status refers to invoking statistics, delivering routing policies in real time, and adjusting configuration parameters.

Registery is responsible for service discovery and registration, Provider registers service information to Registry, Consumer subscribes service information to Registry, Registry will timely push to Consumer. The Consumer then selects a Provider from the list of services and invokes the service.

Dubbo configuration mode

Dubbo’s services are configured in three ways: API, Spring-based XML, and Springboot-based Properties. All three methods of service configuration are implemented in the Demo project without further details. The thing to note here is the priority of the various configurations.

Relationship between the three configuration modes

Obviously, the API approach is no longer a servitization configuration approach, but a low-level implementation approach that shows how Dubbo’s core objects can be assembled into services. It is rarely used under normal circumstances, but can be used occasionally in environments outside of Spring, such as MapReduce, Spark, etc. The latter two kinds of configuration, in fact, the effect is equivalent. For example, dubbo.application.name=foo and
are equivalent, Dubo.registry. Address =nacos://localhost:8848 and
The two methods are equivalent. In fact, it is possible to specify dubbo’s service configuration XML in the SpringBoot project by introducing the @importResource annotation. What is the priority of a SpringBoot project that integrates the two configurations? The priority is {Java -d}>{XML}>{properties}. Also, if a project has multiple dubbo.properties(for example, multiple JARS with configuration files), Dubbo will randomly read a configuration file and throw an exception message. The official recommendation is also to use XML for configuration. In addition, there is another annotation-based Service declaration based on SpringCloud’s properties configuration, where @Service exposes the Service and @Reference invokes the Service, which is actually equivalent to XML configuration.

Configuration priorities of the server and the consumer

Many service properties, such as retris(retry times), timeout(timeout time), and loadBalance (load method), can be configured on both the service provider and the service consumer. In this case, the configuration of the service consumer takes precedence over that of the service provider. The configuration on the service provider side is equivalent to the default properties of the service, so it is recommended that as many of these properties be configured on the service provider side as possible. In addition, the official recommendation is to provide more detailed service configuration on the server side, such as providing detailed configuration for each method when configuring the service if possible. Such as:

<dubbo:protocol threads="200" /> 
<dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService"
    executes="200" >
    <dubbo:method name="findAllPerson" executes="50" />
</dubbo:service>
Copy the code

This specifies a thread pool of 200, whereas findAllPerson’s thread pool is 50.

Specifies the Cache File for Dubbo

The official recommendation is to specify file in Registry. For example,
. This Cache File can Cache service registration information so that the consumer can still make service calls after the registry stops serving. Because of the importance of this file, although it will be generated locally by default, the official recommendation is to specify the cache file separately, and be careful not to have multiple projects specify the same cache file, which can cause file write permissions to compete and service registration information to be overwritten. This CacheFile mechanism allows consumers to bypass the registry to access service providers, and if you want to prevent this, you can use Dubbo’s token authentication mechanism, which requires authorization authentication in the registry to access. You can specify the token attribute in provider or service:

<! -- Random token, generated using UUID -->
<dubbo:provider interface="com.foo.BarService" token="true" />
<! -- Fixed token, equivalent to password -->
<dubbo:provider interface="com.foo.BarService" token="123456" />
Copy the code

Some other interesting things

The official documentation explains many of Dubbo’s features in great detail, but here are some interesting ones. Others can refer to official documents.

Fault tolerance mechanism of service cluster

You can specify cluster fault tolerance in a service, such as <dubbo:service cluster=”failsafe” />

  • The default is Failover. In this mode, if an access error occurs (such as a timeout), the system automatically searches for another provider and initiates a retry. You can specify the number of retries by specifying retries, which does not include the first request. This is usually used for read operations, and for write operations, it is easy to cause service idempotent problems.
  • Failfast: Initiates only one service invocation and reports an error immediately if it fails. This comparison applies to write operations.
  • Failsafe: If the service invocation fails or an exception occurs, it is ignored. This comparison applies to operations that allow failure, such as logging.
  • Failback: The system automatically recovers faults. Failed requests are recorded in the background and retransmitted periodically. This comparison applies to message-driven scenarios.
  • Forking: Requests are made to multiple servers at the same time. If one of the service providers returns a success, the service invocation succeeds. This comparison applies to read operations that require high real-time performance. But obviously, this will waste more service resources. The parallel count can be configured using the fork attribute.
  • BroadCast: Sends requests to all service providers at the same time and reports each error. This is typically used to notify all servers of operations such as cache updates.

Local service stub with local masquerade local stub, local mock

1. Generally, the service consumer has only one interface, and the invocation of the service is entirely dependent on the service provider. Sometimes, however, the service provider wants to do some local operations on the service consumer, such as ThreadLocal caching, parameter checking, and returning Mock data after a failed call. This way, things that need to be done on the consumer side with Hystrix in SpringCloud can be handled directly on the server side with the local service stub, allowing the consumer to further ignore the service invocation details. For example, perform the following configuration on the service provider:

<dubbo:service interface="com.foo.BarService" stub="true" /> or
<dubbo:service interface="com.foo.BarService" stub="com.foo.BarServiceStub" />
Copy the code

The service provider can then provide a local stub method so that BarServiceStub’s sayHello method executes locally on the consumer, allowing the consumer to return fault-tolerant data if the service invocation fails.

public class BarServiceStub implements BarService {
    private final BarService barService;
    // The constructor passes in the real remote proxy object
    public BarServiceStub(BarService barService){
        this.barService = barService;
    }
    public String sayHello(String name) {
        // This code is executed on the client side, where you can do ThreadLocal local caching, pre-validate arguments, etc
        try {
            return barService.sayHello(name);
        } catch (Exception e) {
            // You can be fault-tolerant and can do any AOP interception
            return "Fault tolerant data"; }}}Copy the code

For Mock fault tolerant scenarios, Dubbo can use Mock properties for simpler configuration;

<dubbo:reference interface="com.foo.BarService" mock="true" /> or
<dubbo:reference interface="com.foo.BarService" mock="com.foo.BarServiceMock" />
Copy the code

Thus, in barServiceMock, there is no try cache and only post-cache processing is concerned.

public class BarServiceMock implements BarService {
    public String sayHello(String name) {
        // You can fake fault-tolerant data. This method is executed only when RpcException occurs
        return "Fault tolerant data"; }}Copy the code

This saves the service consumer a lot of unnecessary try cache operations. 3. In mock properties, you can directly return some specified objects, so that the implementation code can be omitted. Such as:

<dubbo:reference interface="com.foo.BarService" mock="return null" />
Copy the code

The mock attribute can return the following objects:

  • Empty: An empty object, representing the default value of a base type, or an empty collection, etc.
  • Null: A Null object in Java
  • Boolean: true or false
  • JSON format: A JSON deserialized object of an object.

Also, mock properties allow you to simply throw exceptions

<dubbo:reference interface="com.foo.BarService" mock="throw" />// Throw a RPCException exception<dubbo:reference interface="com.foo.BarService" mock="throw com.foo.MockException" />// Throws a specified exceptionCopy the code

4. In this version of Dubbo, the mock property also supports the mock behavior force and fail. Fail is consistent with the default process, which means that the remote call on the consumer side occurs when an exception occurs. Force, on the other hand, means to return mock data without making a remote call. This can be useful in debugging. Both force and fail can be combined with the return or throw above. ,

<dubbo:reference interface="com.foo.BarService" mock="force:return fake" /> or
<dubbo:reference interface="com.foo.BarService" mock="force:throw com.foo.MockException" />
Copy the code

5. This local mock is quite powerful when handling service invocation exceptions. The official advice is to mock at the method level rather than the entire service. Like this, mock only on the sayHello method.

<dubbo:reference id="demoService" check="false" interface="com.foo.BarService">
    <dubbo:parameter key="sayHello.mock" value="force:return fake"/>
</dubbo:reference>
Copy the code

Note that stubs and mocks can be specified on both the provider and consumer side of the service, and the consumer side should take precedence over the provider side.

GenericService

Dubbo’s services are always interface oriented, meaning that service invocations always require a fixed interface object, which is both secure and inflexible. Dubbo can increase service flexibility through GenericService Pan-China service. 1, the service provider side: in the service provider side, can use the org. Apache. Dubbo. RPC. Service. GenericService replace all of the interface implementation. For example, provide a service as follows:

<bean id="genericService" class="com.foo.MyGenericService" />
<dubbo:service interface="com.foo.BarService" ref="genericService" />
Copy the code

GenericService (MyGenericService); GenericService (MyGenericService);

public class MyGenericService implements GenericService {
    @Override
    public Object $invoke(String methodName, String[] parameterTypes, Object[] args) throws GenericException {
        if ("sayHello".equals(methodName)) {
            return "Welcome " + args[0]; }}}Copy the code

This allows you to respond to service requests such as barservice.sayHello (String args) on the server side without requiring an interface. This generic service approach also supports API service exposure, which is basically equivalent to XML configuration. To generalize service invocations, specify generic to true in reference.

<dubbo:reference id="barService" interface="com.foo.BarService" generic="true" />
Copy the code

The generalization service has no predefined methods and needs to be invoked using the $invoke method of GenericService

GenericService barService = (GenericService) applicationContext.getBean("barService");
Object result = barService.$invoke("sayHello".new String[] { "java.lang.String" }, new Object[] { "World" });
Copy the code

This invocation also supports service invocation in API format. The return object of the generalization method, if it is a POJO object, will return the POJO information in a Map structure similar to the following

Map<String, Object> map = new HashMap<String, Object>(); // Note: If the parameter type is interface, or if List is missing generics, you can specify the type through the class attribute. map.put("class", "com.xxx.PersonImpl"); map.put("name", "xxx"); // Person attribute map.put("password", "yyy");Copy the code

Service Management console

When Dubbo uses Nacos as the registry, Nacos already acts as a service console. There is also a project to replace Dubbo Admin as Dubbo’s service management console. Github address: github.com/apache/dubb… A separate admin console based on vue. js and Verify+SpringBoot.

The official website of Chinese people looks comfortable, with rich examples and simple and detailed instructions. The current version of Dubbo still has some functions such as distributed transactions, which are not yet realized. We look forward to more powerful Dubbo.