Nacos

简介

​ Nacos 是 Spring Cloud Alibaba 生态中的一个开源组件。Nacos 致力于发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助开发人员快速实现动态服务发现、服务配置、服务元数据及流量管理。

主要功能

  1. 服务注册和发现,适配了Spring Cloud 服务注册与发现标准,默认集成了 Ribbon(一个负载均衡的客户端) 。
  2. 动态配置服务,中心化、外部化、动态化的方式管理所有环境的配置,配置更改时无需重新部署服务。
  3. 动态 DNS 服务,对于每一个服务实例可以灵活设置权重来达到负载均衡、流量控制。
  4. 服务及其元数据管理,可以对服务进行更详细的描述,达到对服务的细粒化控制。

Nacos 搭建

Note:本实例使用 Nacos 源码来使用Nacos.

准备:clone源码到本地

一、利用 IDEA 创建一个父项目MicroServices,删除掉不需要的文件夹

二、在 pom 文件中添加 spring cloud alibaba 依赖。

	<?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.local</groupId>
  <artifactId>Microservices</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>${project.artifactId}</name>
  <packaging>pom</packaging>
  
  <properties>
    <spring-boot.version>2.1.7.RELEASE</spring-boot.version>
    <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    <spring-cloud-alibaba.version>2.1.0.RELEASE</spring-cloud-alibaba.version>
  </properties>

  <!--子模块管理-->
  <modules>
    <module>nacos</module>
  </modules>
  
  <!--所有的子模块默认依赖-->
  <dependencies>
    <!--配置文件处理器-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-configuration-processor</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  
  <!--管理依赖版本号,子模块不会默认依赖-->
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring-boot.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <!--spring cloud alibaba-->
      <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>${spring-cloud-alibaba.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

三、将 nacos 源码中的 console 文件夹改名为nacos。并修改pom文件。

<?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>

    <parent>
        <groupId>com.local</groupId>
        <artifactId>Microservices</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    
    <artifactId>nacos</artifactId>
    <packaging>jar</packaging>
    <name>nacos</name>
    
    <dependencies>
        <!--测试依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-config</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-naming</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.10.5</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.10.5</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.10.5</version>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
</project>

四、将 nacos 文件夹复制到父项目MicroServices文件夹下面,并导入IDEA。

五、修改启动类。Nacos 默认的启动模式为集群模式。本实例使用单机模式

/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.nacos;

import com.alibaba.nacos.console.config.ConfigConstants;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
 * @author nacos
 */
@SpringBootApplication(scanBasePackages = "com.alibaba.nacos")
@EnableScheduling
public class Nacos {

    public static void main(String[] args) {

        /**
         * nacos默认启动的是集群模式,改为单机模式
         */
        System.setProperty(ConfigConstants.STANDALONE_MODE, "true");
        SpringApplication.run(Nacos.class, args);
    }
}

六、Nacos 默认的数据源为内存型数据库,本例中使用Mysql。SQL脚本在源码distribution/conf 文件夹下。修改默认的配置文件。添加如下配置

# mysql配置
db.num=1
db.url.0=jdbc:mysql://localhost:3307/microservice_nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
db.user=root
db.password=123456

七、启动 Nacos 浏览器输入http://localhost:8848/nacos/#/login 用户名/密码:nacos/nacos。登录即可。

服务service-01

一、在父工程中新建一个 spring boot 子工程service-01。加入以下依赖。

<?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">
    <parent>
        <artifactId>Microservices</artifactId>
        <groupId>com.local</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-01</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <!--mvc-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--注册中心客户端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--配置中心客户端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
         <!--服务调用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>com.github.ulisesbocchio</groupId>
                <artifactId>jasypt-maven-plugin</artifactId>
                <version>3.0.0</version>
            </plugin>

        </plugins>
    </build>
</project>

二、修改配置文件。

server:
  port: 7700 #服务端口
spring:
  application:
    name: service-01 #服务名称
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848 #注册地址
      config:
        server-addr: 127.0.0.1:8848 #配置地址
        file-extension: yml
  profiles:
    active: dev

三、在 Nacos 控制台的配置管理中创建 Data Id 为 service-01-dev.yml 的配置文件。(配置文件拉取规则参照官网)

四、启动服务,到 Nacos 控制台服务列表中查看是否注册成功。

服务service-02

​ 创建和配置同上

服务发现和调用

一、service-01中创建CallController

package com.local.web;

import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.local.service.ServiceFeign;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.Map;

/**
 * 服务之间调用的demo
 * @ProjectName: Microservices
 * @Author: Qiao
 * @Description:
 * @Date: 2019/12/16 19:23
 */
@Slf4j
@RestController
@RequestMapping("/demo")
public class CallController {

    Logger logger = LoggerFactory.getLogger(CallController.class);

    // 具有负载均衡的RestTemplate
    @Autowired
    private RestTemplate restTemplateLoadBalanced;

    // 普通的RestTemplate
    @Autowired
    private  RestTemplate restTemplateCommon;

    // 默认集成了ribbon(负载均衡客户端)
    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    private ServiceFeign serviceFeign;

    @Value("${server.port}")
    public Integer port;

    /**
     * 1.根据loadBalancerClient获取到服务的(uri)IP+PORT
     * 2.普通的RestTemplate利用url调用服务接口
     * @param name
     * @return
     */
    @GetMapping("/serviceRestTemplateCommon")
    public String serviceInfo(String name) {
        logger.info("port:"+port);
        ServiceInstance serviceInstance = loadBalancerClient.choose("service-02");
        URI instanceUri = serviceInstance.getUri();
        logger.info("Uri:"+instanceUri.toString());
        String res = restTemplateCommon.getForObject(instanceUri + "/demo/service", String.class);
        return name+"调用"+res;

    }

    /**
     * 1.为RestTemplatet添加@LoadBalanced注解开启负载均衡功能
     * 2.具有负载均衡的RestTemplate利用服务名调用服务接口
     * @param name
     * @return
     */
    @GetMapping("/serviceRestemplateLB")
    public String serviceInfo1(String name) {
        String res = restTemplateLoadBalanced.getForObject("http://service-02/demo/service", String.class);
        return name+"调用"+res;

    }

    /**
     * 获取实例的元数据
     * @param name
     * @return
     */
    @GetMapping("/serviceMeta")
    public String serviceMeta(String name) {
        // 选择实例
        RibbonLoadBalancerClient.RibbonServer ribbonServer = (RibbonLoadBalancerClient.RibbonServer) loadBalancerClient.choose("service-02");
        NacosServer nacosServer = (NacosServer) ribbonServer.getServer();
        Map<String, String> nacosServerMetadata = nacosServer.getMetadata();
        logger.info(nacosServerMetadata.toString());
        // 选择实例
        String res = restTemplateLoadBalanced.getForObject("http://service-02/demo/service", String.class);
        return name+"调用"+res;

    }

    @GetMapping("/serviceFeign")
    public String serviceFeign() {
       return "调用"+serviceFeign.serviceInfo();
    }
}

ServiceFeign

package com.local.service;

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

/**
 * @ProjectName: Microservices
 * @Author: Qiao
 * @Description:
 * @Date: 2019/12/20 10:22
 */
@FeignClient(value = "service-02")
public interface ServiceFeign {

    @GetMapping("/demo/service")
    public String serviceInfo();
}

修改启动类

package com.local;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.web.client.RestTemplate;

/**
 * @ProjectName: Microservices
 * @Author: Qiao
 * @Description:
 * @Date: 2019/12/16 19:21
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableResourceServer
@EnableFeignClients
public class NacosComsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(NacosComsumerApplication.class,args);
    }

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

    @Bean
    public RestTemplate restTemplateCommon() {
        return new RestTemplate();
    }
}

二、service-02添加DemoController

package com.local.web;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ProjectName: Microservices
 * @Author: Qiao
 * @Description:
 * @Date: 2019/12/16 19:35
 */
@Slf4j
@RestController
@RequestMapping("/demo")
public class DemoController {
    Logger logger = LoggerFactory.getLogger(DemoController.class);

    @Value("${server.port}")
    private String port;

    @GetMapping("/service")
    public String serviceInfo() {
        logger.info(port);
        return "provider";
    }
}

三、调用 service-01 中的接口进测试。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