springcloud使用nacos进行服务注册与发现

自从有了spring-cloud-alibaba的开源之后,springcloud中使用nacos进行服务的注册与发现就已变得非常容易,只需要引入“spring-cloud-starter-alibaba-nacos-discovery”即可,然后开启@EnableDiscoveryClient,便可以做到无缝替换eureka和consul等注册中心。

下面通过给出一个简单的案例来演示springcloud中如何使用nacos。

nacos-discovery-stater原理

首先来看一下springcloud中nacos进行服务注册与发现的原理。

服务注册

spring-cloud-starter-alibaba-nacos-discovery遵循了spring-cloud-common标准,实现了 AutoServiceRegistration、ServiceRegistry、Registration 这三个接口。

在springcloud应用的启动阶段,监听了WebServerInitializedEvent事件,当Web容器初始化完成后,即收到WebServerInitializedEvent 事件后,会触发注册的动作,调用ServiceRegistry的register方法,将服务注册到 Nacos Server。

服务发现

NacosServerList 实现了 com.netflix.loadbalancer.ServerList 接口,并在 @ConditionOnMissingBean 的条件下进行自动注入,默认集成了Ribbon。

如果需要有更加自定义的可以使用 @Autowired 注入一个 NacosRegistration 实例,通过其持有的 NamingService 字段内容直接调用 Nacos API。

nacos-service-provider

