Dubbo integrates Nacos to become a registration center

Get started quickly

The operation steps for Dubbo to integrate Nacos into a registration center are very simple. The steps can be roughly divided into "adding Maven dependencies" and "configuring the registration center".

Add Maven dependency

You only need to rely on the Dubbo client. For the recommended version, please refer to Dubbo official documents or consult Dubbo developers:

<dependencies>

    ...

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>3.0.5</version>
    </dependency>

    <!-- Dubbo Nacos registry dependency -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo-registry-nacos</artifactId>
        <version>3.0.5</version>
    </dependency>

    <!-- Alibaba Spring Context extension -->
    <dependency>
        <groupId>com.alibaba.spring</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>1.0.11</version>
    </dependency>
    ...
    
</dependencies>

Configure the registry

Assuming that your Dubbo application uses Spring Framework assembly, there will be two configuration options: Dubbo Spring external configuration and Spring XML configuration file, and the author strongly recommends the former.

Dubbo Spring external configuration

Dubbo Spring external configuration is  2.5.8 a new feature introduced by Dubbo, which can  Environment automatically generate and bind Dubbo configuration beans through Spring properties, simplifying configuration and lowering the threshold for microservice development.

Assume that your Dubbo application uses Nacos as the registration center, and its server IP address is: 10.20.153.10, and the registration address is stored in the file as Dubbo externalization configuration properties  dubbo-config.properties , as follows:

## application
dubbo.application.name = your-dubbo-application

## Nacos registry address
dubbo.registry.address = nacos://10.20.153.10:8848
##如果要使用自己创建的命名空间可以使用下面2种方式
#dubbo.registry.address = nacos://10.20.153.10:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932
#dubbo.registry.parameters.namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932
...

Then, restart your Dubbo application, and Dubbo's service provision and consumption information can be displayed in the Nacos console:

image-20181213103845976-4668726.png | left | 747x284

As shown in the figure, the information prefixed with the service name is  providers: the meta information of the service provider, consumers: which represents the meta information of the service consumer. Click " Details " to view service status details:

image-20181213104145998-4668906.png | left | 747x437

If you are using the Spring XML configuration file to assemble the Dubbo registry, please refer to the next section.

Spring XML configuration file

Similarly, assume that your Dubbo application uses Nacos as the registration center, and its server IP address is: 10.20.153.10, and assemble Spring Bean in the XML file, as follows:

<?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://dubbo.apache.org/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
 
    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="dubbo-provider-xml-demo"  />
 
    <!-- 使用 Nacos 注册中心 -->
    <dubbo:registry address="nacos://10.20.153.10:8848" />
    <!-- 如果要使用自己创建的命名空间可以使用下面配置 -->
    <!-- <dubbo:registry address="nacos://10.20.153.10:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932" /> -->
 	...
</beans>

After restarting the Dubbo application, you can also find that the registration meta information of the service provider and consumer is displayed in the Nacos console:

image-20181213113049185-4671849.png | left | 747x274

Do you think it is super easy to configure or switch Nacos registry? If you still don't understand or don't understand, you can refer to the following complete example.

complete example

The metadata in the above picture comes from the Dubbo Spring annotation-driven example and the Dubbo Spring XML configuration-driven example. The two will be introduced below, and you can choose your preferred programming model. Before the formal discussion, let's introduce the preliminary work of both, because they both rely on the Java service interface and implementation. At the same time, please make sure that the local ( 127.0.0.1) environment has started the Nacos service .

Example interface and implementation

Complete code archive location:  https://github.com/nacos-group/nacos-examples/tree/master/nacos-dubbo-example

First define the example interface as follows:

package com.alibaba.nacos.example.dubbo.service;

public interface DemoService {
    String sayName(String name);
}

Provide the implementation class of the above interface:


package com.alibaba.nacos.example.dubbo.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.rpc.RpcContext;
import org.springframework.beans.factory.annotation.Value;

/**
 * Default {@link DemoService}
 *  https://nacos.io/zh-cn/docs/use-nacos-with-dubbo.html
 * @since 2.6.5
 */
@Service(version = "${demo.service.version}")
public class DefaultService implements DemoService {

    @Value("${demo.service.name}")
    private String serviceName;

