One why dubbo

Most of the time, when we actually use this technology, may be because the project need, so we went with, but, as to why we need to use this technology, may itself is not very understanding, but actually understand the background and the source of technology, and is helpful in understanding a technology, then, How did Dubbo get on the agenda?

In the course of the Development of the Internet, in the past, we only need a server, all packaged applications can be, but as the traffic increases, the normal vertical application architecture can not cope with, so the architecture has evolved.

1 Single application architecture

2 Deploy applications and databases separately

3 Cluster deployment of applications and databases

4 Database pressure increases and read/write separation occurs

Use caching to speed things up

6 Database database table

7 Applications are divided into different types

At this stage of development, we find that the relationship between applications is very complicated, and the following problems will occur (excerpted from the official website) :

① When there are more and more services, service URL configuration management becomes very difficult, and the single point of pressure of F5 hardware load balancer becomes more and more. (2) As the dependencies between services become so complex that it is not clear which application should be launched before which, architects cannot fully describe the architectural relationships of applications. ③ Then, the volume of service is increasing, and the capacity problem of the service is exposed. How much machine support does the service need? When should you add machines?

Dubbo was born to solve several problems arising from the evolution of the architecture. Dubbo isn’t the only technology to solve this problem, of course.

From the service governance diagram of Dubbo above, we can see that Duboo has solved some of the above problems well.

So, when you get to this stage in your system architecture, you need to consider using Dubbo.

Dubbo technology architecture

Now that we have a pretty good idea of why we need Dubbo in our system, let’s move on to the Dubbo architecture.

First, the previous image (from the official website).

After seeing the pictures, you may still be confused by the concepts above, but let’s take a look at what these characters mean.

Node Role description

node The role that
Provider The service provider that exposes the service
Consumer Service consumer that invokes the remote service
Registry A registry for service registration and discovery
Monitor A monitoring center that collects statistics on service invocation times and invocation time
Container Service run container

After looking at these concepts, it seems that Dubbo’s architecture is also very simple (the implementation details are complex). Why? It is very similar to the producer-consumer model. It’s just that on top of this model, a registry and a monitoring center are added to manage the urls provided by providers and the overall process.

Then, the whole publish-subscribe process is very simple.

  • Start the container, load, and run the service provider.
  • At startup, service providers register their own services by publishing in the registry.
  • Service consumers subscribe to the services they need in the registry at startup time.

If you consider failure or change, you need to consider the following process.

  • The registry returns a list of service provider addresses to the consumer, and if there are changes, the registry pushes the change data to the consumer based on the long connection.
  • The service consumer, from the provider address list, selects one provider to call based on the soft load balancing algorithm. If the call fails, selects another one to call.
  • Service consumers and providers accumulate calls and call times in memory and regularly send statistics to the monitoring center every minute.

With that, I’m sure Dubbo’s architecture is pretty familiar to us, so let’s go ahead and drive.

Three Dubbo start getting started

I have finally come to this step, and I stopped writing here for about a week. The main reason is that I am too busy with the project recently, and I have to meet the deadline. Today, I hope I can work hard and finish the basic chapter of Dubbo completely!

3.1 the service side

First, let’s write the interface on the server side, because dubbo’s purpose is simply to provide the interface to the consumer side.

The interface definition
Public interface ProviderService {String SayHello(String word); }Copy the code

This interface is very simple and contains only a SayHello method.

Next, define its implementation class.