创建一个服务提供者的springcloud项目,引入如下依赖:

    <properties>
        <spring-cloud.version>Greenwich.SR1spring-cloud.version>
        <spring-cloud.alibaba.version>0.2.1.RELEASEspring-cloud.alibaba.version>
    properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>${spring-cloud.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                <version>${spring-cloud.alibaba.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
    dependencies>

在项目的application.yml文件中配置nacos相关的配置信息如下:

如果不想使用 Nacos 作为您的服务注册与发现,可以将 spring.cloud.nacos.discovery 设置为 false。

spring:
  application:
    name: nacos-service-provider
  cloud:
    nacos:
      discovery:
        register-enabled: true
        server-addr: 127.0.0.1:8848
        weight: 1
        namespace: dev
management:
  endpoints:
    web:
      exposure:
        include: "*"

server:
  port: 8080

接着便是创建一个服务,供调用者使用,勿忘在主函数引入@EnableDiscoveryClient注解。

package com.lazycece.scac.nacos.discovery.provider.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author lazycece
 * @date 2019/03/19
 */
@RestController
@RequestMapping("/nacos")
public class NacosProviderController {
    @GetMapping("/provider/{name}")
    public String provider(@PathVariable String name) {
        return "hello," + name;
    }
}

nacos-service-consumer

创建一个服务消费者的springcloud项目,引入如下依赖,这里多引入了open-feign和ribbon的依赖,是为了同时演示这两种方式的消费。

    <properties>
        <spring-cloud.version>Greenwich.SR1spring-cloud.version>
        <spring-cloud.alibaba.version>0.2.1.RELEASEspring-cloud.alibaba.version>
    properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-dependenciesartifactId>
                <version>${spring-cloud.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
            <dependency>
                <groupId>org.springframework.cloudgroupId>
                <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                <version>${spring-cloud.alibaba.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>
        <dependencies>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-netflix-ribbonartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-openfeignartifactId>
        dependency>
    dependencies>

在项目的application.yml文件中配置nacos相关的配置信息如下:

如果不想使用 Nacos 作为您的服务注册与发现,可以将 spring.cloud.nacos.discovery 设置为 false.

spring:
  application:
    name: nacos-service-consumer
  cloud:
    nacos:
      discovery:
        register-enabled: true
        server-addr: 127.0.0.1:8848
        weight: 1
        namespace: dev
management:
  endpoints:
    web:
      exposure:
        include: "*"

server:
  port: 8081

创建服务消费者的代码如下,勿忘在主函数引入@EnableDiscoveryClient注解。

package com.lazycece.scac.nacos.discovery.consumer.controller;

import com.lazycece.scac.nacos.discovery.consumer.api.FeignConsumerApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author lazycece
 * @date 2019/03/19
 */
@RestController
@RequestMapping("/nacos/consumer")
public class NacosConsumerController {

    private LoadBalancerClient loadBalancerClient;
    private RestTemplate restTemplate;
    private FeignConsumerApi feignConsumerApi;

    @Autowired
    public NacosConsumerController(LoadBalancerClient loadBalancerClient, RestTemplate restTemplate,
                                   FeignConsumerApi feignConsumerApi) {
        this.loadBalancerClient = loadBalancerClient;
        this.restTemplate = restTemplate;
        this.feignConsumerApi = feignConsumerApi;
    }

    @GetMapping("/rest/{name}")
    public String rest(@PathVariable String name) {
        ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-service-provider");
        String url = String.format("http://%s:%s/nacos/provider/%s",
                serviceInstance.getHost(), serviceInstance.getPort(), name);
        System.out.println("url -> " + url);
        return restTemplate.getForObject(url, String.class);
    }

    @GetMapping("/feign/{name}")
    public String feign(@PathVariable String name) {
        return feignConsumerApi.provider(name);
    }


    @GetMapping("/ribbon/{name}")
    public String ribbon(@PathVariable String name) {
        return restTemplate.getForObject("http://nacos-service-provider/nacos/provider/" +
                name, String.class);
    }
}

要使用rest方式消费,需要注入RestTemplate,如果需要用ribbon来进行负载均衡,则可以@LoadBalanced注解,否则可以不加。

package com.lazycece.scac.nacos.discovery.consumer.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @author lazycece
 * @date 2019/03/19
 */
@Configuration
public class RestTemplateConfig {

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

使用feign方式消费,需要有feign的client,如下,且项目主函数还需引入@EnableFeignClients
注解。

package com.lazycece.scac.nacos.discovery.consumer.api;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author lazycece
 * @date 2019/03/19
 */
@FeignClient("nacos-service-provider")
@RequestMapping("/nacos")
public interface FeignConsumerApi {

    @GetMapping("/provider/{name}")
    String provider(@PathVariable String name);
}

服务注册与发现案例验证

需要先启动nacos-server服务,安装部署详见 nacos安装部署

服务的 EndPoint

spring-cloud-starter-alibaba-nacos-discovery 在实现的时候提供了一个EndPoint,EndPoint的访问地址为 http://ip:port/actuator/nacos-discovery 。因为我们加了 spring-boot-starter-actuator 依赖,所以可以查看endpoint信息。EndPoint 的信息主要提供了两类:

  • subscribe: 显示了当前有哪些服务订阅者
  • NacosDiscoveryProperties: 显示了当前服务实例关于 Nacos 的基础配置

其中一个服务实例访问 EndPoint 的信息如下所示:

{
    "subscribe":[

    ],
    "NacosDiscoveryProperties":{
        "serverAddr":"127.0.0.1:8848",
        "endpoint":"",
        "namespace":"dev",
        "logName":"",
        "service":"nacos-service-provider",
        "weight":1,
        "clusterName":"DEFAULT",
        "namingLoadCacheAtStart":"false",
        "metadata":{

        },
        "registerEnabled":true,
        "ip":"192.168.3.8",
        "networkInterface":"",
        "port":8080,
        "secure":false,
        "accessKey":"",
        "secretKey":""
    }
}

nacos管界面

访问 http://localhost:8848/nacos/ 进入nacos的管理界面,查看 服务管理->服务列表 模块,便可以看到我们的服务消费者和提供者已经注册到nacos上了,如下图所示:

springcloud使用nacos进行服务注册与发现_第1张图片

服务消费

这里需要先启动nacos服务,然后启动上面两个服务,访问如下地址:
http://localhost:8081/nacos/consumer/rest/lazycece
http://localhost:8081/nacos/consumer/ribbon/lazycece
http://localhost:8081/nacos/consumer/feign/lazycece

输出信息:hello,lazycece

更多springcloud nacos信息

关于 spring-cloud-starter-alibaba-nacos-discovery 中的其他配置信息如下图所示:

springcloud使用nacos进行服务注册与发现_第2张图片

案例源码

案例源码地址:
https://github.com/lazycece/springcloud-actual-combat/tree/master/springcloud-ac-nacos-discovery

你可能感兴趣的:(springcloud)