菜鸟学Dubbo和Nacos随记(更新中)

Dubbo和Nacos是两个在微服务架构中常用的工具,它们各自扮演着不同的角色。

Dubbo主要关注于RPC框架的实现,提供了高性能的远程方法调用和服务治理功能;而Nacos则更侧重于服务发现、配置管理和服务管理平台的建设。

Dubbo是阿里巴巴公司开源的一个高性能、轻量级的Java RPC框架。它允许应用通过高性能的RPC实现服务的输出和输入功能,并可以与Spring框架无缝集成。

Dubbo提供了六大核心能力,包括面向接口代理的高性能RPC调用、智能容错和负载均衡、服务自动注册和发现、高度可扩展能力、运行期流量调度,以及可视化的服务治理与运维。在Dubbo中,服务提供方(Provider)和服务消费方(Consumer)通过注册中心(Registry)进行服务的注册与发现,同时有Monitor用于统计服务的调用次数和调用时间,Container则作为服务的运行容器。

Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台的工具。Nacos帮助开发者快速实现动态服务发现、服务配置、服务元数据及流量管理。它通过服务名来发现其他服务,有助于实现微服务架构中的服务之间的通信。同时,Nacos还提供了统一的配置管理平台,可用于管理和动态更新分布式系统中的配置信息,如数据库连接、参数设置等。此外,Nacos还支持动态DNS服务、服务健康监测、权重和流量管理等功能。

dubbo可以替换sping cloud哪些组件?

Dubbo主要用于服务之间的远程调用和通信。虽然Dubbo本身并不是Spring Cloud的一部分,但它可以与Spring框架进行集成,并在某些场景下替换Spring Cloud中的某些组件或功能。具体来说,Dubbo可以替换或补充Spring Cloud中的以下组件或功能:

  1. 服务注册与发现:Dubbo使用自身的注册中心组件(如Zookeeper、Nacos、Etcd等),可以替换Spring Cloud中的Eureka、Consul等服务注册与发现组件。Dubbo的注册中心用于维护服务提供者和消费者的信息,实现服务的自动注册、发现和管理。

  2. 远程调用:Dubbo提供了基于RPC的远程调用机制,可以替换Spring Cloud中基于HTTP的远程调用方式(如使用RestTemplate或Feign)。Dubbo的RPC调用更加轻量级和高效,适用于大规模、高并发的服务调用场景。

  3. 负载均衡:Dubbo内置了多种负载均衡策略(如随机、轮询、一致性哈希等),可以替换或补充Spring Cloud中的负载均衡组件。Dubbo的负载均衡机制能够根据服务提供者的性能和负载情况,智能地分配请求,提高系统的吞吐量和稳定性。

虽然Dubbo可以在某些方面替换Spring Cloud的组件,但两者在设计和定位上存在差异。Dubbo更专注于服务之间的远程调用和通信,而Spring Cloud则是一个更完整的微服务解决方案,提供了服务治理、配置管理、熔断降级、智能路由等一系列功能.

nacos概念

它的作用:发现、配置和管理微服务。

1.地域、可用区、接入点(这三个是前期需要关注的点,可找运维去问)

地域:物理的数据中心,资源创建成功后不能更换。

可用区:同一地域内,电力和网络互相独立的物理区域。同一可用区内,实例的网络延迟较低。

接入点:地域的某个服务的入口域名。

2.命名空间。

用于进行租户粒度的配置隔离,主要用于区分环境(如区分生产和测试环境)。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。

3.配置管理。

顾名思义是管理配置的,可管理“配置项”(通常以 param-key=param-value),配置项的集合又称为“配置集”。配置集可以通过“Data ID”进行组织划分(命名规则如:com.taobao.tc.refund.log.level)保证全局唯一性。

4.服务。

给客户端提供服务的软件,他有自己的服务名(在服务管理-服务列表里能看到)。

5.服务注册中心。

存储服务实例和服务负载均衡策略的数据库。

6.服务发现。

对服务下的实例的地址和元数据进行探测,并以预先定义的接口提供给客户端进行查询。

7.元信息

Nacos数据(如配置和服务)描述信息,如服务版本、权重、容灾策略、负载均衡策略、鉴权配置、各种自定义标签 (label),从作用范围来看,分为服务级别的元信息、集群的元信息及实例的元信息。

8.服务分组。

不同的服务可以归类到同一分组。

9.虚拟集群。

同一个服务下的所有服务实例组成一个默认集群, 集群可以被进一步按需求划分,划分的单位可以是虚拟集群。

10.实例。

提供一个或多个服务的具有可访问网络地址(IP)的进程。

11.权重。

实例级别的配置。权重为浮点数。权重越大,分配给该实例的流量越大。和dubbo里的权重概念类似。

12.健康检查。

以指定方式检查服务下挂载的实例 (Instance) 的健康度,从而确认该实例 (Instance) 是否能提供服务。根据检查结果,实例 (Instance) 会被判断为健康或不健康。对服务发起解析请求时,不健康的实例 (Instance) 不会返回给客户端。

下面是nacos1.x的界面。

下面是nacos2.x的界面。

通过url对nacos进行服务管理

服务怎么注册到nacos上的呢?其实也是调nacos的接口来进行服务注册的,我们用postman来试一下:

1.服务注册

路径填好你的nacos地址,端口号,参数(要注册的服务名,ip,端口),直接一发送,ok。注意:可看到路径里nacos后面是v1,代表的是注册到1.x的版本的nacos,即使你服务器上同时装了1.x和2.x。不同的nacos用法可参照官网:Nacos 快速开始 | Nacos

http://124.xxx.xxx.xxx:8848/nacos/v1/ns/instance

在nacos里就看到这个手工注册上的服务了,虽然它是假的,我根本都没有这个服务。

2.服务发现

同样,填好地址 http://124.xxx.xxx.xxx:8848/nacos/v1/ns/instance/list 以及你要查询的服务名得到刚刚注册的服务信息。注意:这里是get请求。

3.发布配置

也是一样,填好配置项,post请求http://124.xxx.xxx.xxx:8848/nacos/v1/cs/configs

 我们根据dataDd一搜,并点击详情看一下,发现和我们post传入的结果一样。

 4.获取配置

根据服务名,dataid,group三件套定位到我们刚刚设置的配置即可读取我们刚刚配置好的配置项。

5.程序启用配置管理

我们在nacos中设置这些配置用来干嘛呢?

我们可以利用nacos动态给程序配参数,例如我们程序某个类里有个useLocalCache的属性,我想在不重新打包的情况下改变它的值,以前要么就是程序里搞个配置文件改配置文件,要么就是重新发版打包,有了nacos就不一样了,使我们的程序更灵活了。

如下针对的是spring,spring-boot,和spring-cloud相关的用法,其实nacos还可以集成在docker中(后续再更新到文章里,也许我懒得更新了,大家自己也可以去学学看)