/** * public class ProviderServiceImpl implements ProviderService{public String SayHello(String word) {returnword; }}Copy the code

Now that we have our interfaces written, how do we expose our services?

Importing Maven dependencies
<? xml version="1.0" encoding="UTF-8"? > <project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> < modelVersion > 4.0.0 < / modelVersion > < groupId > com. Ouyangsihai < / groupId > < artifactId > dubbo - provider < / artifactId > <version>1.0-SNAPSHOT</version> <dependencies> <groupId>junit</groupId> <artifactId> < version > 3.8.1 < / version > < scope >test</scope> </dependency> <! -- https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> < artifactId > dubbo < / artifactId > < version > 2.6.6 < / version > < / dependency > < the dependency > < the groupId > org. Apache. Zookeeper < / groupId > < artifactId > zookeeper < / artifactId > < version > 3.4.10 < / version > < / dependency > <dependency> <groupId>com.101tec</groupId> <artifactId> zkClient </artifactId> <version>0.5</version> </dependency> Ty < dependency > < groupId > io.net < / groupId > < artifactId > netty -all < / artifactId > < version > 4.1.32. The Final < / version > </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> < version > 2.8.0 < / version > < / dependency > < the dependency > < groupId > org. Apache. The curator < / groupId > <artifactId> co-curator -recipes</artifactId> <version>2.8.0</version> </dependency> </dependencies> </project>Copy the code

Note that if you import only dubbo’s version 2.6.6, an error will be reported. If you import only Dubbo’s version 2.6.6, you will not find netty and curator dependencies.

In addition, here we use ZooKeeper as the registry.

So far, that’s all dubbo needs. Now, let’s expose the interface we just defined above.

Exposing interfaces (XML configuration approach)

First, we create the meta-INF. spring package in our project’s resource directory, and then we create the provider.xml file with any name we want, as shown below.

<? xml version="1.0" encoding="UTF-8"? > <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <! Dubbo: Application name= <dubbo: Application name= <dubbo: Application name="provider" owner="sihai">
        <dubbo:parameter key="qos.enable" value="true"/>
        <dubbo:parameter key="qos.accept.foreign.ip" value="false"/>
        <dubbo:parameter key="qos.port" value="55555"/>
    </dubbo:application>

    <dubbo:monitor protocol="registry"/ > <! -- Dubbo the registry where the service address is exposed --> <! --<dubbo:registry address="N/A"/>-->
    <dubbo:registry address="N/A"/ > <! -- the protocol on which the current service is published; Webserovice, Thrift, Hessain, HTTP --> <dubbo:protocol name="dubbo" port="20880"/ > <! <dubbo:service interface="com.sihai.dubbo.provider.service.ProviderService"
            ref="providerService"/ > <! --Bean Bean definition --> < Bean id="providerService" class="com.sihai.dubbo.provider.service.ProviderServiceImpl"/>

</beans>
Copy the code

The above file is actually a spring-like configuration file, and the underlying dubbo is Spring. Dubbo: Application is the unique name of the entire project in the distributed architecture, which can be configured in the name attribute. In addition, the owner field can be configured to indicate who the project belongs to. The following parameters do not need to be configured. They are configured because port conflicts occur. 3 Node: dubbo:monitor Configuration, which is used to configure information about the connection to the monitoring center. For example, here we can configure ZooKeeper as our registry. Address is the address of the registry. Here we set N/A to indicate that dubbo automatically assigns the address. Or a direct connection, not through the registry. ⑤ Node: Dubbo :protocol Specifies the protocol that Dubbo depends on when the service is advertised. You can configure protocols such as Dubbo, Webserovice, Thrift, Hessain, and HTTP. ⑥ Node: dubbo:service this node is our focus, when we publish our service, we publish our service through this configuration. Interface is the package path of the interface, and ref is the bean of the interface configured at point ⑦. ⑦ Finally, we need to configure the interface bean just as we configured the Spring interface.

At this point, the server configuration is complete. Now we publish the interface using the main method.

Published interface
package com.sihai.dubbo.provider; import com.alibaba.dubbo.config.ApplicationConfig; import com.alibaba.dubbo.config.ProtocolConfig; import com.alibaba.dubbo.config.RegistryConfig; import com.alibaba.dubbo.config.ServiceConfig; import com.alibaba.dubbo.container.Main; import com.sihai.dubbo.provider.service.ProviderService; import com.sihai.dubbo.provider.service.ProviderServiceImpl; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; /** * Start in XML mode ** / public class App {public static void main(String[] args) throws IOException {// Start by loading the XML configuration file ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/provider.xml"); context.start(); System.in.read(); // Press any key to exit}}Copy the code

Published interface is very simple, because the dubbo bottom is dependent on the spring, so we only need we just through the ClassPathXmlApplicationContext configured XML, and then call the context. The start () method on.

As you can see in the screenshot below, even if the startup is successful, the interface is published.

You think we’re done here, but we’re not. We’ve got the URL analysis dubbo exposed.

Dubbo exposed URL

Dubbo: / / 192.168.234.1:20880 / com. Sihai. Dubbo. The provider. The service. ProviderService? anyhost=true& application = provider&bean. Name = com. Sihai. Dubbo. Provider. Service. ProviderService&bind. IP = 192.168.234.1 & bind. The port & d = 20880 Ubbo = 2.0.2 & generic =false&interface=com.sihai.dubbo.provider.service.ProviderService&methods=SayHello&owner=sihai&pid=8412&qos.accept.foreign.ip=false&qos.enable=true&qos.port=55555&side=provider&timestamp=1562077289380
Copy the code

Analysis of the

Dubbo uses a protocol similar to HTTP to publish its own services, but here we use the Dubbo protocol. (2) the dubbo: / / 192.168.234.1:20880 / com. Sihai. Dubbo. The provider. The service. ProviderService top section of the link is this? The previous link consists of: protocol :// IP: port/interface. There’s no mystery about finding out. 3. Anyhost = true&application = provider&bean. Name = com. Sihai. Dubbo. The provider. The service. ProviderService&bind. IP = 192.168.234.1 & bind. Port = 20880 & dubbo = 2.0.2 & generic = false&interface = com. Sihai. Dubbo. The provider. The service. ProviderService&methods = SayHello&owner = s IP =false&qos.enable=true&qos.port=55555&side= PROVIDer&timestamp =1562077289380? After analyzing it, you realize that these are fields that were just configured in provider.xml and then concatenated with &. Smell the HTTP smell?

Finally, dubbo server is here to stay. Now let’s look at what happens when we get the URL.

3.2 the consumer end

As mentioned above, we provide a point-to-point service on the server side without using a registry, so the following configuration will be a little different.

Consumer environment configuration

First, we create the consumer.xml configuration file under the resource on the consumer side.

<? xml version="1.0" encoding="UTF-8"? > <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <! Dubbo: Application name= <dubbo: Application name= <dubbo: Application name="consumer" owner="sihai"/ > <! -- Dubbo the registry where the service address is exposed --> <! Dubbo :registry address="N/A"/ > <! --<dubbo:registry address="zookeeper://localhost:2181" check="false"/ > -- > <! -- Generate a calling proxy for the remote service --> <! --> <dubbo: Reference id="providerService"
                     interface="com.sihai.dubbo.provider.service.ProviderService"
                     url="Dubbo: / / 192.168.234.1:20880 / com. Sihai. Dubbo. The provider. The service. The ProviderService"/ > <! --<dubbo:reference id="providerService"
                     interface="com.sihai.dubbo.provider.service.ProviderService"/>-->

</beans>
Copy the code

Analysis of the

Dubbo :registry is the same as Dubbo :application. ② Dubbo: Reference: We use the point-to-point approach here, so we need to configure the url exposed on the server side.

Maven rely on

Same as the server

<? xml version="1.0" encoding="UTF-8"? > <project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> < modelVersion > 4.0.0 < / modelVersion > < groupId > com. Ouyangsihai < / groupId > < artifactId > dubbo - consumer < / artifactId > < version > 1.0 - the SNAPSHOT < / version > < dependencies > < the dependency > < groupId > com. Ouyangsihai < / groupId > < artifactId > dubbo - provider < / artifactId > < version > 1.0 - the SNAPSHOT < / version > < / dependency > < the dependency > < the groupId > junit < / groupId > < artifactId > junit < / artifactId > < version > 3.8.1 < / version > < scope >test</scope> </dependency> <! -- https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> < artifactId > dubbo < / artifactId > < version > 2.6.6 < / version > < / dependency > < the dependency > < the groupId > org. Apache. Zookeeper < / groupId > < artifactId > zookeeper < / artifactId > < version > 3.4.10 < / version > < / dependency > <dependency> <groupId>com.101tec</groupId> <artifactId> zkClient </artifactId> <version>0.5</version> </dependency> Ty < dependency > < groupId > io.net < / groupId > < artifactId > netty -all < / artifactId > < version > 4.1.32. The Final < / version > </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> < version > 2.8.0 < / version > < / dependency > < the dependency > < groupId > org. Apache. The curator < / groupId > <artifactId> co-curator -recipes</artifactId> <version>2.8.0</version> </dependency> </dependencies> </project>Copy the code
Call the service
package com.sihai.dubbo.consumer; import com.alibaba.dubbo.config.ApplicationConfig; import com.alibaba.dubbo.config.ReferenceConfig; import com.alibaba.dubbo.config.RegistryConfig; import com.sihai.dubbo.provider.service.ProviderService; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; Public class App {public static void main(String[] args) throws IOException {public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("consumer.xml");
        context.start();
        ProviderService providerService = (ProviderService) context.getBean("providerService");
        String str = providerService.SayHello("hello"); System.out.println(str); System.in.read(); }}Copy the code

This is the same as publishing on the server side.

Add ZooKeeper as the registration center

In the previous example, we did not use any registry, but a direct connection. However, in fact, most of the time, we are using Dubbo + ZooKeeper, using ZooKeeper as the registry, here, we will introduce the use of ZooKeeper as the registry.

Here, we modify the previous introductory example.

4.1 the service side

On the server side, we just need to modify provider.xml.

<? xml version="1.0" encoding="UTF-8"? > <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <! Dubbo: Application name= <dubbo: Application name= <dubbo: Application name="provider" owner="sihai">
        <dubbo:parameter key="qos.enable" value="true"/>
        <dubbo:parameter key="qos.accept.foreign.ip" value="false"/>
        <dubbo:parameter key="qos.port" value="55555"/>
    </dubbo:application>

    <dubbo:monitor protocol="registry"/ > <! -- Dubbo the registry where the service address is exposed --> <! --<dubbo:registry address="N/A"/>-->
    <dubbo:registry address="zookeeper://localhost:2181" check="false"/ > <! -- the protocol on which the current service is published; Webserovice, Thrift, Hessain, HTTP --> <dubbo:protocol name="dubbo" port="20880"/ > <! <dubbo:service interface="com.sihai.dubbo.provider.service.ProviderService"
            ref="providerService"/ > <! --Bean Bean definition --> < Bean id="providerService" class="com.sihai.dubbo.provider.service.ProviderServiceImpl"/>

</beans>
Copy the code

Focus on this sentence

<dubbo:registry address="zookeeper://localhost:2181" />
Copy the code

In Address, use the address of our ZooKeeper.

For the ZooKeeper cluster, use the following method.

<dubbo:registry protocol="zookeeper" address="192.168.11.129:2181192168 11.137:2181192168 11.138:2181"/>
Copy the code

The server configuration is fine. The rest is the same as the starter case.

4.2 the consumer end

On the consumer side, as on the server side, we just need to modify consumer.xml.

<? xml version="1.0" encoding="UTF-8"? > <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <! Dubbo: Application name= <dubbo: Application name= <dubbo: Application name="consumer" owner="sihai"/ > <! -- Dubbo the registry where the service address is exposed --> <! -- Point-to-point --> <! --<dubbo:registry address="N/A" />-->
    <dubbo:registry address="zookeeper://localhost:2181" check="false"/ > <! -- Generate a calling proxy for the remote service --> <! Point-to-point mode --> <! --<dubbo:reference id="providerService"
                     interface="com.sihai.dubbo.provider.service.ProviderService"
                     url="Dubbo: / / 192.168.234.1:20880 / com. Sihai. Dubbo. The provider. The service. The ProviderService"/>-->

    <dubbo:reference id="providerService"
                     interface="com.sihai.dubbo.provider.service.ProviderService"/>

</beans>
Copy the code

① The registry configuration is the same as that of the server.

<dubbo:registry address="zookeeper://localhost:2181"/>
Copy the code

Because we use ZooKeeper as the registry, it is not the same as the point-to-point method. We no longer need the URL provided by the Dubbo server, only need to directly reference the interface provided by the server.

<dubbo:reference id="providerService"
                     interface="com.sihai.dubbo.provider.service.ProviderService"/>
Copy the code

Ok, the consumer side is configured so that you can restart and run using the modified introductory case.

It was equally successful.

The difference at this time is that the URL published by Dubbo is registered with ZooKeeper, and the consumer ends consume from ZooKeeper. Zookeeper acts as an intermediary to provide services to consumers.

You think this is the end? No, the fun is just beginning.

Five configuration modes are available

In the first example, we used XML configuration to configure the Dubbo environment, but there are other configuration methods provided by the authorities, which we break down here.

5.1 API Configuration Mode

XML configuration is not recommended, but it can be used when testing, and it is necessary to mention it for completeness.

First, back to the server-side project.

The service side

The main method of the AppApi class is used to configure and start provider. XML.

package com.sihai.dubbo.provider; import com.alibaba.dubbo.config.ApplicationConfig; import com.alibaba.dubbo.config.ProtocolConfig; import com.alibaba.dubbo.config.RegistryConfig; import com.alibaba.dubbo.config.ServiceConfig; import com.sihai.dubbo.provider.service.ProviderService; import com.sihai.dubbo.provider.service.ProviderServiceImpl; import java.io.IOException; /** * Api mode start * Api mode call no additional configuration, just need the following code. * Note, however, that official advice: * Api mode for test case use, XML is recommended */ public class AppApi {public static void main(String[] args) throws IOException {// The service implements ProviderService providerService = new ProviderServiceImpl(); ApplicationConfig application = new ApplicationConfig(); application.setName("provider");
        application.setOwner("sihai"); RegistryConfig registry = new RegistryConfig(); registry.setAddress("zookeeper://localhost:2181");
//        registry.setUsername("aaa");
//        registry.setPassword("bbb"); ProtocolConfig protocol = new ProtocolConfig(); protocol.setName("dubbo"); protocol.setPort(20880); //protocol.setThreads(200); / / note: The ServiceConfig object, which internally encapsulates the connection to the registry, ServiceConfig<ProviderService> service = new ServiceConfig<ProviderService>(); // This instance is very heavy and encapsulates the connection to the registry. Please cache it yourself, otherwise it may cause memory and connection leakage. service.setRegistry(registry); // Multiple registries can be usedsetRegistries() service.setProtocol(protocol); // Multiple protocols can be usedsetProtocols()
        service.setInterface(ProviderService.class);
        service.setRef(providerService);
        service.setVersion("1.0.0"); // Expose and register service service.export(); }}Copy the code

Analysis of the

Don’t panic if the above code is a bit confusing, let’s examine it against XML.

XML mode of Registry

<dubbo:registry protocol="zookeeper" address="localhost:2181"/>
Copy the code

API way

RegistryConfig registry = new RegistryConfig();
registry.setAddress("zookeeper://localhost:2181");
Copy the code

Dubbo: Registry node corresponds to RegistryConfig, and XML attributes correspond to API mode using set method. By contrast, you’ll find that if you’re not familiar with the WAY the API works, you can just look at the XML configuration.

Other apis

org.apache.dubbo.config.ServiceConfig
org.apache.dubbo.config.ReferenceConfig
org.apache.dubbo.config.ProtocolConfig
org.apache.dubbo.config.RegistryConfig
org.apache.dubbo.config.MonitorConfig
org.apache.dubbo.config.ApplicationConfig
org.apache.dubbo.config.ModuleConfig
org.apache.dubbo.config.ProviderConfig
org.apache.dubbo.config.ConsumerConfig
org.apache.dubbo.config.MethodConfig
org.apache.dubbo.config.ArgumentConfig
Copy the code

More details can be found in the official documentation: dubbo.apache.org/zh-cn/docs/…

Let’s look at the way I configured the Api on the consumer side.

The consumer end

Again, we don’t need the consumer.xml configuration file anymore, just launch it in the main method.

package com.sihai.dubbo.consumer; import com.alibaba.dubbo.config.ApplicationConfig; import com.alibaba.dubbo.config.ReferenceConfig; import com.alibaba.dubbo.config.RegistryConfig; import com.sihai.dubbo.provider.service.ProviderService; /** * API calls * API calls require no additional configuration, just the following code. * Note, however, that official advice: * Api mode for test case use, */ public class AppApi {public static void main(String[] args) {ApplicationConfig Application = new  ApplicationConfig(); application.setName("consumer");
        application.setOwner("sihai"); RegistryConfig registry = new RegistryConfig(); registry.setAddress("zookeeper://localhost:2181"); / / note: ReferenceConfig is a heavy object that internally encapsulates the connection to the registry, ReferenceConfig<ProviderService> reference = new ReferenceConfig<ProviderService>(); // This instance is very heavy and encapsulates the connection to the registry and the connection to the provider. Please cache it yourself, otherwise it may cause memory and connection leakage. SetApplication (application); reference.setRegistry(registry); // Multiple registries can be usedsetRegistries() reference.setInterface(ProviderService.class); // Use xxxService ProviderService = reference.get() as with the local bean; SayHello(providerService.sayHello (providerService.sayHello (providerService.sayHello (providerService.sayHello ("hello dubbo! I am sihai!"); }}Copy the code

This part of the API configuration method, note: the official recommended XML configuration method.

5.2 Comments Configuration Mode

Note configuration mode or need to understand, now micro services tend to this way, this is the future development trend, 0 configuration should be the trend of these years.

So how do you annotate Dubbo? Let’s look at the server side first.

The service side

Step 1: Define the interface and implementation class, under the Annotation package in the screenshot above

package com.sihai.dubbo.provider.service.annotation; / * * * way annotation interface * / public interface ProviderServiceAnnotation {String SayHelloAnnotation (String word); }Copy the code
package com.sihai.dubbo.provider.service.annotation; import com.alibaba.dubbo.config.annotation.Service; / comment way implementation class * * * * / @ Service (timeout = 5000) public class ProviderServiceImplAnnotation implements ProviderServiceAnnotation{ public String SayHelloAnnotation(String word) {returnword; }}Copy the code

@Service

@service is used to configure the Service provider of Dubbo.

** Step 2: Assemble the service provider. ** Discover, assemble, and provide Dubbo’s services via Spring’s Java Config technology (@Configuration) and annotation scanning (@enableDubbo).

package com.sihai.dubbo.provider.configuration; import com.alibaba.dubbo.config.ApplicationConfig; import com.alibaba.dubbo.config.ProtocolConfig; import com.alibaba.dubbo.config.ProviderConfig; import com.alibaba.dubbo.config.RegistryConfig; import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * Annotation mode Configuration */ @configuration @enableDubbo (scanBasePackages ="com.sihai.dubbo.provider.service.annotation")
public class DubboConfiguration {

    @Bean // #1 Service provider information configuration
    public ProviderConfig providerConfig() {
        ProviderConfig providerConfig = new ProviderConfig();
        providerConfig.setTimeout(1000);
        return providerConfig;
    }

    @Bean // #2 Distributed application information configuration
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("dubbo-annotation-provider");
        return applicationConfig;
    }

    @Bean // #3 Registry information configuration
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setProtocol("zookeeper");
        registryConfig.setAddress("localhost");
        registryConfig.setPort(2181);
        return registryConfig;
    }

    @Bean // #4 Using protocol configuration, dubbo is used here
    public ProtocolConfig protocolConfig() {
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setName("dubbo");
        protocolConfig.setPort(20880);
        returnprotocolConfig; }}Copy the code

Analysis of the

  • Specify at @enabledubbocom.sihai.dubbo.provider.service.annotationScan all labels below there@ServiceThe class of
  • through@ConfigurationDubboConfigurationAll of the@BeanthroughJava ConfigIs assembled and injected into the Dubbo service, that is, labeled with@ServiceIn the class. These include:
    • ProviderConfig: Service provider configuration
    • ApplicationConfig: Indicates application configuration
    • RegistryConfig: registry configuration
    • ProtocolConfig: indicates protocol configuration

It looks complicated, but…

Step 3: Start the service

package com.sihai.dubbo.provider; import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan; import com.sihai.dubbo.provider.configuration.DubboConfiguration; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import sun.applet.Main; import java.io.IOException; Public class AppAnnotation {public static void main(String[] args) throws IOException {public class AppAnnotation (String[] args) throws IOException { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DubboConfiguration.class); context.start(); System.in.read(); }}Copy the code

The following information is found to indicate success.

The consumer end

Also let’s take a look at the consumer side of engineering, and get a sense of what’s going on.

Step 1: Reference the service

package com.sihai.dubbo.consumer.Annotation; import com.alibaba.dubbo.config.annotation.Reference; import com.sihai.dubbo.provider.service.annotation.ProviderServiceAnnotation; import org.springframework.stereotype.Component; /** * annotated service */ @component ("annotatedConsumer")
public class ConsumerAnnotationService {

    @Reference
    private ProviderServiceAnnotation providerServiceAnnotation;

    public String doSayHello(String name) {
        returnproviderServiceAnnotation.SayHelloAnnotation(name); }}Copy the code

ConsumerAnnotationService class, the class provides referenced by @ the Reference service end, then, by means of method calls this class provides interfaces to consumers. Note: * * * * if here can’t find ProviderServiceAnnotation class, on the server, please put the service side project using Maven intall once, then will be dependent on the consumption side from the server in the pom. As follows:

< the dependency > < groupId > com. Ouyangsihai < / groupId > < artifactId > dubbo - provider < / artifactId > < version > 1.0 - the SNAPSHOT < / version > </dependency>Copy the code

Step 2: Assemble the service consumer This step is similar to the server side and will not be repeated here.

package com.sihai.dubbo.consumer.configuration; import com.alibaba.dubbo.config.ApplicationConfig; import com.alibaba.dubbo.config.ConsumerConfig; import com.alibaba.dubbo.config.RegistryConfig; import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import java.util.HashMap; import java.util.Map; /** * Annotation Configuration class */ @configuration @enableDubbo (scanBasePackages ="com.sihai.dubbo.consumer.Annotation")
@ComponentScan(value = {"com.sihai.dubbo.consumer.Annotation"}) public class ConsumerConfiguration {@bean // Public ApplicationConfigapplicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("dubbo-annotation-consumer");
        Map<String, String> stringStringMap = new HashMap<String, String>();
        stringStringMap.put("qos.enable"."true");
        stringStringMap.put("qos.accept.foreign.ip"."false");
        stringStringMap.put("qos.port"."33333");
        applicationConfig.setParameters(stringStringMap);
        returnapplicationConfig; } @bean // service ConsumerConfig public ConsumerConfigconsumerConfig() {
        ConsumerConfig consumerConfig = new ConsumerConfig();
        consumerConfig.setTimeout(3000);
        returnconsumerConfig; } @bean // Configure the registry public RegistryConfigregistryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setProtocol("zookeeper");
        registryConfig.setAddress("localhost");
        registryConfig.setPort(2181);
        returnregistryConfig; }}Copy the code