    public String sayName(String name) {
        RpcContext rpcContext = RpcContext.getContext();
        return String.format("Service [name :%s , port : %d] %s(\"%s\") : Hello,%s",
                serviceName,
                rpcContext.getLocalPort(),
                rpcContext.getMethodName(),
                name,
                name);
    }
}

After the interface and implementation are ready, the annotation-driven and XML configuration-driven implementations will be used below.

Spring Annotation Driven Example

Dubbo  2.5.7 refactors the Spring annotation-driven programming model.

Service provider annotation-driven implementation

  • Define Dubbo provider externalization configuration property source - provider-config.properties
## application
dubbo.application.name = dubbo-provider-demo

## Nacos registry address
dubbo.registry.address = nacos://127.0.0.1:8848
##如果要使用自己创建的命名空间可以使用下面2种方式
#dubbo.registry.address = nacos://127.0.0.1:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932
#dubbo.registry.parameters.namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932

## Dubbo Protocol
dubbo.protocol.name = dubbo
dubbo.protocol.port = -1

# Provider @Service version
demo.service.version=1.0.0
demo.service.name = demoService

dubbo.application.qosEnable=false

  • Implement the service provider bootstrap class - DemoServiceProviderBootstrap
package com.alibaba.nacos.example.dubbo.provider;

import com.alibaba.nacos.example.dubbo.service.DemoService;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.PropertySource;
import java.io.IOException;

/**
 * {@link DemoService} provider demo
 * https://nacos.io/zh-cn/docs/use-nacos-with-dubbo.html
 */
@EnableDubbo(scanBasePackages = "com.alibaba.nacos.example.dubbo.service")
@PropertySource(value = "classpath:/provider-config.properties")
public class DemoServiceProviderBootstrap {

    public static void main(String[] args) throws IOException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(DemoServiceProviderBootstrap.class);
        context.refresh();
        System.out.println("DemoService provider is starting...");
        System.in.read();
    }
}

The annotation  @EnableDubbo activates the Dubbo annotation driver and external configuration,  scanBasePackages scans the specified Java package for its properties, and  @Service exposes all marked service interface implementation classes as Spring Beans, which are then exported to Dubbo services.

@PropertySource It is a standard import attribute configuration resource annotation introduced by Spring Framework 3.1, which will provide external configuration for Dubbo.

Annotation-driven implementation of service consumers

  • Define Dubbo consumer externalization configuration property source - consumer-config.properties
## Dubbo Application info
dubbo.application.name = dubbo-consumer-demo

## Nacos registry address
dubbo.registry.address = nacos://127.0.0.1:8848
##如果要使用自己创建的命名空间可以使用下面2种方式
#dubbo.registry.address = nacos://127.0.0.1:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932
#dubbo.registry.parameters.namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932

# @Reference version
demo.service.version= 1.0.0

dubbo.application.qosEnable=false

Similarly, dubbo.registry.address the attribute points to the Nacos registration center, and the meta information related to other Dubbo services is obtained through the Nacos registration center.

  • Implement the service consumer bootstrap class - DemoServiceConsumerBootstrap
package com.alibaba.nacos.example.dubbo.consumer;


import com.alibaba.nacos.example.dubbo.service.DemoService;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.PropertySource;
import javax.annotation.PostConstruct;
import java.io.IOException;

/**
 * {@link DemoService} consumer demo
 * https://nacos.io/zh-cn/docs/use-nacos-with-dubbo.html
 */
@EnableDubbo
@PropertySource(value = "classpath:/consumer-config.properties")
public class DemoServiceConsumerBootstrap {

    @DubboReference(version = "${demo.service.version}")
    private DemoService demoService;

    @PostConstruct
    public void init() {
        for (int i = 0; i < 10; i++) {
            System.out.println(demoService.sayName("Nacos"));
        }
    }

    public static void main(String[] args) throws IOException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(DemoServiceConsumerBootstrap.class);
        context.refresh();
        context.close();
    }
}

Similarly, @EnableDubbo the annotation activates Dubbo annotation driver and external configuration, but currently belongs to the service consumer, and there is no need to specify the  @Service service implementation of the Java package name scanning annotation.

@Reference It is the dependency injection annotation of Dubbo remote service, which requires the service provider and the consumer to agree on the interface, version and group information. In the current service consumption example, DemoService the service version is derived from the properties configuration file  consumer-config.properties.