1.首先添加 spring的nacos依赖,版本号参照你的nacos,选择自己合适的。(注:如下依赖和操作是针对于spring的,如果用spring boot需要引入别的依赖

        a.针对spring的依赖:

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-spring-context</artifactId>
    <version>${latest.version}</version>
</dependency>

        b.针对spring boot的依赖,用的是我们熟悉的starter。

<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>nacos-config-spring-boot-starter</artifactId>
    <version>${latest.version}</version>
</dependency>

        c.针对spring-cloud的依赖,又不一样了。

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>${latest.version}</version>
</dependency>

2.启用nacos config配置管理服务。

        a.针对于spring。

@Configuration
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "xxx.0.0.xxx:8848"))
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class NacosConfiguration {

}

        b.如果是spring-boot可以在application.properties 中配置 Nacos server 的地址,并在启动类上添加nacos的dataid:

#配置文件
nacos.config.server-addr=xx.0.0.xxx:8848


//启动类
@SpringBootApplication
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class NacosConfigApplication {

    public static void main(String[] args) {
        SpringApplication.run(NacosConfigApplication.class, args);
    }
}

        c.如果使用spring-cloud,可以在bootstrap.properties中这样配置。

#bootstrap.properties
spring.cloud.nacos.config.server-addr=xxx.0.0.xxx:8848
spring.application.name=example


#在 Nacos Spring Cloud 中,dataId 的完整格式如下
${prefix}-${spring.profiles.active}.${file-extension}

prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
spring.profiles.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。


//通过 Spring Cloud 原生注解 @RefreshScope 实现配置自动更新:
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {

    @Value("${useLocalCache:false}")
    private boolean useLocalCache;

    @RequestMapping("/get")
    public boolean get() {
        return useLocalCache;
    }
}

3.通过nacos的注解,给useLocalCache赋值,这都一一样的方式获取了。

@Controller
@RequestMapping("config")
public class ConfigController {

    @NacosValue(value = "${useLocalCache:false}", autoRefreshed = true)
    private boolean useLocalCache;

    @RequestMapping(value = "/get", method = GET)
    @ResponseBody
    public boolean get() {
        return useLocalCache;
    }
}

 启动 Tomcat,调用 curl http://localhost:8080/config/get尝试获取配置信息。由于此时还未发布过配置,所以返回内容是 false(因为Boolean类型默认值就是false)。

然后我们通过curl或者postman都行,给上面的api接口给nacos里添加一个useLocalCache属性并赋值为true。

curl -X POST "http://xxx.xxx.xxx.xxx:8848/nacos/v1/cs/configs?dataId=example&group=DEFAULT_GROUP&content=useLocalCache=true"

再次访问 http://localhost:8080/config/get,此时返回内容为true,说明程序中的useLocalCache值已经被动态更新了。

6.程序启用服务发现

1.同样是添加依赖

        a.针对于spring

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-spring-context</artifactId>
    <version>${latest.version}</version>
</dependency>

        b.针对于spring-boot

<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>nacos-discovery-spring-boot-starter</artifactId>
    <version>${latest.version}</version>
</dependency>

         c.针对spring-cloud,注意:版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本。版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本,版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本。

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>${latest.version}</version>
</dependency>

2.开启服务发现。

        a.针对于spring,用@EnableNacosDiscovery 注解开启 Nacos Spring 的服务发现功能:

@Configuration
@EnableNacosDiscovery(globalProperties = @NacosProperties(serverAddr = "xxx.0.0.xxx:8848"))
public class NacosConfiguration {

}

        b.针对于spring-boot ,在 application.properties 中配置 Nacos server 的地址,使用 @NacosInjected 注入 Nacos 的 NamingService 实例。

#配置文件
nacos.discovery.server-addr=xxx.0.0.xxx:8848



//注入服务

@Controller
@RequestMapping("discovery")
public class DiscoveryController {

    @NacosInjected
    private NamingService namingService;

    @RequestMapping(value = "/get", method = GET)
    @ResponseBody
    public List<Instance> get(@RequestParam String serviceName) throws NacosException {
        return namingService.getAllInstances(serviceName);
    }
}

@SpringBootApplication
public class NacosDiscoveryApplication {

    public static void main(String[] args) {
        SpringApplication.run(NacosDiscoveryApplication.class, args);
    }
}

        c.针对于spring-cloud。

        对于服务提供者来说:

#配置服务提供者,从而服务提供者可以通过 Nacos 的服务注册发现功能将其服务注册到 Nacos server 上。

#在 application.properties 中配置 Nacos server 的地址:
server.port=8070
spring.application.name=service-provider

spring.cloud.nacos.discovery.server-addr=xxx.0.0.xxx:8848


//通过 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现功能:
@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderApplication {

  public static void main(String[] args) {
    SpringApplication.run(NacosProviderApplication.class, args);
  }

  @RestController
  class EchoController {
    @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
    public String echo(@PathVariable String string) {
      return "Hello Nacos Discovery " + string;
    }
  }
}

        对于服务消费者来说 。

#配置服务消费者,从而服务消费者可以通过 Nacos 的服务注册发现功能从 Nacos server 上获取到它要调用的服务。

#在 application.properties 中配置 Nacos server 的地址:
server.port=8080
spring.application.name=service-consumer
spring.cloud.nacos.discovery.server-addr=xxx.0.0.xxx:8848


#通过 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现功能。给 RestTemplate 实例添加 @LoadBalanced 注解,开启 @LoadBalanced 与 Ribbon 的集成:

@SpringBootApplication
@EnableDiscoveryClient
public class NacosConsumerApplication {

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(NacosConsumerApplication.class, args);
    }

    @RestController
    public class TestController {

        private final RestTemplate restTemplate;

        @Autowired
        public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}

        @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
        public String echo(@PathVariable String str) {
            return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
        }
    }
}

3.使用 @NacosInjected 注入 Nacos 的 NamingService 实例:

@Controller
@RequestMapping("discovery")
public class DiscoveryController {

    @NacosInjected
    private NamingService namingService;

    @RequestMapping(value = "/get", method = GET)
    @ResponseBody
    public List<Instance> get(@RequestParam String serviceName) throws NacosException {
        return namingService.getAllInstances(serviceName);
    }
}

启动 Tomcat,调用 curl http://localhost:8080/discovery/get?serviceName=example,此时返回为空 JSON 数组[]。

通过调用 Nacos Open API 向 Nacos server 注册一个名称为 example 服务。

curl -X POST 'http://xxx.0.0.xxx:8848/nacos/v1/ns/instance?serviceName=example&ip=127.0.0.1&port=8080'

再次访问 curl http://localhost:8080/discovery/get?serviceName=example,我们就获取到了这个服务,此时返回内容为:

[
  {
    "instanceId": "127.0.0.1#8080#DEFAULT#example",
    "ip": "127.0.0.1",
    "port": 8080,
    "weight": 1.0,
    "healthy": true,
    "cluster": {
      "serviceName": null,
      "name": "",
      "healthChecker": {
        "type": "TCP"
      },
      "defaultPort": 80,
      "defaultCheckPort": 80,
      "useIPPort4Check": true,
      "metadata": {}
    },
    "service": null,
    "metadata": {}
  }
]