Step 3: Initiate a remote call

The service consumer of the assembled Dubbo is found by starting a Spring Context in the main method and making a remote call.

package com.sihai.dubbo.consumer; import com.sihai.dubbo.consumer.Annotation.ConsumerAnnotationService; import com.sihai.dubbo.consumer.configuration.ConsumerConfiguration; import com.sihai.dubbo.provider.service.ProviderService; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; /** */ public class AppAnnotation {public static void main(String[] args) throws IOException { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class); context.start(); / / start ConsumerAnnotationService ConsumerAnnotationService = context. GetBean (ConsumerAnnotationService. Class); String hello = consumerAnnotationService.doSayHello("annotation"); // Call system.out.println ("result: "+ hello); // Output result}}Copy the code

The results of

6 Common Scenarios

In the following sections, XML configuration will be used, which is the preferred method of Dubbo. The following operations are explained in the XML configuration file on the server side and the configuration file on the consumer side.

6.1 Check during Startup

Dubbo checks to see if dependent services are available at startup. If not, it will throw an exception to prevent Spring initialization from completing so that problems can be detected early when it goes live. By default, ‘check=”true”.

However, sometimes, we do not need to check at startup, such as testing, we need a faster startup, so, this scenario, we need to turn this function off.

Let’s look at how to use this feature.

When the server is registered (the same applies when the client is registered);

<dubbo:registry protocol="zookeeper" address="localhost:2181,localhost:2182,localhost:2183" check="false"/>
Copy the code

When a client references a server service;

<dubbo:reference check="false" id="providerService"
                     interface="com.sihai.dubbo.provider.service.ProviderService"/>
Copy the code

It’s that simple, it’s that strong!

6.2 Cluster fault tolerance

Dubbo also supports cluster fault tolerance, and there are many alternatives. The default solution is failover, which is a retry mechanism.

First of all, let’s go through all the fault tolerance mechanisms and then see how they work.

Cluster pattern instructions Method of use
Failover Cluster Failure to switch automatically, when failure occurs, retry other servers. Typically used for read operations, but retries introduce longer delays. Retries =”2″ can be used to set the number of retries (excluding the first). Cluster =” XXX “XXX: cluster mode name, for example, cluster=”failover”
Failfast Cluster Fast failure, only one call, failure immediately error. Typically used for non-idempotent writes, such as new records.
Failsafe Cluster Fail-safe, ignore exceptions when they occur.
Failback Cluster The system automatically recovers the failure, records the failure request in the background, and periodically resends the failure request. Typically used for message notification operations.
Forking Cluster Call multiple servers in parallel and return if one succeeds. It is usually used for read operations that require high real-time performance but waste more service resources. The maximum parallel number can be set by forks=”2″.
Broadcast Cluster The broadcast calls all the providers, one by one, and an error is reported on any one. Typically used to notify all providers to update local resource information such as caches or logs.

Example Set when publishing or referencing a service

<! Dubbo :service cluster= <dubbo:service cluster="failover" retries="2"
            interface="com.sihai.dubbo.provider.service.ProviderService"
            ref="providerService"/>
Copy the code
<dubbo:reference cluster="failover" retries="2" check="false" id="providerService"
                     interface="com.sihai.dubbo.provider.service.ProviderService"/>
Copy the code

6.3 Load Balancing

Load balancing is a familiar concept, so dubbo support is not uncommon. Here is a summary of dubbo support for load balancing and how to use it.

Load balancing mode instructions Method of use
Random LoadBalance Random Set random probability by weight <dubbo:service loadBalance =” XXX “/> XXX: load balancing method
RoundRobin LoadBalance Polling the polling ratio is set according to the weight after the convention.
LeastActive LoadBalance Minimum number of active calls Random with the same number of active calls.
ConsistentHash LoadBalance Consistent Hash requests with the same parameters are always sent to the same provider. When a provider hangs, requests originally sent to that provider are spread over other providers based on virtual nodes without drastic changes.

6.4 Directly Connected Provider

In the development and testing environment, often need to bypass the registry, testing only designated service providers, so, in this case, we only need to connect directly to the server can, in fact, this method has been used to the interpretation of in front, the first interpretation of the way is this way, because this way is simple.

use

<dubbo:reference id="providerService"
                     interface="com.sihai.dubbo.provider.service.ProviderService"
                     url="Dubbo: / / 192.168.234.1:20880 / com. Sihai. Dubbo. The provider. The service. The ProviderService"/>
Copy the code

Note: As you can see, just use the URL to give the method on the server side at the dubbo:reference node on the consumer side.

6.5 only subscribe

Subscribe only means that you can only subscribe to the services of the server, but not register them.

The official usage scenarios are as follows:

For development testing purposes, it is common to share a registry of all services available offline, where a registered service provider under development may affect consumer performance. You can have service provider developers test services under development by direct connection, only subscribing to services that may depend on other services, without registering services under development.

<dubbo:registry register="false" protocol="zookeeper" address="localhost:2181,localhost:2182,localhost:2183" check="false"/>
Copy the code

① Use subscription only

When register=”false” is used on the service provider side, we use the following method to get the service on the server side;

<dubbo:reference cluster="failover" retries="2" check="false" id="providerService"
                     interface="com.sihai.dubbo.provider.service.ProviderService"/>
Copy the code

Startup information

Registry ZooKeeper
Publish the service and start Netty

② Do not use subscription only

<dubbo:registry protocol="zookeeper" address="localhost:2181,localhost:2182,localhost:2183" check="false"/>
Copy the code

Startup information

As you can see, this is registered with the registry ZooKeeper.

6.6 only registered

Register-only is the opposite of subscriber-only, in which you can register with the registry, but the consumer cannot read the service.

Application scenarios

If you have two mirrored environments, two registries, one service is deployed in only one of them, the other is not yet deployed, and other applications in both registries need to rely on this service. At this point, the service provider can only register the service to another registry, rather than subscribing to the service from another registry.

Directions for use

<dubbo:registry subscribe="false" address="localhost:2181"></dubbo:registry>
Copy the code

Subscribe =”false” is used under the dubbo: Registry node on the service side to declare that the service is registered only.

This is not called when the consumer calls.

6.7 Multi-protocol Mechanism

The protocols we used previously were dubbo, but dubbo also supports other protocols, such as RMI, Hessian, etc., and multiple protocols can be used to expose a service at the same time.

Method of use

① One interface uses one protocol

Declare multiple protocols first

<! -- the protocol on which the current service is published; Webserovice, Thrift, Hessain, HTTP --> <dubbo:protocol name="dubbo" port="20880"/>
    <dubbo:protocol name="rmi" port="1099" />
Copy the code

Then use the protocol when publishing the interface

<! Dubbo :service cluster= <dubbo:service cluster="failover" retries="2"
            interface="com.sihai.dubbo.provider.service.ProviderService"
            ref="providerService"/>
    <dubbo:service cluster="failover" retries="2"
                   interface="com.sihai.dubbo.provider.service.ProviderService"
                   ref="providerService" protocol="rmi"/>
Copy the code

In the output log, you can find the interface published by RMI.

Rmi: / / 192.168.234.1:1099 / com. Sihai. Dubbo. The provider. The service. ProviderService? anyhost=true& application = provider&bean. Name = com. Sihai. Dubbo. The provider. The service. The ProviderService&cluster = failover&dubbo = 2.0.2 & generic =false&interface=com.sihai.dubbo.provider.service.ProviderService&methods=SayHello&owner=sihai&pid=796&retries=2&side=provider &timestamp=1564281053185, dubbo version: 2.6.6, current host: 192.168.234.1Copy the code

② An interface uses multiple protocols. The protocol declaration is the same as the above method, but the interface publication is a little different.

<dubbo:service cluster="failover" retries="2"
                   interface="com.sihai.dubbo.provider.service.ProviderService"
                   ref="providerService" protocol="rmi,dubbo"/>
Copy the code

** Description: **protocol attribute, can be used, separated, use multiple protocols.

6.8 Multiple Registries

Dubbo supports simultaneous registration of the same service in multiple registries, registration of different services in different registries, and even simultaneous reference of the same service registered in different registries.

Server multi-registry publishing service

A service can be registered in different registries, and when problems occur in one registry, other registries can be used.

registered

<! --> <dubbo: Registry protocol="zookeeper" id="reg1" timeout="10000" address="localhost:2181"/>
    <dubbo:registry protocol="zookeeper" id="reg2" timeout="10000" address="localhost:2182"/>
    <dubbo:registry protocol="zookeeper" id="reg3" timeout="10000" address="localhost:2183"/>
Copy the code

Publishing service

<! Dubbo :service cluster= <dubbo:service cluster="failover" retries="2"
            interface="com.sihai.dubbo.provider.service.ProviderService"
            ref="providerService" registry="reg1"/>
    <dubbo:service cluster="failover" retries="2"
                   interface="com.sihai.dubbo.provider.service.ProviderService"
                   ref="providerService" protocol="rmi" registry="reg2"/>
Copy the code

** Use registry=”reg2″ to specify the registry to be used by the interface. Multiple, separated by, can also be used, for example, registry=”reg1,,reg2″.

Consumer side multiple registry reference service

First, register with a different registry;

<! --> <dubbo: Registry protocol="zookeeper" id="reg1" timeout="10000" address="localhost:2181"/>
    <dubbo:registry protocol="zookeeper" id="reg2" timeout="10000" address="localhost:2182"/>
    <dubbo:registry protocol="zookeeper" id="reg3" timeout="10000" address="localhost:2183"/>

Copy the code

Second, different consumer service references use different registries;

! --> <dubbo: Reference cluster="failover" retries="2" check="false" id="providerService"
                     interface="com.sihai.dubbo.provider.service.ProviderService" registry="reg1"/>
    <dubbo:reference cluster="failover" retries="2" check="false" id="providerService2"
                     interface="com.sihai.dubbo.provider.service.ProviderService" registry="reg2"/>
Copy the code

** Note: ** Use registry 1 and registry 2 respectively above.

More than 6.9 version

Different services have different versions. Versions can be updated and upgraded. At the same time, different versions cannot be called.

<! Dubbo :service cluster= <dubbo:service cluster="failover" retries="2"
            interface="com.sihai.dubbo.provider.service.ProviderService"
            ref="providerService" registry="reg1" version="1.0.0"/>
    <dubbo:service cluster="failover" retries="2"
                   interface="com.sihai.dubbo.provider.service.ProviderService"
                   ref="providerService" protocol="rmi" registry="reg2" version="1.0.0"/>
Copy the code

Version control was added.

6.10 Log Management

Dubbo can also record or save log information to a file.

① Output to log4j using accesslog

<dubbo:protocol accesslog="true" name="dubbo" port="20880"/>
    <dubbo:protocol accesslog="true" name="rmi" port="1099" />
Copy the code

② Output to a file

<dubbo:protocol accesslog="http://localhost/log.txt" name="dubbo" port="20880"/>
    <dubbo:protocol accesslog="http://localhost/log2.txt" name="rmi" port="1099" />
Copy the code

Seven summarizes

Dubbo is used in the ZooKeeper registrie. dubbo is used in the zooKeeper registrie. dubbo is used in the ZooKeeper registrie. dubbo is used in the zooKeeper registry. Source code analysis will be discussed.

If there are any improper articles, please correct them. If you like reading on wechat, you can also follow my wechat official account: Learn Java well and get quality learning resources.