zoukankan      html  css  js  c++  java
  • nacos使用-服务注册中心和配置中心

    本例子基于 spring boot + spring cloud alibaba + spring cloud, nacos作为服务注册中心和配置中心。

    简介

    Nacos 是Spring Cloud Alibaba 的一个组件。致力于发现、配置和管理微服务。

    Nacos名字:前四个字母分别为 Naming 和 Configuration 的前两个字母,最后的 s 为 Service。

    下载启动

    版本选择

    如果是使用spring boot + spring cloud alibaba + spring cloud全家桶。那么版本选择一定要按照官网匹配,否则会因jar包冲突导致项目启动失败。

    我们可以去spring cloud alibaba的版本说明查看

    版本说明

    在此文中,我选择的版本为spring boot - 2.2.5.RELEASE, spring cloud alibaba - 2.2.1.RELEASE, spring cloud - Hoxton.SR3

    下载

    nacos下载地址 https://github.com/alibaba/nacos/releases

    根据上面的版本说明,我这里选择1.2.1

    启动

    下载解压后,进入bin目录

    nacos的bin目录

    可以看到启动命令。其中cmd是window系统使用,sh是linux系统使用。

    我们本地测试使用windows环境,直接双击startup.cmd即可。linux环境请执行./startup.sh -m standalone (standalone代表单机启动,实际使用应做集群,集群数量三台起步)

    查看控制台

    nacos默认端口是8848,可不是某手机,8848代表珠穆朗玛峰的高度(但是现在高度好像是8844了)。

    启动nacos后,访问localhost:8848/nacos/index.html,可以看到nacos后台。在这里可以对服务和配置做可视化管理(当然现在是空的,一会儿项目启动就有东西了)。

    nacos服务为空

    注册中心

    先看看如何作为服务注册中心

    服务注册

    1 项目pom添加依赖

    <!-- spring boot 项目 -->
    <parent>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-parent</artifactId>
    	<version>2.2.5.RELEASE</version>
    	<relativePath/>
    </parent>
    
    <dependencies>
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-web</artifactId>
    	</dependency>
    	
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-test</artifactId>
    		<scope>test</scope>
    	</dependency>
    
    	<!-- 服务注册/发现 -->
    	<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>
    
    <dependencyManagement>
    	<dependencies>
    		<!-- spring cloud alibaba 依赖管理 -->
    		<dependency>
    			<groupId>com.alibaba.cloud</groupId>
    			<artifactId>spring-cloud-alibaba-dependencies</artifactId>
    			<version>2.2.1.RELEASE</version>
    			<type>pom</type>
    			<scope>import</scope>
    		</dependency>
    	</dependencies>
    </dependencyManagement>
    

    2 application.properties添加配置

    # 服务端口
    server.port=8081
    # 服务名
    spring.application.name=service-provider
    # 服务注册中心地址
    spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
    

    3 启动类上添加服务发现注解

    @EnableDiscoveryClient
    @SpringBootApplication
    public class ProviderApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(ProviderApplication.class, args);
    	}
    
    }
    

    PS:这里不加@EnableDiscoveryClient也行,Spring Cloud Dalston.SR4版本之后会自动向注册中心注册

    4 启动查看

    启动服务,刷新nacos后台就能看到这个服务了

    nacos服务一个

    服务调用

    为了说明服务调用,我们先以同样的方式配置好另外一个服务

    1 pom添加依赖

    同上,略

    2 application.properties添加配置

    # 服务端口
    server.port=9091
    # 服务名
    spring.application.name=service-consumer
    # 服务注册中心地址
    spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
    

    3 启动类

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

    4 启动查看

    可以看到,我们有两个微服务了

    nacos服务两个

    5 引入openfeign

    openfeign是spring cloud的组件,为微服务之间的调用提供了解决方案。

    openfeign的使用也非常简单,我们在service-consumer项目的基础上继续完善

    1) pom添加依赖

    <dependencies>
    	... //省略之前已添加
    
    	<!-- 服务调用 -->
    	<dependency>
    		<groupId>org.springframework.cloud</groupId>
    		<artifactId>spring-cloud-starter-openfeign</artifactId>
    	</dependency>
    </dependencies>
    
    <dependencyManagement>
    	<dependencies>
    		... //省略之前已添加
    		
    		<!-- spring cloud 依赖管理 -->
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-dependencies</artifactId>
    			<version>Hoxton.SR3</version>
    			<type>pom</type>
    			<scope>import</scope>
    		</dependency>
    	</dependencies>
    </dependencyManagement>
    

    2) 编写远程调用类

    package com.test.consumer.feign;
    
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    
    @FeignClient("service-provider")
    public interface ProviderFeignService {
    	
    	@RequestMapping("provider/test")
    	public Result providerTest(@RequestBody TestEntity testEntity, @RequestParam String name);
    	
    }
    

    映射说明: @FeignClient括号里是要调用的微服务名称,@RequestMapping括号里是被调用微服务的具体api路径。

    传参说明: 实体类添加@RequestBody,字符串和普通类型添加@RequestParam。

    这个service就和我们平时普通的service一样,在controller使用@Autowired依赖注入即可。

    3) 启动类添加@EnableFeignClients

    @EnableFeignClients(basePackages = "com.test.consumer.feign")
    @SpringBootApplication
    public class ConsumerApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(ConsumerApplication.class, args);
    	}
    
    }
    

    说明: @EnableFeignClients括号里是要实行远程调用服务所在的包路径,即上面远程调用类所在的包路径。

    现在回到service-provider添加一个测试controller就可以调用成功了

    @RestController
    @RequestMapping("provider")
    public class TestController {
    
    	@PostMapping("test")
    	public Result test(TestEntity testEntity, String name) {
    		Result result = new Result();
    		// do something, balabala
    		return result;
    	}
    }
    

    Result是自定义返回类,略。

    原理简述

    服务注册中心的实现,大概依赖三个重要的定时任务

    1. 客户端定时任务:定时发送心跳,告诉nacos我还活着
    2. 客户端定时任务:定时拉取可用服务,放在本地缓存。openfeign调用时自行选用缓存中服务
    3. 服务端定时任务,定时刷新可用列表,踢掉太久没发心跳的客户端【默认15秒未发心跳的会被踢出】

    小结

    以上,我们实现了服务注册与发现,服务间远程调用。

    配置中心

    问题说明

    随着业务越来越复杂,我们会面临一些问题:

    1. 微服务项目越来越多,配置文件也越来越多,管理起更麻烦
    2. 改动一个配置参数时,需要重新打包微服务重新发布
    3. 有时候希望改动某个参数可以立即生效

    接下来,我们使用nacos解决这些问题。

    1 添加pom依赖

    <dependencies>
    	... //省略之前已添加
    	
    	<!-- 配置中心 -->
    	<dependency>
    		<groupId>com.alibaba.cloud</groupId>
    		<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    	</dependency>
    </dependencies>
    

    2 在application.properties设置运行环境

    spring.profiles.active=dev
    

    3 新建bootstrap.properties文件

    # 服务名
    spring.application.name=service-consumer
    # 配置中心地址
    spring.cloud.nacos.config.server-addr=127.0.0.1:8848
    

    4 添加注解 @Value + @RefreshScope

    @RefreshScope // 自动感知配置文件变化
    @RequestMapping("test")
    @RestController
    public class TestController {
    	// 从配置文件获取属性值
    	@Value("{message}")
    	private String message;
    	
    	@RequestMapping("message")
    	public String message() {
    		return message;
    	}
    
    }
    

    5 去nacos配置中心添加配置文件

    nacos配置中心之添加按钮

    nacos配置中心之配置文件

    这里Data Id就是配置文件名

    6 启动服务,验证结果

    服务启动时会去配置中心找文件 ${prefix}-${spring.profile.active}.${file-extension}

    1. prefix默认为spring.application.name,本例中即 service-consumer ;也可以通过配置spring.cloud.nacos.config.prefix来指定
    2. spring.profile.active就是当前环境对应的 profile,本例中即 dev ;如果spring.profile.active不存在,这之前的连接符-也将不存在,文件拼接格式变为${prefix}.${file-extension}
    3. file-extension就是文件后缀,默认为properties;可以通过配置spring.cloud.nacos.config.file-extension来指定,但其值目前只支持propertiesyaml

    根据上述说明,服务会去配置中心找的文件就是service-consumer-dev.properties,也即是第5步新增的配置文件。

    浏览器访问localhost:9091/test/message就可以看到返回结果为panda,即我们配置文件中的值。

    然后去配置中心修改配置文件内容:

    nacos配置中心之编辑按钮

    nacos配置中心之配置文件修改

    再次访问localhost:9091/test/message,可以看到返回结果变为panda2

    如此,就解决了之前提到的三个问题:

    1. 配置文件和项目包分开,配置文件可统一管理
    2. 配置参数修改后,不需要重新打包项目,直接重启项目就能读到修改的值
    3. 对于一些需要立即生效的参数,使用@Value + @RefreshScope组合

    7 小结

    我们项目的启动脚本里一般会加上profile,如测试环境java -jar order.jar --spring.profile.active=test,生产环境java -jar order.jar --spring.profile.active=prod。那么,同一个jar包,我们完全不需要任何改动,发布到不同环境,它自己就能读取到不同环境的配置文件。

    一"一个jar包,到处发布"。非常的方便。

    namespace & group

    我们已经把配置文件从项目中抽离出来了,然而这里仍有麻烦:如果我们有很多微服务,那么就对应有很多配置文件;这些文件还有各自不同环境的版本,也许还有不同业务场景下的版本。如果只是把这么多配置文件都单纯放在一起,那么维护起来也会很困难。

    1 说明

    为了解决配置文件太多不好管理的问题,我们可以使用nacos提供的命名空间(namesapce)和组(group)的概念。

    namespace可以看成是一个独立的一级目录,namespace之间相互隔离;组可以看成namespace下面的二级目录,group之间同样隔离。

    之前说,服务启动后会去配置中心找${prefix}-${spring.profile.active}.${file-extension},其实前面还得加上命名空间和组;即到底是去哪个命名空间下面的哪个组找配置文件。我们没有配置这两项,默认是去public下DEFAULT_GROUP找该文件。

    而我们创建配置文件时并没有指定命名空间和组,默认就放在了public下的DEFAULT_GROUP组。

    所以才能正常读取到配置文件。

    2 解决方案

    根据以上说明,我们可以使用微服务名来作为namespace。如一个商城项目,有订单微服务(order),商品微服务(product),库存微服务(stock)等,那我们就分别建立namespace为order, product, stock等。

    然后,对于不同的业务场景,我们可以使用group来区分。比如双11对应的组,我们就叫1111;618对应的组,我们就叫618

    我们去命名空间菜单,点击新建命名空间

    nacos配置中心之命名空间菜单

    nacos配置中心之新建命名空间

    依次添加三个命名空间后,回到配置列表,可以看到新建的命名空间

    nacos配置中心之命名空间三个

    单击命名空间,可选中之。我们在其中新建配置文件,组也是在建立配置文件时指定的。

    nacos配置中心之命名空间新建配置文件

    连续建立不同组不同环境的配置文件,最后应该看起来类似这样

    nacos配置中心之命名空间配置文件一览

    然后其他微服务也如此,建立自己的不同组的不同环境的配置文件。

    这里我们可以使用克隆功能,批量复制。

    nacos配置中心之命名空间配置文件克隆

    结果如下

    nacos配置中心之命名空间配置文件克隆结果

    如果微服务的配置差别不大的话,可以用这个方式批量复制,再去修改部分参数。

    配置文件完成后,再去bootstrap.properties文件指定namespace和group

    spring.cloud.nacos.config.group=1111
    spring.cloud.nacos.config.namespace=12078634-abb1-4604-8678-45c11db8fe74
    

    这里面的12078634-abb1-4604-8678-45c11db8fe74就是order命名空间后面那一串id

    3 小结

    以上,我们分离了配置文件和项目。并且能根据微服务和业务分开管理。使得配置维护,项目发布都更加容易。

    tip:这里其实有个问题,这个group切换,还是需要修改group后重新发布项目。所以,这里失去了之前说好的"一个jar包,到处发布"的特点。所以,实际使用中,如果没有特别的业务场景,就使用一个默认group。只指定namespace,那么依旧可以做到不重新打包项目。

    ps: 如果有同学知道项目启动如何指定group,请指正,多谢。

    自定义数据库

    默认情况下,nacos是使用了一个嵌入式数据库。

    如果想使用自己的数据库(目前只支持mysql数据库)

    1 conf目录下,修改application.properties文件。

    spring.datasource.platform=mysql
    
    db.num=1
    db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
    db.user=root            #使用的mysql用户名
    db.password=xxx    #使用的mysql连接密码
    

    2 将conf/nacos-mysql.sql表结构导入到自己的数据库中

    3 重新启动启动nacos,会发现之前的配置文件没有了。重新添加配置文件,在mysql表里看到自己的配置文件内容。

    集群

    为了保证nacos本身的高可用,可以用三台nacos组成集群。

    集群首先要使用自定义数据库,不然三台集群的配置文件都不能保证一致,集群的基本意义就没了。

    1 复制conf目录下的cluster.conf.example,重命名为cluster.conf,写入三台nacos的ip地址

    192.168.0.101
    192.168.0.102
    192.168.0.103
    

    如果在同一台机器上测试,可以设定不同端口

    127.0.0.1:8848
    127.0.0.1:8858
    127.0.0.1:8868
    

    2 复制两个nacos,放在不同的机器上(单机测试则去conf/application.properties修改端口)。启动三台nacos。

    3 nginx代理配置

    # 集群节点
    upstream nacos {
     server 192.168.0.101:8848 weight=1;
     server 192.168.0.102:8848 weight=1;
     server 192.168.0.103:8848 weight=1;
    }
    # 本地集群节点
    #upstream nacos {
     #server 127.0.0.1:8848 weight=1;
     #server 127.0.0.1:8858 weight=1;
     #server 127.0.0.1:8868 weight=1;
    #}
    
    server {
        listen       80;
        server_name  localhost;
        location /nacos/ {
            #代理
            proxy_pass http://nacos/nacos/;
        }
    }
    

    4 访问
    浏览器访问http://localhost/nacos/index.html即可

    tip: 保证了Nacos不会有单点故障后,其背后的Mysql最好也做一个主从备份或高可用。

  • 相关阅读:
    Git 常用命令 Better
    HTTP Cookie 总结 Better
    clientWidth, offsetWidth, scrollWidth的区别 Better
    Math.round() 0.5时的特殊性 Better
    screenY、pageY、clientY、offsetY的区别 Better
    Oracle 数据快速导出工具:sqluldr2
    使用 barman的备份和归档PostgreSQL
    Android RK 内置应用 不可卸载
    AS SerialPort 编译依赖库
    RK 看门狗 WatchDog
  • 原文地址:https://www.cnblogs.com/tenny-peng/p/12911956.html
Copyright © 2011-2022 走看看