nacos可以替换spring cloud哪些组件?

Nacos作为一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台,可以替换Spring Cloud中的一些关键组件,具体来说,主要有以下几个方面:

  1. 服务注册与发现:Nacos可以作为服务注册中心,替换Spring Cloud中的Eureka或Consul等传统的服务注册与发现组件。Nacos支持基于DNS和RPC的服务发现,能够动态地管理服务实例信息,实现服务之间的通信。
  2. 配置中心:Nacos提供了配置中心的功能,可以替换Spring Cloud Config、Apollo等配置管理组件。Nacos能够集中管理系统各个服务的配置信息,支持动态配置更新、配置监听、配置推送等特性,实现配置的实时更新,而无需重启服务。

综上所述,Nacos通过其强大的服务注册与发现以及配置管理能力,可以有效地替换Spring Cloud中的Eureka、Consul、Spring Cloud Config以及Apollo等组件。

dubbo结合nacos(大致步骤)

Dubbo自带了多种注册中心的实现(Zookeeper、Nacos、Redis等),用于服务提供者和消费者之间的注册与发现。这些注册中心可以是独立的进程,也可以是集成在Dubbo服务提供者或消费者进程中的组件。

以下是Dubbo集成Nacos的基本步骤:

  1. 引入依赖:首先,你需要在你的项目中引入Dubbo和Nacos的相关依赖。这通常是通过在你的pom.xml文件中添加相应的Maven依赖来完成的。
  2. 配置Nacos注册中心:在Dubbo的配置文件中,你需要指定Nacos作为注册中心的地址。这通常包括Nacos服务器的IP地址和端口号。
  3. 服务提供者配置:对于服务提供者,你需要在Dubbo的配置中指定服务的接口和实现类,并设置注册中心为Nacos。这样,当服务提供者启动时,它会将自己提供的服务注册到Nacos中。
  4. 服务消费者配置:对于服务消费者,你也需要在Dubbo的配置中指定需要调用的服务接口,并设置注册中心为Nacos。服务消费者会从Nacos中获取服务提供者的地址列表,并基于这些地址进行服务的调用。

要注意Dubbo和Nacos的版本兼容性是一个重要的问题。你需要确保你使用的Dubbo版本和Nacos版本是兼容的。

下面是一个简化的spring-cloud的示例:

添加依赖

<dependencies>  
    <!-- Dubbo依赖 -->  
    <dependency>  
        <groupId>org.apache.dubbo</groupId>  
        <artifactId>dubbo</artifactId>  
        <version>你的dubbo版本号</version>  
    </dependency>  
    <!-- Nacos客户端依赖 -->  
    <dependency>  
        <groupId>com.alibaba.cloud</groupId>  
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>  
        <version>你的nacos客户端版本号</version>  
    </dependency>  
    <!-- 其他依赖 -->  
</dependencies>
配置Nacos注册中心

在dubbo的配置文件(通常是application.ymlapplication.properties)中,配置Nacos注册中心的地址和其他相关属性:

dubbo:  
  scan:  
    base-packages: com.example.dubboservice # 你的服务接口包路径  
  protocol:  
    name: dubbo  
    port: -1 # 使用随机端口,或者指定端口号  
  registry:  
    address: nacos://localhost:8848 # Nacos注册中心地址
服务提供者配置

对于服务提供者,使用@DubboService注解标记你的实现类,以便dubbo能够扫描到并将其注册到Nacos中。

package com.example.dubboservice.impl;  
  
import com.example.dubboservice.YourService;  
import org.apache.dubbo.config.annotation.DubboService;  
  
@DubboService  
public class YourServiceImpl implements YourService {  
    // 实现服务接口的方法  
}
服务消费者配置

对于服务消费者,使用@DubboReference注解来注入远程服务:

package com.example.dubboclient;  
  
import com.example.dubboservice.YourService;  
import org.apache.dubbo.config.annotation.DubboReference;  
import org.springframework.stereotype.Component;  
  
@Component  
public class YourServiceConsumer {  
    @DubboReference  
    private YourService yourService;  
      
    // 调用远程服务的方法  
    public void doSomething() {  
        yourService.someMethod();  
    }  
}

dubbo结合nacos(完整例子)

1.代码例子

如下是spring-boot版本的例子,搞一个服务提供者dubbo-provider-demo,然后再写上一个消费者去nacos中拉取服务并调用。

这里nacos版本用的是1.1.3,dubbo版本用的是3.0.5,Java版本为1.8

1.首先你的nacos要起来 然后创建一个maven项目,项目结构如下。

2.创建maven项目后,项目pom依赖根据自己的版本配好。

    <dependencies>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>${dubbo.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-registry-nacos</artifactId>
            <version>${dubbo.version}</version>
        </dependency>
        <!-- 使用Spring装配方式时可选: -->
        <dependency>
            <groupId>com.alibaba.spring</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>1.0.11</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.36</version>
        </dependency>
    </dependencies>
    <properties>
        <dubbo.version>3.0.5</dubbo.version>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

3.创建服务提供者的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

4.创建消费者的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

5.创建一个接口,里面创建一个待实现的方法sayName,dubbo服务端和消费端都需要这个接口。

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

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

6.创建服务提供者dubbo-provider-demo对应的启动类DemoServiceProviderBootstrap和服务类DefaultService。

        启动类:

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
 */
//开启dubbo,并扫描对应的路径
@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();
    }
}

        服务类(服务类实现了DemoService接口):

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);
    }
}

7.创建服务消费者dubbo-consumer-demo,并调用DemoService的sayName方法。

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
 */
//开启dubbo
@EnableDubbo
//引入配置
@PropertySource(value = "classpath:/consumer-config.properties")
public class DemoServiceConsumerBootstrap {

    //dubbo的reference,并配置对应的版本号,其实这里注册的就是服务端的远程服务代理对象
    @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();
    }
}

8.我们先启动服务提供者的服务,并在nacos前端管理页面中发现我们的服务提供者已经注册进去了。

9.再启动消费者的服务,可以在控制台看到调用成功。

2.启动解读

我们在服务提供者启动和停止时,可以看到控制台打印了如下一大串的内容,我们来大致看一下启动时干了什么。

