Spring Nacos

参考:

课程开场白

nacos功能

  • 服务发现
  • 服务健康检查
  • 配置管理
  • DNS服务
  • 服务和元数据管理

配置中心介绍

配置文件信息使用nacos保存用于它自身启动或运行需要的信息。

相当于spring consul的功能。

image-20220606133348759

  • 配置中心

    • 发布修改配置

    • 获取最新配置

    • 配置更新通知后获取最新配置

      对于类似于连接池需要配置

安装

  • 下载

    https://github.com/alibaba/nacos/releases/download/2.1.0/nacos-server-2.1.0.tar.gz

  • 启动

    https://nacos.io/en-us/docs/quick-start.html

    1
    2
    3
    4
    5
    6
    #Linux/Unix/Mac
    #Run the following command to start(standalone means non-cluster mode):

    sh startup.sh -m standalone
    #Shutdown
    sh shutdown.sh

    默认端口是8848

  • 各服务位置

    Service registration 注册服务

    1
    curl -X POST 'http://192.168.86.100:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080'

    Service discovery 发现服务

    1
    curl -X GET 'http://192.168.86.100:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'

    Publish config 发布配置

    1
    curl -X POST "http://192.168.86.100:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=helloWorld"

    Get config 获取配置

    1
    curl -X GET "http://192.168.86.100:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"
  • 发布配置

使用mysql数据库对nacos进行持久化

执行nacos的数据文件创建他的数据库。

https://nacos.io/zh-cn/docs/deployment.html 部署模式参考

1
2
3
#[root@java-study ~]# find -name nacos-mysql.sql
# 默认nacos-mysql数据文件在这
./nacos/conf/nacos-mysql.sql
  • 创建nacos_config数据库

  • 修改配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #*************** Config Module Related Configurations ***************#
    ### If use MySQL as datasource:
    spring.datasource.platform=mysql

    ### Count of DB:
    # db.num=1

    ### Connect URL of DB:
    db.num=1
    db.url.0=jdbc:mysql://192.168.86.1:4306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
    db.user.0=root
    db.password.0=123456

    这里使用本地的数据库一直再出问题

    有三种可能:

    1. 本地登陆数据库不适用密码- 这个应该解决了。
    2. 其次就是无法正确的获得数据。
    3. mariadb版本问题(切换到86.1就解决了问题)
    log
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Caused by: java.lang.IllegalStateException: No DataSource set
    at org.springframework.util.Assert.state(Assert.java:73)
    at org.springframework.jdbc.support.JdbcAccessor.obtainDataSource(JdbcAccessor.java:77)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:371)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:452)
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:462)
    at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:473)
    at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:480)
    at com.alibaba.nacos.config.server.service.repository.extrnal.ExternalStoragePersistServiceImpl.findConfigMaxId(ExternalStoragePersistServiceImpl.java:674)
    at com.alibaba.nacos.config.server.service.dump.processor.DumpAllProcessor.process(DumpAllProcessor.java:51)
    at com.alibaba.nacos.config.server.service.dump.DumpService.dumpConfigInfo(DumpService.java:282)
    at com.alibaba.nacos.config.server.service.dump.DumpService.dumpOperate(DumpService.java:195)
    ... 61 common frames omitted

配置管理使用DEMO

编写一个入门程序

发布一个配置

image-20220607141857861

点击这里来发布一个配置

编写一个程序来获取配置

  • 编写一个可以运行的spring boot程序

  • 创建一个NacosConfiguration类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    package org.akachi.demo.nacos.product.configuration;

    import com.alibaba.nacos.api.annotation.NacosProperties;
    import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig;
    import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.Configuration;

    /**
    * @Author akachi
    * @Email zsts@hotmail.com
    * @Date 2022/6/7 14:55
    */
    @Configuration
    @EnableNacosConfig(globalProperties =
    @NacosProperties(serverAddr = "192.168.86.100:8848")
    )
    @NacosPropertySource(dataId = "nacos-product-demo", autoRefreshed = true)
    public class NacosConfiguration {
    }
  • 创建一个Controller作为验证

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    package org.akachi.demo.nacos.product.controller;

    import com.alibaba.nacos.api.config.annotation.NacosValue;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;

    /**
    * @Author akachi
    * @Email zsts@hotmail.com
    * @Date 2022/6/7 15:00
    */
    @Controller
    @RequestMapping("config")
    public class ConfigController {
    @NacosValue(value = "${useLocalCache:false}", autoRefreshed = true)
    private boolean useLocalCache;

    @GetMapping(value = "/get")
    @ResponseBody
    public boolean get() {
    return useLocalCache;
    }
    }
  • 调用 GET http://localhost:18880/config/get

    如果返回true则为成功