@PostConstruct Part of the code indicates that when  DemoServiceConsumerBootstrap the Bean is initialized, ten Dubbo remote method calls are executed.

Run the annotation-driven example

Start it twice locally  DemoServiceProviderBootstrap, and there will be two health services in the registry:

image-20181213123909636-4675949.png | left | 747x38

Run it again  DemoServiceConsumerBootstrap, the result is as follows:

Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos

The operation is correct, and the service consumer uses a load balancing strategy to evenly distribute ten RPC calls to two Dubbo service provider instances.

Spring XML configuration driven example

The Spring XML configuration driver is a programming model for traditional Spring assembly components.

Service provider XML configuration driver

  • Define the service provider XML context configuration file - /META-INF/spring/dubbo-provider-context.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://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="dubbo-provider-xml-demo"/>

    <!-- 使用 Nacos 注册中心 -->
    <dubbo:registry address="nacos://127.0.0.1:8848"/>
    <!-- 如果要使用自己创建的命名空间可以使用下面配置 -->
    <!-- <dubbo:registry address="nacos://127.0.0.1:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932" /> -->

    <!-- 用dubbo协议在随机端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="-1"/>

    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.alibaba.nacos.example.dubbo.service.DemoService" ref="demoService" version="2.0.0"/>

    <!-- 和本地bean一样实现服务 -->
    <bean id="demoService" class="com.alibaba.nacos.example.dubbo.service.DefaultService"/>
</beans>
  • Implement the service provider bootstrap class - DemoServiceProviderXmlBootstrap

package com.alibaba.nacos.example.dubbo.provider;

import com.alibaba.dubbo.demo.service.DemoService;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**
 * {@link DemoService} provider demo XML bootstrap
 */
public class DemoServiceProviderXmlBootstrap {

    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
        context.setConfigLocation("/META-INF/spring/dubbo-provider-context.xml");
        context.refresh();
        System.out.println("DemoService provider (XML) is starting...");
        System.in.read();
    }
}

Service consumer XML configuration driver

  • Define service consumer XML context configuration file - /META-INF/spring/dubbo-consumer-context.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://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd        http://dubbo.apache.org/schema/dubbo        http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="dubbo-consumer-xml-demo"/>

    <!-- 使用 Nacos 注册中心 -->
    <dubbo:registry address="nacos://127.0.0.1:8848"/>
    <!-- 如果要使用自己创建的命名空间可以使用下面配置 -->
    <!-- <dubbo:registry address="nacos://127.0.0.1:8848?namespace=5cbb70a5-xxx-xxx-xxx-d43479ae0932" /> -->

    <!-- 引用服务接口 -->
    <dubbo:reference id="demoService" interface="com.alibaba.nacos.example.dubbo.service.DemoService" version="2.0.0"/>

</beans>
  • Implement the service consumer bootstrap class - DemoServiceConsumerXmlBootstrap

package com.alibaba.nacos.example.dubbo.consumer;

import com.alibaba.dubbo.demo.service.DemoService;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;

/**
 * {@link DemoService} consumer demo XML bootstrap
 */
public class DemoServiceConsumerXmlBootstrap {

    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
        context.setConfigLocation("/META-INF/spring/dubbo-consumer-context.xml");
        context.refresh();
        System.out.println("DemoService consumer (XML) is starting...");
        DemoService demoService = context.getBean("demoService", DemoService.class);
        for (int i = 0; i < 10; i++) {
            System.out.println(demoService.sayName("Nacos"));
        }
        context.close();
    }
}

Run the XML configuration driver example

Similarly, start two  DemoServiceProviderXmlBootstrap bootstrap classes first, and observe the changes of the Nacos registry service provider:

image-20181213125527201-4676927.png | left | 747x33

The service version driven by the XML configuration is  2.0.0, so there is no error in registering the service.

Then run the service consumer boot class  DemoServiceConsumerXmlBootstrapand observe the console output:

Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos
Service [name :demoService , port : 20880] sayName("Nacos") : Hello,Nacos

The result is also running and load balancing is normal, but because the current example has not added attributes  demo.service.name , the output of the "name" part of the information is  null.

Guess you like

Origin blog.csdn.net/leesinbad/article/details/132381414