"D:\tool\JDK 8\bin\java.exe" -javaagent:D:\tools\idea2019\lib\idea_rt.jar=61533:D:\tools\idea2019\bin -Dfile.encoding=UTF-8 -classpath "D:\tool\JDK 8\jre\lib\charsets.jar;D:\tool\JDK 8\jre\lib\deploy.jar;D:\tool\JDK 8\jre\lib\ext\access-bridge-64.jar;D:\tool\JDK 8\jre\lib\ext\cldrdata.jar;D:\tool\JDK 8\jre\lib\ext\dnsns.jar;D:\tool\JDK 8\jre\lib\ext\jaccess.jar;D:\tool\JDK 8\jre\lib\ext\jfxrt.jar;D:\tool\JDK 8\jre\lib\ext\localedata.jar;D:\tool\JDK 8\jre\lib\ext\nashorn.jar;D:\tool\JDK 8\jre\lib\ext\sunec.jar;D:\tool\JDK 8\jre\lib\ext\sunjce_provider.jar;D:\tool\JDK 8\jre\lib\ext\sunmscapi.jar;D:\tool\JDK 8\jre\lib\ext\sunpkcs11.jar;D:\tool\JDK 8\jre\lib\ext\zipfs.jar;D:\tool\JDK 8\jre\lib\javaws.jar;D:\tool\JDK 8\jre\lib\jce.jar;D:\tool\JDK 8\jre\lib\jfr.jar;D:\tool\JDK 8\jre\lib\jfxswt.jar;D:\tool\JDK 8\jre\lib\jsse.jar;D:\tool\JDK 8\jre\lib\management-agent.jar;D:\tool\JDK 8\jre\lib\plugin.jar;D:\tool\JDK 8\jre\lib\resources.jar;D:\tool\JDK 8\jre\lib\rt.jar;E:\nacos-study\nacos-examples\nacos-dubbo-example\target\classes;E:\mavenRepository\org\apache\dubbo\dubbo\3.0.5\dubbo-3.0.5.jar;E:\mavenRepository\org\springframework\spring-context\5.2.8.RELEASE\spring-context-5.2.8.RELEASE.jar;E:\mavenRepository\org\springframework\spring-aop\5.2.8.RELEASE\spring-aop-5.2.8.RELEASE.jar;E:\mavenRepository\org\springframework\spring-beans\5.2.8.RELEASE\spring-beans-5.2.8.RELEASE.jar;E:\mavenRepository\org\springframework\spring-core\5.2.8.RELEASE\spring-core-5.2.8.RELEASE.jar;E:\mavenRepository\org\springframework\spring-jcl\5.2.8.RELEASE\spring-jcl-5.2.8.RELEASE.jar;E:\mavenRepository\org\springframework\spring-expression\5.2.8.RELEASE\spring-expression-5.2.8.RELEASE.jar;E:\mavenRepository\org\javassist\javassist\3.23.1-GA\javassist-3.23.1-GA.jar;E:\mavenRepository\io\netty\netty-all\4.1.56.Final\netty-all-4.1.56.Final.jar;E:\mavenRepository\com\google\code\gson\gson\2.8.5\gson-2.8.5.jar;E:\mavenRepository\org\yaml\snakeyaml\1.29\snakeyaml-1.29.jar;E:\mavenRepository\com\alibaba\fastjson\1.2.70\fastjson-1.2.70.jar;E:\mavenRepository\org\apache\dubbo\dubbo-registry-nacos\3.0.5\dubbo-registry-nacos-3.0.5.jar;E:\mavenRepository\org\apache\dubbo\dubbo-registry-api\3.0.5\dubbo-registry-api-3.0.5.jar;E:\mavenRepository\org\apache\dubbo\dubbo-cluster\3.0.5\dubbo-cluster-3.0.5.jar;E:\mavenRepository\org\apache\dubbo\dubbo-rpc-api\3.0.5\dubbo-rpc-api-3.0.5.jar;E:\mavenRepository\org\apache\dubbo\dubbo-serialization-api\3.0.5\dubbo-serialization-api-3.0.5.jar;E:\mavenRepository\org\apache\dubbo\dubbo-remoting-api\3.0.5\dubbo-remoting-api-3.0.5.jar;E:\mavenRepository\org\apache\dubbo\dubbo-container-api\3.0.5\dubbo-container-api-3.0.5.jar;E:\mavenRepository\org\apache\dubbo\dubbo-metadata-api\3.0.5\dubbo-metadata-api-3.0.5.jar;E:\mavenRepository\org\apache\dubbo\dubbo-common\3.0.5\dubbo-common-3.0.5.jar;E:\mavenRepository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;E:\mavenRepository\log4j\log4j\1.2.16\log4j-1.2.16.jar;E:\mavenRepository\commons-io\commons-io\2.6\commons-io-2.6.jar;E:\mavenRepository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;E:\mavenRepository\com\alibaba\nacos\nacos-client\2.0.3\nacos-client-2.0.3.jar;E:\mavenRepository\commons-codec\commons-codec\1.11\commons-codec-1.11.jar;E:\mavenRepository\com\fasterxml\jackson\core\jackson-core\2.12.2\jackson-core-2.12.2.jar;E:\mavenRepository\com\fasterxml\jackson\core\jackson-databind\2.12.2\jackson-databind-2.12.2.jar;E:\mavenRepository\com\fasterxml\jackson\core\jackson-annotations\2.12.2\jackson-annotations-2.12.2.jar;E:\mavenRepository\org\apache\httpcomponents\httpasyncclient\4.1.3\httpasyncclient-4.1.3.jar;E:\mavenRepository\org\apache\httpcomponents\httpcore\4.4.6\httpcore-4.4.6.jar;E:\mavenRepository\org\apache\httpcomponents\httpcore-nio\4.4.6\httpcore-nio-4.4.6.jar;E:\mavenRepository\org\apache\httpcomponents\httpclient\4.5.3\httpclient-4.5.3.jar;E:\mavenRepository\org\reflections\reflections\0.9.11\reflections-0.9.11.jar;E:\mavenRepository\com\google\guava\guava\20.0\guava-20.0.jar;E:\mavenRepository\io\prometheus\simpleclient\0.5.0\simpleclient-0.5.0.jar;E:\mavenRepository\com\alibaba\spring\spring-context-support\1.0.11\spring-context-support-1.0.11.jar;E:\mavenRepository\org\slf4j\slf4j-api\1.7.36\slf4j-api-1.7.36.jar" com.alibaba.nacos.example.dubbo.provider.DemoServiceProviderBootstrap
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
[17/05/24 12:53:46:046 CST] main ERROR common.Version:  [DUBBO] Duplicate class org/apache/dubbo/common/Version.class in 2 jar [file:/E:/mavenRepository/org/apache/dubbo/dubbo/3.0.5/dubbo-3.0.5.jar!/org/apache/dubbo/common/Version.class, file:/E:/mavenRepository/org/apache/dubbo/dubbo-common/3.0.5/dubbo-common-3.0.5.jar!/org/apache/dubbo/common/Version.class], dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO model.FrameworkModel:  [DUBBO] Reset global default framework from null to Dubbo Framework[1], dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO model.FrameworkModel:  [DUBBO] Dubbo Framework[1] is created, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO model.ApplicationModel:  [DUBBO] Dubbo Application[1.0](unknown) is created, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO model.ScopeModel:  [DUBBO] Dubbo Module[1.0.0] is created, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO context.AbstractConfigManager:  [DUBBO] Config settings: {dubbo.config.mode=STRICT, dubbo.config.ignore-duplicated-interface=false}, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO context.AbstractConfigManager:  [DUBBO] Config settings: {dubbo.config.mode=STRICT, dubbo.config.ignore-duplicated-interface=false}, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO model.FrameworkModel:  [DUBBO] Reset global default application from null to Dubbo Application[1.1](unknown), dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO model.ApplicationModel:  [DUBBO] Dubbo Application[1.1](unknown) is created, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO model.ScopeModel:  [DUBBO] Dubbo Module[1.1.0] is created, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO context.AbstractConfigManager:  [DUBBO] Config settings: {dubbo.config.mode=STRICT, dubbo.config.ignore-duplicated-interface=false}, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO context.AbstractConfigManager:  [DUBBO] Config settings: {dubbo.config.mode=STRICT, dubbo.config.ignore-duplicated-interface=false}, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO context.DubboSpringInitializer:  [DUBBO] Use default application: Dubbo Application[1.1](unknown), dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO model.ScopeModel:  [DUBBO] Dubbo Module[1.1.1] is created, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO context.AbstractConfigManager:  [DUBBO] Config settings: {dubbo.config.mode=STRICT, dubbo.config.ignore-duplicated-interface=false}, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO context.DubboSpringInitializer:  [DUBBO] Use default module model of target application: Dubbo Module[1.1.1], dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO context.DubboSpringInitializer:  [DUBBO] Bind Dubbo Module[1.1.1] to spring container: org.springframework.beans.factory.support.DefaultListableBeanFactory@5bc79255, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO annotation.ServiceAnnotationPostProcessor:  [DUBBO] BeanNameGenerator bean can't be found in BeanFactory with name [org.springframework.context.annotation.internalConfigurationBeanNameGenerator], dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO annotation.ServiceAnnotationPostProcessor:  [DUBBO] BeanNameGenerator will be a instance of org.springframework.context.annotation.AnnotationBeanNameGenerator , it maybe a potential problem on bean name generation., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO annotation.ServiceAnnotationPostProcessor:  [DUBBO] Found 1 classes annotated by Dubbo @Service under package [com.alibaba.nacos.example.dubbo.service]: [com.alibaba.nacos.example.dubbo.service.DefaultService], dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO annotation.ServiceAnnotationPostProcessor:  [DUBBO] Register ServiceBean[ServiceBean:com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0]: Root bean: class [org.apache.dubbo.config.spring.ServiceBean]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO deploy.DefaultApplicationDeployer:  [DUBBO] No value is configured in the registry, the DynamicConfigurationFactory extension[name : nacos] supports as the config center, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO deploy.DefaultApplicationDeployer:  [DUBBO] The registry[<dubbo:registry address="nacos://127.0.0.1:8848" protocol="nacos" port="8848" />] will be used as the config center, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:46:046 CST] main  INFO deploy.DefaultApplicationDeployer:  [DUBBO] use registry as config-center: <dubbo:config-center highestPriority="false" id="config-center-nacos-127.0.0.1-8848" address="nacos://127.0.0.1:8848" protocol="nacos" port="8848" />, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  WARN config.ConfigurationUtils:  [DUBBO] You specified the config center, but there's not even one single config item in it., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  WARN config.ConfigurationUtils:  [DUBBO] You specified the config center, but there's not even one single config item in it., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  INFO deploy.DefaultModuleDeployer:  [DUBBO] Dubbo Module[1.1.0] has been initialized!, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  INFO deploy.DefaultModuleDeployer:  [DUBBO] Dubbo Module[1.1.1] has been initialized!, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  INFO deploy.DefaultApplicationDeployer:  [DUBBO] No value is configured in the registry, the MetadataReportFactory extension[name : nacos] supports as the metadata center, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  INFO deploy.DefaultApplicationDeployer:  [DUBBO] The registry[<dubbo:registry address="nacos://127.0.0.1:8848" protocol="nacos" port="8848" />] will be used as the metadata center, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  INFO deploy.DefaultApplicationDeployer:  [DUBBO] use registry as metadata-center: <dubbo:metadata-report id="metadata-center-nacos-127.0.0.1-8848" address="nacos://127.0.0.1:8848" protocol="nacos" port="8848" />, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  INFO deploy.DefaultApplicationDeployer:  [DUBBO] Dubbo Application[1.1](dubbo-provider-demo) has been initialized!, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  INFO deploy.DefaultModuleDeployer:  [DUBBO] Dubbo Module[1.1.1] is starting., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  INFO deploy.DefaultApplicationDeployer:  [DUBBO] Dubbo Application[1.1](dubbo-provider-demo) is starting., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  WARN config.ServiceConfig:  [DUBBO] Use random available port(20880) for protocol dubbo, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  INFO config.ServiceConfig:  [DUBBO] Export dubbo service com.alibaba.nacos.example.dubbo.service.DemoService to local registry url : injvm://127.0.0.1/com.alibaba.nacos.example.dubbo.service.DemoService?anyhost=true&application=dubbo-provider-demo&background=false&bind.ip=192.168.56.1&bind.port=20880&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.alibaba.nacos.example.dubbo.service.DemoService&metadata-type=remote&methods=sayName&pid=9292&qos.enable=false&release=3.0.5&revision=1.0.0&side=provider&timestamp=1715921631498&version=1.0.0, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  INFO config.ServiceConfig:  [DUBBO] Register dubbo service com.alibaba.nacos.example.dubbo.service.DemoService url com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0 to registry 127.0.0.1:8848, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main  INFO protocol.QosProtocolWrapper:  [DUBBO] qos won't be started because it is disabled. Please check dubbo.application.qos.enable is configured either in system property, dubbo.properties or XML/spring-boot configuration., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main ERROR common.Version:  [DUBBO] Duplicate class org/apache/dubbo/remoting/exchange/Exchangers.class in 2 jar [file:/E:/mavenRepository/org/apache/dubbo/dubbo/3.0.5/dubbo-3.0.5.jar!/org/apache/dubbo/remoting/exchange/Exchangers.class, file:/E:/mavenRepository/org/apache/dubbo/dubbo-remoting-api/3.0.5/dubbo-remoting-api-3.0.5.jar!/org/apache/dubbo/remoting/exchange/Exchangers.class], dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main ERROR common.Version:  [DUBBO] Duplicate class org/apache/dubbo/remoting/Transporters.class in 2 jar [file:/E:/mavenRepository/org/apache/dubbo/dubbo-remoting-api/3.0.5/dubbo-remoting-api-3.0.5.jar!/org/apache/dubbo/remoting/Transporters.class, file:/E:/mavenRepository/org/apache/dubbo/dubbo/3.0.5/dubbo-3.0.5.jar!/org/apache/dubbo/remoting/Transporters.class], dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:51:051 CST] main ERROR common.Version:  [DUBBO] Duplicate class org/apache/dubbo/remoting/RemotingException.class in 2 jar [file:/E:/mavenRepository/org/apache/dubbo/dubbo/3.0.5/dubbo-3.0.5.jar!/org/apache/dubbo/remoting/RemotingException.class, file:/E:/mavenRepository/org/apache/dubbo/dubbo-remoting-api/3.0.5/dubbo-remoting-api-3.0.5.jar!/org/apache/dubbo/remoting/RemotingException.class], dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO transport.AbstractServer:  [DUBBO] Start NettyServer bind /0.0.0.0:20880, export /192.168.56.1:20880, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO client.ServiceDiscoveryRegistry:  [DUBBO] The URL[dubbo://192.168.56.1:20880/com.alibaba.nacos.example.dubbo.service.DemoService?anyhost=true&application=dubbo-provider-demo&background=false&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.alibaba.nacos.example.dubbo.service.DemoService&metadata-type=remote&methods=sayName&pid=9292&release=3.0.5&revision=1.0.0&service-name-mapping=true&side=provider&timestamp=1715921631498&version=1.0.0] registered successfully., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO migration.MigrationRuleListener:  [DUBBO] Listening for migration rules on dataId dubbo-provider-demo.migration, group DUBBO_SERVICEDISCOVERY_MIGRATION, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO config.ServiceConfig:  [DUBBO] Register dubbo service com.alibaba.nacos.example.dubbo.service.DemoService url com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0 to registry 127.0.0.1:8848, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO protocol.QosProtocolWrapper:  [DUBBO] qos won't be started because it is disabled. Please check dubbo.application.qos.enable is configured either in system property, dubbo.properties or XML/spring-boot configuration., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO nacos.NacosRegistry:  [DUBBO] Register: dubbo://192.168.56.1:20880/com.alibaba.nacos.example.dubbo.service.DemoService?anyhost=true&application=dubbo-provider-demo&background=false&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.alibaba.nacos.example.dubbo.service.DemoService&metadata-type=remote&methods=sayName&pid=9292&release=3.0.5&revision=1.0.0&service-name-mapping=true&side=provider&timestamp=1715921631498&version=1.0.0, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO nacos.NacosRegistry:  [DUBBO] Subscribe: provider://192.168.56.1:20880/com.alibaba.nacos.example.dubbo.service.DemoService?anyhost=true&application=dubbo-provider-demo&background=false&bind.ip=192.168.56.1&bind.port=20880&category=configurators&check=false&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.alibaba.nacos.example.dubbo.service.DemoService&metadata-type=remote&methods=sayName&pid=9292&qos.enable=false&release=3.0.5&revision=1.0.0&service-name-mapping=true&side=provider&timestamp=1715921631498&version=1.0.0, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  WARN nacos.NacosRegistry:  [DUBBO] Ignore empty notify urls for subscribe url provider://192.168.56.1:20880/com.alibaba.nacos.example.dubbo.service.DemoService?anyhost=true&application=dubbo-provider-demo&background=false&bind.ip=192.168.56.1&bind.port=20880&category=configurators&check=false&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.alibaba.nacos.example.dubbo.service.DemoService&metadata-type=remote&methods=sayName&pid=9292&qos.enable=false&release=3.0.5&revision=1.0.0&service-name-mapping=true&side=provider&timestamp=1715921631498&version=1.0.0, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] DubboSaveMetadataReport-thread-1  INFO nacos.NacosMetadataReport:  [DUBBO] store provider metadata. Identifier : org.apache.dubbo.metadata.report.identifier.MetadataIdentifier@7b4b69e8; definition: FullServiceDefinition{parameters=org.apache.dubbo.common.url.component.URLParam$URLParamMap@16aff98d} ServiceDefinition [canonicalName=com.alibaba.nacos.example.dubbo.service.DemoService, codeSource=file:/E:/nacos-study/nacos-examples/nacos-dubbo-example/target/classes/, methods=[MethodDefinition [name=sayName, parameterTypes=[java.lang.String], returnType=java.lang.String]]], dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO config.ServiceConfig:  [DUBBO] Successfully registered interface application mapping for service com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO deploy.DefaultModuleDeployer:  [DUBBO] Dubbo Module[1.1.0] is starting., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO deploy.DefaultModuleDeployer:  [DUBBO] Dubbo Module[1.1.0] has started., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO metadata.ConfigurableMetadataServiceExporter:  [DUBBO] Metadata Service Port hasn't been set will use default protocol defined in protocols., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO metadata.ConfigurableMetadataServiceExporter:  [DUBBO] Using dubbo protocol to export MetadataService on port 20880, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO metadata.ConfigurableMetadataServiceExporter:  [DUBBO] Using dubbo protocol to export metadata service on port 20880, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO config.ServiceConfig:  [DUBBO] Export dubbo service org.apache.dubbo.metadata.MetadataService to local registry url : injvm://127.0.0.1/org.apache.dubbo.metadata.MetadataService?anyhost=true&application=dubbo-provider-demo&background=false&bind.ip=192.168.56.1&bind.port=20880&connections=1&delay=0&deprecated=false&dubbo=2.0.2&dynamic=true&executes=100&generic=false&getAndListenInstanceMetadata.1.callback=true&getAndListenInstanceMetadata.return=true&getAndListenInstanceMetadata.sent=true&group=dubbo-provider-demo&interface=org.apache.dubbo.metadata.MetadataService&metadata-type=remote&methods=getExportedURLs,getAndListenInstanceMetadata,toURLs,serviceName,isMetadataServiceURL,version,getSubscribedURLs,getExportedServiceURLs,exportInstanceMetadata,getMetadataInfo,toSortedStrings,getMetadataInfos,getServiceDefinition,getInstanceMetadataChangedListenerMap&pid=9292&qos.enable=false&release=3.0.5&revision=3.0.5&side=provider&timestamp=1715921633928&version=1.0.0, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO config.ServiceConfig:  [DUBBO] Export dubbo service org.apache.dubbo.metadata.MetadataService to url dubbo://192.168.56.1:20880/org.apache.dubbo.metadata.MetadataService?anyhost=true&application=dubbo-provider-demo&background=false&bind.ip=192.168.56.1&bind.port=20880&connections=1&delay=0&deprecated=false&dubbo=2.0.2&dynamic=true&executes=100&generic=false&getAndListenInstanceMetadata.1.callback=true&getAndListenInstanceMetadata.return=true&getAndListenInstanceMetadata.sent=true&group=dubbo-provider-demo&interface=org.apache.dubbo.metadata.MetadataService&metadata-type=remote&methods=getExportedURLs,getAndListenInstanceMetadata,toURLs,serviceName,isMetadataServiceURL,version,getSubscribedURLs,getExportedServiceURLs,exportInstanceMetadata,getMetadataInfo,toSortedStrings,getMetadataInfos,getServiceDefinition,getInstanceMetadataChangedListenerMap&pid=9292&qos.enable=false&release=3.0.5&revision=3.0.5&side=provider&timestamp=1715921633928&version=1.0.0, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO metadata.ConfigurableMetadataServiceExporter:  [DUBBO] The MetadataService exports urls : [dubbo://192.168.56.1:20880/org.apache.dubbo.metadata.MetadataService?anyhost=true&application=dubbo-provider-demo&background=false&bind.ip=192.168.56.1&bind.port=20880&connections=1&delay=0&deprecated=false&dubbo=2.0.2&dynamic=true&executes=100&generic=false&getAndListenInstanceMetadata.1.callback=true&getAndListenInstanceMetadata.return=true&getAndListenInstanceMetadata.sent=true&group=dubbo-provider-demo&interface=org.apache.dubbo.metadata.MetadataService&metadata-type=remote&methods=getExportedURLs,getAndListenInstanceMetadata,toURLs,serviceName,isMetadataServiceURL,version,getSubscribedURLs,getExportedServiceURLs,exportInstanceMetadata,getMetadataInfo,toSortedStrings,getMetadataInfos,getServiceDefinition,getInstanceMetadataChangedListenerMap&pid=9292&qos.enable=false&release=3.0.5&revision=3.0.5&side=provider&timestamp=1715921633928&version=1.0.0], dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] DubboSaveMetadataReport-thread-1  INFO nacos.NacosMetadataReport:  [DUBBO] store provider metadata. Identifier : org.apache.dubbo.metadata.report.identifier.MetadataIdentifier@7a278fd7; definition: FullServiceDefinition{parameters=org.apache.dubbo.common.url.component.URLParam$URLParamMap@75a9a70d} ServiceDefinition [canonicalName=org.apache.dubbo.metadata.MetadataService, codeSource=dubbo-3.0.5.jar, methods=[MethodDefinition [name=version, parameterTypes=[], returnType=java.lang.String], MethodDefinition [name=getInstanceMetadataChangedListenerMap, parameterTypes=[], returnType=java.util.Map<java.lang.String,org.apache.dubbo.metadata.InstanceMetadataChangedListener>], MethodDefinition [name=getMetadataInfo, parameterTypes=[java.lang.String], returnType=org.apache.dubbo.metadata.MetadataInfo], MethodDefinition [name=getMetadataInfos, parameterTypes=[], returnType=java.util.Map<java.lang.String,org.apache.dubbo.metadata.MetadataInfo>], MethodDefinition [name=getExportedURLs, parameterTypes=[java.lang.String], returnType=java.util.SortedSet<java.lang.String>], MethodDefinition [name=getExportedURLs, parameterTypes=[], returnType=java.util.SortedSet<java.lang.String>], MethodDefinition [name=getExportedURLs, parameterTypes=[java.lang.String, java.lang.String, java.lang.String], returnType=java.util.SortedSet<java.lang.String>], MethodDefinition [name=getExportedURLs, parameterTypes=[java.lang.String, java.lang.String], returnType=java.util.SortedSet<java.lang.String>], MethodDefinition [name=getExportedURLs, parameterTypes=[java.lang.String, java.lang.String, java.lang.String, java.lang.String], returnType=java.util.SortedSet<java.lang.String>], MethodDefinition [name=serviceName, parameterTypes=[], returnType=java.lang.String], MethodDefinition [name=getExportedServiceURLs, parameterTypes=[], returnType=java.util.Set<org.apache.dubbo.common.URL>], MethodDefinition [name=exportInstanceMetadata, parameterTypes=[java.lang.String], returnType=void], MethodDefinition [name=getSubscribedURLs, parameterTypes=[], returnType=java.util.SortedSet<java.lang.String>], MethodDefinition [name=getAndListenInstanceMetadata, parameterTypes=[java.lang.String, org.apache.dubbo.metadata.InstanceMetadataChangedListener], returnType=java.lang.String], MethodDefinition [name=getServiceDefinition, parameterTypes=[java.lang.String, java.lang.String, java.lang.String], returnType=java.lang.String], MethodDefinition [name=getServiceDefinition, parameterTypes=[java.lang.String], returnType=java.lang.String]]], dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO metadata.ServiceInstanceMetadataUtils:  [DUBBO] Start registering instance address to registry., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO metadata.MetadataInfo:  [DUBBO] metadata revision changed: null -> df52a76a07d5245e54975809553beb23, app: dubbo-provider-demo, services: 1, dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO deploy.DefaultModuleDeployer:  [DUBBO] Dubbo Module[1.1.1] has started., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:53:53:053 CST] main  INFO deploy.DefaultApplicationDeployer:  [DUBBO] Dubbo Application[1.1](dubbo-provider-demo) is ready., dubbo version: 3.0.5, current host: 192.168.56.1
DemoService provider is starting...
[17/05/24 12:54:22:022 CST] NettyServerWorker-3-1  INFO netty4.NettyServerHandler:  [DUBBO] The connection of /192.168.56.1:61743 -> /192.168.56.1:20880 is established., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:54:22:022 CST] NettyServerWorker-3-2  INFO netty4.NettyServerHandler:  [DUBBO] The connection of /192.168.56.1:61745 -> /192.168.56.1:20880 is established., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:54:22:022 CST] NettyServerWorker-3-2  INFO netty4.NettyServerHandler:  [DUBBO] The connection of /192.168.56.1:61745 -> /192.168.56.1:20880 is disconnected., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:54:22:022 CST] NettyServerWorker-3-1  WARN transport.AbstractServer:  [DUBBO] All clients has disconnected from /192.168.56.1:20880. You can graceful shutdown now., dubbo version: 3.0.5, current host: 192.168.56.1
[17/05/24 12:54:22:022 CST] NettyServerWorker-3-1  INFO netty4.NettyServerHandler:  [DUBBO] The connection of /192.168.56.1:61743 -> /192.168.56.1:20880 is disconnected., dubbo version: 3.0.5, current host: 192.168.56.1

