zoukankan      html  css  js  c++  java
  • SpringBoot使用Nacos进行服务注册发现与配置管理

    前提

    最近由于业务发展,需要调研一套完善和主流的基础架构,进行中台化(微服务)的实施,考虑到技术栈切换到SOFAStack。既然整个体系都切换到蚂蚁金服的技术栈,那么自然考虑一些基础组件如服务注册发现、配置管理等都切换为阿里的技术栈。考虑到目前比较热的服务发现组件是Nacos,需要调研SpringBoot服务接入Nacos的可行性,为以后强制要求新服务使用SOFAStack + Nacos的技术栈进行服务开发打下基础。

    Nacos简介

    下面的简介来源于Nacos的官网:

    Nacos致力于帮助您发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

    Nacos帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos是构建以服务为中心的现代应用架构(例如微服务范式、云原生范式)的服务基础设施。

    Nacos地图:

    Nacos生态图:

    Nacos提供的发展地图来看,它基本提供了目前微服务实施中一些核心问题:监控、服务发现注册、配置灰度发布、配置回滚等等。另外,它在生态上能够融入目前主流的K8SDockerSpringCloudConsulZookeeper等等(有点像屏蔽底层细节,只需少量配置就可以切换底层架构的实现),这一点十分重要。目前Nacos在阿里云上提供了商用版本(记得有前辈说过开源的终极目标就是商用,大概如此)。如果在项目中使用的是SpringCloud全家桶,引入Nacos以及它和SpringCloud之间的胶水层,可以完全替代Eureka组件的功能,替代和强化部分Spring Cloud Config的功能。

    Nacos服务部署

    Nacos-Server部署相对简单,它的发布版本见Github的Releases页面。下载完成后进行解压,Windows系下启动Nacos-Server只需进入解压后的${解压目录} acosin目录,执行startup.cmd即可,服务启动成功的结果如下:

    单机模式在不修改配置的前提下直接启动,使用的是内存数据库,重启后数据会被清空。如果需要数据持久化,则需要建立数据库,具体的步骤是:

    • 建表的脚本在${解压目录} acosconf目录下,见schema.sqlnacos-mysql.sql两个文件。
    • 自行通过建表的脚本建立数据库。
    • 需要指定数据库,则需要修改${解压目录} acosconfapplication.properties,在文件的尾部追加数据源的连接配置,下面是官方给出的多数据源的例子:
    # 需要确保多个数据源的用户名和密码一致
    db.num=2
    db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
    db.url.1=jdbc:mysql://11.163.152.9:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
    db.user=nacos_devtest
    db.password=nacos
    

    测试获取已经注册的服务:

    λ curl -X GET http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName
    {"hosts":[],"name":"DEFAULT_GROUP@@nacos.naming.serviceName","clusters":""}
    

    访问http://127.0.0.1:8848/nacos即可打开Nacos-Console,初始的登录账号和密码都是nacos

    更多运维部署相关的内容见文档运维指南中的一节。

    SpirngBoot应用使用Nacos作为注册中心

    SpringBoot应用使用Nacos作为注册中心需要引入依赖nacos-discovery-spring-boot-starter,笔者编写本文的时候(2020-01-01),该依赖的最新版本为0.2.4,对应于SpringBoot的版本为2.0.3.RELEASE,引入如下依赖:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.0.3.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>nacos-discovery-spring-boot-starter</artifactId>
            <version>0.2.4</version>
        </dependency>
    </dependencies>
    

    为了方便起见,笔者把控制器、服务注册的代码都写在启动类ProvideApplication中:

    @RestController
    @SpringBootApplication(scanBasePackages = "club.throwable.provide")
    public class ProvideApplication implements CommandLineRunner {
    
        @NacosInjected
        private NamingService namingService;
    
        @Value("${spring.application.name}")
        private String applicationName;
    
        @Value("${server.port}")
        private Integer serverPort;
    
        public static void main(String[] args) {
            SpringApplication.run(ProvideApplication.class, args);
        }
    
        @GetMapping(path = "/hello")
        public String hello(@RequestParam(name = "name") String name) {
            return String.format("%s say hello!", name);
        }
    
        @Override
        public void run(String... args) throws Exception {
            // 通过Naming服务注册实例到注册中心
            namingService.registerInstance(applicationName, "127.0.0.1", serverPort);
        }
    }
    

    配置文件application-provide.properties内容如下:

    spring.application.name=provide-service
    server.port=9092
    nacos.discovery.server-addr=127.0.0.1:8848
    

    使用spring.profiles.active=provide启动ProvideApplication,启动成功后用浏览器打开Nacos-Console

    暂时可知服务的提供方已经注册成功。接着编写服务的消费方代码,引入的最小依赖和服务提供方完全一致,编写启动类ConsumeApplication如下:

    @SpringBootApplication(scanBasePackages = "club.throwable.consume")
    public class ConsumeApplication implements CommandLineRunner {
    
        @NacosInjected
        private NamingService namingService;
    
        public static void main(String[] args) {
            SpringApplication.run(ConsumeApplication.class, args);
        }
    
        @Override
        public void run(String... args) throws Exception {
            // 根据服务名从注册中心获取一个健康的服务实例
            Instance instance = namingService.selectOneHealthyInstance("provide-service");
            // 这里只是为了方便才新建RestTemplate实例
            RestTemplate template = new RestTemplate();
            String url = String.format("http://%s:%d/hello?name=throwable", instance.getIp(), instance.getPort());
            String result = template.getForObject(url, String.class);
            System.out.println(String.format("请求URL:%s,响应结果:%s", url, result));
        }
    }
    

    消费服务的配置文件application-consume.properties内容如下:

    spring.application.name=consume-service
    server.port=9091
    nacos.discovery.server-addr=127.0.0.1:8848
    

    使用spring.profiles.active=consume启动ConsumeApplicationCommandLineRunner执行完毕后控制台打印:

    请求URL:http://127.0.0.1:9092/hello?name=throwable,响应结果:throwable say hello!
    

    这种方式使用起来会感觉模板代码比较多,不够简洁。如果在SpringCloud体系中,结合Feign客户端则可以省略这些模板代码。

    SpirngBoot应用使用Nacos管理配置

    如果使用Nacos进行配置管理,则需要引入nacos-config-spring-boot-starter依赖,笔者编写本文的时候(2020-01-01),该依赖的最新版本为0.2.4

    <dependency>
        <groupId>com.alibaba.boot</groupId>
        <artifactId>nacos-config-spring-boot-starter</artifactId>
        <version>0.2.4</version>
    </dependency>
    

    新建一个启动类ConfigApplication如下:

    @RestController
    @NacosPropertySource(dataId = "example", autoRefreshed = true)
    @SpringBootApplication(scanBasePackages = "club.throwable.config")
    public class ConfigApplication {
    
        @NacosValue(value = "${counter:0}", autoRefreshed = true)
        public Long counter;
    
        public static void main(String[] args) {
            SpringApplication.run(ConfigApplication.class, args);
        }
    
        @GetMapping(path = "/get")
        public String get() {
            return String.format("Counter value:%d", counter);
        }
    }
    

    笔者定义了一个长整型的计数器,设置了autoRefreshed(自动刷新)为true,新建一个配置文件application-config.properties

    spring.application.name=config-service
    server.port=9093
    nacos.config.server-addr=127.0.0.1:8848
    

    使用spring.profiles.active=config启动ConfigApplication,启动成功后通过CURL调用下面的接口:

    λ curl -X GET http://127.0.0.1:9093/get
    Counter value:0
    

    接着通过Nacos-Console添加一个配置:

    点击发布按钮后再次调用接口:

    λ curl -X GET http://127.0.0.1:9093/get
    Counter value:10086
    

    可见计数器的值已经动态刷新。配置项里面还有很多高级配置如:指定配置生效的服务、Beta发布等等,可以按照合适的场景进行设置。

    另外,Nacos Server提供Open API从而可以使用HTTP客户端就可以轻松进行配置查询、配置更新发布等操作(目前这些API没有做鉴权,社区也有人曾提出这样会引发安全性问题,Nacos官方已经立项在后续新版本中加入鉴权的功能,目前建议屏蔽或者仅允许内网访问这些Open API):

    • 获取配置:curl -X GET http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=${DATA_ID}&group=${GROUP}
    • 发布配置:curl -X POST http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=${DATA_ID}&group=${GROUP}&content=${CONFIG_CONTENT}

    小结

    本文只是简单介绍了SpringBoot中使用Nacos作为注册中心以及进行配置管理。Nacos项目Github仓库当前(2020-01-01)的star数已经接近10000,社区也十分活跃,Issues和交流群的响应都十分迅速。加之Netflix的部分开源产品如EurekaHystrix等已经停止迭代,但Nacos还在飞速迭代,甚至已经在阿里云衍生出商业版本,所以笔者认为Nacos值得使用,在相对熟悉它的大部分特性之后会付之于生产环境中使用。

    参考资料:

    本文的Demo项目:

    下一篇博文会介绍一下SOFAStack中基于SOFABootSOFARpc以及Nacos等组件作为基础架构搭建一套微服务的详细过程。

    原文链接

    (本文完 c-2-d e-a-20200101 23:11)

    技术公众号(《Throwable文摘》),不定期推送笔者原创技术文章(绝不抄袭或者转载):

    娱乐公众号(《天天沙雕》),甄选奇趣沙雕图文和视频不定期推送,缓解生活工作压力:

  • 相关阅读:
    hive与hbase整合
    待重写
    hive DML
    【知识强化】第六章 总线 6.1 总线概述
    【知识强化】第五章 中央处理器 5.1 CPU的功能和基本结构
    【知识强化】第四章 指令系统 4.3 CISC和RISC的基本概念
    【知识强化】第四章 指令系统 4.2 指令寻址方式
    【知识强化】第四章 指令系统 4.1 指令格式
    【知识强化】第三章 存储系统 3.6 高速缓冲存储器
    【知识强化】第三章 存储系统 3.5 双口RAM和多模块存储器
  • 原文地址:https://www.cnblogs.com/throwable/p/12134282.html
Copyright © 2011-2022 走看看