服务发现DEMO

demo

  • 创建controller

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    package org.akachi.demo.nacos.product.controller;

    import com.alibaba.nacos.api.annotation.NacosInjected;
    import com.alibaba.nacos.api.config.annotation.NacosValue;
    import com.alibaba.nacos.api.exception.NacosException;
    import com.alibaba.nacos.api.naming.NamingService;
    import com.alibaba.nacos.api.naming.pojo.Instance;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;

    import java.util.List;

    /**
    * @Author akachi
    * @Email zsts@hotmail.com
    * @Date 2022/6/7 16:03
    */

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

    @NacosInjected
    private NamingService namingService;

    @ResponseBody
    @GetMapping
    public List<Instance> get(@RequestParam String serviceName) throws NacosException {
    return namingService.getAllInstances(serviceName);
    }
    }
  • 创建service在服务器上执行

    curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos-product-demo&ip=192.168.86.1&port=18880'

  • image-20220607162415865

  • 调用

    http://localhost:18880/discovery?serviceName=nacos-product-demo

    image-20220607162450076

nacos配置文件模型

image-20220607164004627

通常我们使用namespace进行不同环境的隔离,group作为不同系统的文件隔离

如图:

image-20220607164246813

新建命名空间namespace

1
2
3
4
5
6
@EnableNacosConfig(
globalProperties =@NacosProperties(
serverAddr = "192.168.86.100:8848",
namespace = "sdf"
)
)

在调用EnableNacosConfig注解时需要在globalProperties中加入sdf来确定使用的配置文件的namespace

  • 不同namespace之间可以克隆

注册服务

  • 这个教材太蠢了还不如看看官方示例操

  • base pom

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    <?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>org.akachi</groupId>
    <artifactId>nacos-demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
    <module>nacos-provider</module>
    <module>nacos-consumer</module>
    </modules>

    <properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <spring-boot.version>2.0.4.RELEASE</spring-boot.version>
    <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <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>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>0.2.2.RELEASE</version>
    </dependency>
    <dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>1.1.0</version>
    </dependency>
    </dependencies>
    </dependencyManagement>

    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
    <execution>
    <goals>
    <goal>repackage</goal>
    </goals>
    </execution>
    </executions>
    </plugin>
    </plugins>
    </build>
    </project>
  • nacos-provider pom

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    <?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>nacos-demo</artifactId>
    <groupId>org.akachi</groupId>
    <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>nacos-provider</artifactId>

    <properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <exclusions>
    <exclusion>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    </dependency>
    </dependencies>

    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
    <execution>
    <goals>
    <goal>repackage</goal>
    </goals>
    </execution>
    </executions>
    </plugin>
    <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
    <source>11</source>
    <target>11</target>
    </configuration>
    </plugin>
    </plugins>
    </build>
    </project>
  • ProviderApplication

    启动程序和controller都在这

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    package org.akachi.nacos.provider;

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;

    /**
    * @Author akachi
    * @Email zsts@hotmail.com
    * @Date 2022/6/8 15:56
    */
    @SpringBootApplication
    @EnableDiscoveryClient
    public class ProviderApplication {
    public static void main(String[] args) {
    SpringApplication.run(ProviderApplication.class, args);
    }
    @RestController
    class EchoController {
    @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
    public String echo(@PathVariable String string) {
    return "Hello Nacos Discovery " + string;
    }
    }
    }
  • application.yml的配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    server:
    port: 33030

    spring:
    cloud:
    nacos:
    discovery:
    server-addr: 192.168.86.100:8848
    application:
    name: service-provider

使用openfeign相互调用服务

  • yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    server:
    port: 33130
    spring:
    application:
    name: service-consumer
    cloud:
    nacos:
    discovery:
    server-addr: 192.168.86.100:8848
  • RemoteClient

    ```yml
    package org.akachi.nacos.consumer.service;

    import org.akachi.nacos.consumer.service.hystrix.RemoteHystrix;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;

    /**

    • @Author akachi

    • @Email zsts@hotmail.com

    • @Date 2022/6/8 17:24

    • /
      //http://service-provider/echo/" + str
      @FeignClient(name = “service-provider”,fallback = RemoteHystrix.class)
      public interface RemoteClient {

      @GetMapping(“/echo/{string}”)
      String helloNacos(@PathVariable(“string”) String string);
      }