Process finished with exit code -1

大致看一下里面的打印信息。

1.首先可看到dubbo的Framework,Application,Module创建了,还打印出了版本以及本地IP

Dubbo Framework[1] is created, dubbo version: 3.0.5, current host: 192.168.56.1

Dubbo Application[1.0](unknown) is created, dubbo version: 3.0.5, current host: 192.168.56.1

Dubbo Module[1.0.0] is created, dubbo version: 3.0.5, current host: 192.168.56.1

2.只扫描到了一个带有dubbo的@service的类,这里我们确实只有一个类,然后将这个bean注册成servicebean。

Found 1 classes annotated by Dubbo @Service under package [com.alibaba.nacos.example.dubbo.service]

但是我们去看消费者启动的日志,发现打印如下,确实没有类被注册。

[DUBBO] No class annotated by Dubbo @Service was found under package

3.由于我们配置了注册中心也为nacos,dubbo.registry.address = nacos://127.0.0.1:8848 

   可以看到配置中心选为了nacos。

The registry[<dubbo:registry address="nacos://127.0.0.1:8848" protocol="nacos" port="8848" />] will be used as the config center, dubbo version: 3.0.5, current host: 192.168.56.1

use registry as config-center: <dubbo:config-center highestPriority="false" id="config-center-nacos-127.0.0.1-8848" address="nacos://127.0.0.1:8848" protocol="nacos" port="8848" />

4.虽然我们用了这个配置中心,但是里面没有配置项。

[DUBBO] You specified the config center, but there's not even one single config item in it., dubbo version: 3.0.5, current host: 192.168.56.1

5.由于我们配了这个dubbo.protocol.port = -1 ,所以dubbo随机选了一个端口作为服务端口

[DUBBO] Use random available port(20880) for protocol dubbo, dubbo version: 3.0.5, current host: 192.168.56.1

6.dubbo其实也会去nacos导一份服务清单到本地作为一个副本,并且它将在当前JVM内部通过injvm://协议进行通信,可以看出我们发布的这个它也导回来了,虽然它是服务端但是它作为nacos的客户端也会去nacos拉一份上面注册的服务。

[DUBBO] Export dubbo service com.alibaba.nacos.example.dubbo.service.DemoService to local registry url : injvm://127.0.0.1/com.alibaba.nacos.example.dubbo.service.DemoService?anyhost=true&application=dubbo-provider-demo&background=false&bind.ip=192.168.56.1&bind.port=20880&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.alibaba.nacos.example.dubbo.service.DemoService&metadata-type=remote&methods=sayName&pid=9292&qos.enable=false&release=3.0.5&revision=1.0.0&side=provider&timestamp=1715921631498&version=1.0.0, dubbo version: 3.0.5, current host: 192.168.56.1

7.由于我们没有启用qos(dubbo.application.qosEnable=false;dubbo的服务质量检测),所以打印了如下日志:

[DUBBO] qos won't be started because it is disabled. Please check dubbo.application.qos.enable is configured either in system property, dubbo.properties or XML/spring-boot configuration.

8.最后服务启动了

DemoService provider is starting...

我们在日志里看到了几次如下类似于url的日志,是什么意思呢?

dubbo://192.168.56.1:20880/com.alibaba.nacos.example.dubbo.service.DemoService?anyhost=true&application=dubbo-provider-demo&background=false&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.alibaba.nacos.example.dubbo.service.DemoService&metadata-type=remote&methods=sayName&pid=9292&release=3.0.5&revision=1.0.0&service-name-mapping=true&side=provider&timestamp=1715921631498&version=1.0.0 

这个URL是Dubbo服务提供者用于注册到注册中心的URL,它包含了服务提供者的相关信息和配置。下面是对URL中各个参数的详细解释:

  1. dubbo://
    这是Dubbo的协议部分,表示这是一个Dubbo RPC服务。

  2. 192.168.56.1:20880
    这是服务提供者的IP地址和端口号(其实就是我本机电脑的地址),用于指定服务提供者的网络位置。其他服务消费者将使用这个地址和端口号来调用服务。

  3. /com.alibaba.nacos.example.dubbo.service.DemoService
    这是Dubbo服务的接口路径,对应于服务的接口全限定名。在这个例子中,服务接口是com.alibaba.nacos.example.dubbo.service.DemoService

  4. 参数列表
    接下来的部分是一系列的参数,它们用&符号分隔,每个参数由键和值组成,用于配置服务的各种属性和行为。

    • anyhost=true
      表示服务提供者支持接收来自任何主机的调用。

    • application=dubbo-provider-demo
      表示应用名,用于标识和区分不同的Dubbo应用。

    • background=false
      这个参数的具体含义可能取决于Dubbo的版本和配置,但通常用于指示某些操作是否应在后台执行。

    • deprecated=false
      表示这个服务接口是否已被废弃。如果设置为true,可能意味着该接口在未来的版本中将不再被支持。

    • dubbo=2.0.2
      表示Dubbo的版本号。

    • dynamic=true
      表示服务是否动态注册。如果设置为true,服务提供者可以在运行时动态地注册和注销服务。

    • generic=false
      表示是否使用泛化调用。如果设置为true,消费者可以使用GenericService接口来调用服务,而不需要知道具体的接口方法。

    • interface=com.alibaba.nacos.example.dubbo.service.DemoService
      与服务路径相同,再次指定了服务的接口全限定名。这个参数是冗余的,但某些情况下可能用于额外的校验或配置。

    • metadata-type=remote
      表示元数据的存储类型。在这个例子中,元数据存储在远程的注册中心。

    • methods=sayName
      列出了服务中可调用的方法。在这个例子中,只有sayName方法是可以被调用的。注意,这只是一个示例,实际的服务可能包含多个方法。

    • pid=9292
      表示服务提供者进程的ID。

    • release=3.0.5
      可能是Dubbo或相关依赖库的版本号。

    • revision=1.0.0
      表示服务的版本号,用于区分不同版本的服务。

    • service-name-mapping=true
      这个参数的具体含义可能取决于Dubbo的版本和配置,但可能与服务名的映射或别名有关。

    • side=provider
      表示当前的角色是服务提供者。Dubbo中有两种角色:提供者(provider)和消费者(consumer)。

    • timestamp=1715921631498
      表示这个URL被创建或修改的时间戳。

    • version=1.0.0
      与服务版本revision类似,但具体含义和使用场景可能有所不同。在某些情况下,version可能用于表示服务的API版本。

这个URL是Dubbo服务注册和发现的基础,它包含了服务提供者的所有必要信息,使得其他服务消费者能够找到并调用这个服务。

nacos spring

1.注解驱动
1.1启用nacos

@EnableNacos是一个模块驱动的注解,它支持 Nacos Spring 的所有功能,包括服务发现配置管理。它等于 @EnableNacosDiscovery 加上 @EnableNacosConfig,可以单独配置并在不同场景中使用。

比如说我只想获取报告,那么可以只配置@EnableNacosConfig:

@Configuration
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848"))

/**
 * Document: https://nacos.io/zh-cn/docs/quick-start-spring.html
 * <p>
 * Nacos 控制台添加配置:
 * <p>
 * Data ID:example
 * <p>
 * Group:DEFAULT_GROUP
 * <p>
 * 配置内容:useLocalCache=true
 */
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class NacosConfiguration {

}
1.2配置监听

先想一下,nacos为啥要对配置进行监听。Nacos配置监听的主要作用是允许应用程序实时感知Nacos配置中心上的配置变更,这对于需要频繁修改配置的场景来说非常有用,可以大大提高应用程序的可维护性和可扩展性。

假设在 Nacos 服务中有一个配置,其 dataId 是 “testDataId” 而 groupId 是默认组(“DEFAULT_GROUP”)。 现在,您可以使用 ConfigService#publishConfig 方法更改其内容:

@NacosInjected
private ConfigService configService;

@Test
public void testPublishConfig() throws NacosException {
    configService.publishConfig(DATA_ID, DEFAULT_GROUP, "9527");
}

然后您可以添加一个监听器,它将监听配置的变化。 您可以通过在 Spring Bean 中添加配置变更监听器方法来执行此操作:

@NacosConfigListener(dataId = DATA_ID)
public void onMessage(String config) {
    assertEquals("mercyblitz", config); // asserts true
}

下面的代码具有相同的效果:

configService.addListener(DATA_ID, DEFAULT_GROUP, new AbstractListener() {
    @Override
    public void receiveConfigInfo(String config) {
        assertEquals("9527", config); // asserts true
    }
});

  • 10
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值