SpringCloud 微服务实战6 - SpringCloud Alibaba Nacos(服务注册与发现、配置中心)

一、SpringCloud Alibaba 入门简介

1、为什么会出现 SpringCloud Alibaba

SpringCloud Netflix 项目进入了维护模式。Spring Cloud Greenwich.RC1 available now

将模块处于维护模块意味着 Spring Cloud Netflix 团队将不会再向模块添加新功能。

2、SpringCloud Alibaba 带来了什么

官网:https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md 

2018.10.31,SpringCloud Alibaba 正式入驻了 SpringCloud 官方孵化器,并在 Maven 中央库发布了第一个版本。

SpringCloud Alibaba可以干什么?

  • 服务限流降级:默认支持 Servlet、Feign、RestTemplate、Dubbo 和 RocketMQ 限流降级功能的借入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
  • 服务注册与发现:适配 SpringCloud 服务注册与发现,默认集成了 Ribbon 的支持。
  • 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
  • 消息驱动能力:基于 SpringCloud Stream 为微服务应用构建消息驱动能力。
  • 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
  • 分布式任务调度:提供秒级、精准、高可靠的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(Schedule-client)上执行。
  • 阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

SpringCloud Alibaba 包含的组件:

  • Sentinel:阿里巴巴开源产品,把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
  • Nacos:阿里巴巴开源产品,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
  • RocketMQ:Apache RocketMQ™基于 Java 的高性能、高吞吐量的分布式消息和流计算平台。
  • Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。
  • Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。
  • Alibaba Cloud OSS:阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
  • Alibaba Cloud SchedulerX:阿里中间件团队开发的一款分布式任务调度产品,支持周期性的任务与固定时间点触发任务。
  • Alibaba Cloud SMS:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

3、SpringCloud Alibaba 学习资料获取

官网:Spring Cloud Alibaba 

应为:GitHub - alibaba/spring-cloud-alibaba: Spring Cloud Alibaba provides a one-stop solution for application development for the distributed solutions of Alibaba middleware.

中文:

二、SpringCloud Alibaba Nacos 服务注册中心和配置中心

1、Nacos 简介

1.1 Nacos 是什么?

Nacos 是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

Nacos:Dynamic Naming And Configuration Service

Nacos:就是注册中心+配置中心的组合

Nacos = Eureka + Config + Bus

1.2 Nacos 能干嘛

替代 Eureka 做服务注册中心

替代 Config 做服务配置中心

1.3 去哪里下载

Nacos官网:  ,点击版本说明

点击 Tags

自行选择一个合适的版本下载

 本人下载的是 2.0.2,拉到页面的最下方,点击下载(.zip 是window 版本,.tar.gz 是linux 版本)。

1.4 各注册中心比较

据说  Nacos 在阿里巴巴内部有超过 10万 的实例运行,已经过了双十一等各种大型流量的考验。

2、Nacos 安装

本地 Java8+Maven环境已经OK。

前期准备(本人运行环境 Win10):

  • 如果是只有单台机器,则需要修改  nacos/bin/startup.cmd 启动文件,将 MODE 修改为单例 standalone

  • 修改 nacos/conf/application.properties ,配置数据库,注意数据库名称和用户名密码

  • 在本地 数据库执行 nacos/conf/nacos-mysql.sql 的语句

 

双击 nacos/bin/startup.cmd 启动,如下则表示启动成功

命令运行成功后直接访问 http://localhost:8848/nacos , 默认账号密码都是 nacos

3、Nacos 作为服务注册中心演示

Spring Cloud Alibaba 参考文档

3.1 基于 Nacos 的服务提供者

新建 Module :cloudalibaba-provider-payment9001

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">
    <parent>
        <artifactId>cloud-study</artifactId>
        <groupId>com.cloud.study</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloudalibaba-provider-payment9001</artifactId>

    <dependencies>
        <!-- alibaba-nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- 引入自己的 cloud-api-commons 模块-->
        <dependency>
            <groupId>com.cloud.study</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--开启热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

在 父 POM 引入了 spring-cloud-alibaba-dependencies 的依赖,如下图:

            <!-- SpringCloud Alibaba 2.2.6.RELEASE -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.6.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

YAML

server:
  port: 9001

spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

#暴露监控端点
management:
  endpoints:
    web:
      exposure:
        include:  "*"

主启动

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

业务类

@RestController
public class PaymentController {
    @Value("${server.port}")
    private String serverPort;

    @GetMapping("/payment/nacos/{id}")
    public String getPayment(@PathVariable("id") Integer id){
        return "nacos registry, serverPort: " + serverPort + "\t id:"+id;
    }
}

测试,启动 9001 

为了下一章节演示 nacos的负载均衡效果,参照 9001

新建 cloudalibaba-provider-payment9002

3.2 基于 Nacos 的服务消费者

新建 Module: cloudalibaba-consumer-order83

POM

    <dependencies>
        <!-- alibaba-nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- 引入自己的 cloud-api-commons 模块-->
        <dependency>
            <groupId>com.cloud.study</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--开启热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

yaml

server:
  port: 83

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848

#消费者将要去访问的微服务名称(注册成功的微服务提供者)
service-url:
  nacos-user-service: http://nacos-payment-provider

主启动

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

业务类

@RestController
@Slf4j
public class OrderNacosController {
    @Resource
    private RestTemplate restTemplate;

    @Value("${service-url.nacos-user-service}")
    private String serverURL;

    @GetMapping("/consumer/payment/nacos/{id}")
    public String getPayment(@PathVariable("id") Integer id){
        return restTemplate.getForObject(serverURL+"/payment/nacos/"+id, String.class);
    }
}

配置类

@Configuration
public class ApplicationContextConfig {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

测试

  1. 启动83,在 Nacos 控制台可以看到微服务注册上来了
  2. 多刷新几次 http://localhost:83/consumer/payment/nacos/1  ,发现输出的端口不同,实现了负载均衡。

3.3 服务注册中心对比

Nacos 支持 AP 和 CP 模式的切换

C 是所有节点在同一时间看到的数据是一致的;而 A 的定义是所有的请求都会受到响应。

合适选择用何种模式

一般来说,如果不需要存储服务级别的信息,且服务实例是通过 nacos-client 注册,并能够保持心跳上报,那么就可以选择 AP 模式。当前主流的服务如 Spring Cloud  和 Dubbo 服务,都使用 AP 模式, AP 模式为了服务的可能性而减弱了一致性,因此 AP 模式下只支持注册临时实例

如果需要在服务级别编辑或存储配置信息,那么 CP 是必须的,K8S 服务 和 DNS 服务使用 CP 模式。CP模式下则支持注册持久化实例,此时则是以 Raft 协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。

切换并启动 nacos 服务的模式:

curl -X PUT '$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'

4、Nacos 作为服务配置中心演示

4.1 Nacos 作为配置中心-基础配置

新 Module : cloudalibaba-config-nacos-client3377

POM

    <dependencies>
        <!-- alibaba-config -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!-- alibaba-nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- 引入自己的 cloud-api-commons 模块-->
        <dependency>
            <groupId>com.cloud.study</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!-- web + actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--开启热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

yaml:Nacos 与 SpringCloud-config 一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置后,才能保证项目的正常启动。bootstrap 优先级高于 application

  • bootstrap.yaml
server:
  port: 3377

spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos 服务注册中心
      config:
        server-addr: localhost:8848 #Nacos 配置中心
        file-extension: yaml  #指定 yaml 格式的配置
  • application.yaml
spring:
  profiles:
    active: dev # 表示开发环境

主启动

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

业务类

@RestController
@RefreshScope //支持Nacos的动态刷新功能
public class ConfigClientController {
    @Value("${config.ingo}")
    private String configInfo;

    @GetMapping("/config/info")
    public String getConfigInfo(){
        return configInfo;
    }
}

在Nacos中添加配置信息

Nacos Spring Cloud 快速开始

最后的公式为: 

${spring.application.name}-${spring.profiles.active}.${file-extension}

 根据上述 yaml 得出 dataid = 【nacos-config-client-dev.yaml】

  • 点击【配置列表】中的“添加”按钮

  • 在 输入页面 输入【Data Id】,配置格式,配置内容,然后发布。

注意【Data Id】的“${file-extension}”必须为 yaml,不能是 yml,否则会有问题 。

测试

  • 访问  http://localhost:3377/config/info ,可以得到 配置的信息。
  •  自带动态刷新:我们在修改【nacos-config-client-dev.yaml】的配置,刷新 http://localhost:3377/config/info 发现输出的配置是最新的。

4.2 Nacos 作为配置中心-分类配置

问题

问题1

实际开发中,通常一个系统会准备:

  • dev 开发环境
  • test 测试环境
  • prod 生成环境

如何保证指定环境启动时能正确读取到 Nacos 上相应环境的配置文件呢?

问题2

一个大型分布式微服务系统会有很多微服务子项目,每个微服务项目又会有相应的开发环境、测试环境、预发环境、正式环境....

那怎么对这些微服务配置进行管理呢?

Nacos管理后台图形化界面

Nacos 配置管理界面

Nacos 命名空间,public 是保留的

Namespace + Group + Data ID 三者关系?为什么这么设计? 

1、是什么

类似Java里面的 package 名和类名,最外层的 Namespace 是可以用于区分部署环境的,Group 和 Data ID 逻辑上区分两个目标对象。

2 三者情况

3.默认情况

  • Namespace = public
  • Group = DEFAULT_GROUP
  • Cluster = DEFAULT

Nacos 默认的命名空间是 public,Namespace 主要用来实现隔离。比方说我们现在有三个环境:开发、测试、生成环境,我们就可以创建三个 Namespace,不同的 Namespace 之间是隔离的。

Group 默认是 DEFAULT_GROUP,Group 可以把不同的微服务划分到同一分组里面去。

Service 就是微服务,一个 Service 可以包含多个 Cluster(集群),Nacos 默认 Cluster 是 DEFAULT,Cluster 是对指定微服务的一个虚拟划分。比方说为了容灾,将 Service 微服务分别部署在了杭州机房和广州机房,这时就可以给杭州机房的 Service 微服务起一个集群名称(HZ),给广州机房的 Service 微服务起一个集群名称(GZ),还可以尽量让同一个机房的微服务互相调用,以提升性能。

最后 Instance,就是微服务的实例。

案例 - DataID 方案

指定 spring.profile.active 和 配置文件的 DataId来使不同环境下读取不同的配置。

默认空间 + 默认分组 + 新建 dev 和 test 两个 DataID

通过 spring.profile.active 属性就能进行多环境下配置文件的读取

测试

  • 当 spring.profile.active 是 dev 时,读取的内容为 nacos-config-client-dev.yaml 的 config.info
  • 当 spring.profile.active 是 test 时,读取的内容为 nacos-config-client-test.yaml 的 config.info

案例 - Group 方案

通过 Group 实现环境区分,新建 Group(注意,组名为 DEV_GROUP)

配置完成后,如下图:

在 bootstrap.yaml 文件下增加一条 group 的配置(DEV_GROUP或TEST_GROUP),同时将application.yaml 的 spring.profile.active 配置为 info。

根据 spring.cloud.nacos.config.group 的值,来读取不同配置文件的配置。

案例 - Namespace 方案

新建 dev/tes 的 Namespace

回到服务管理-配置列表查看

按照域名配置新建配置

YAML:新增 namespace 配置(namespace 的 内容为 namespaceID)

5、Nacos 集群和持久化配置(重要)

5.1 官网说明

https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html

我们理解官网架构图,自行翻译后的架构图如下:

默认 Nacos 使用嵌入式数据库实现数据的存储。所以,如果启动多个默认配置下的 Nacos 节点,数据存储是存在一致性问题的。为了解决这个问题,Nacos 采用了 集中式存储的方式来支持集群化部署,目前只支持 Mysql 的存储

Nacos 支持三种部署模式:

  • 单机模式-用于测试和单机测试。
  • 集群模式-用于生产环境,确保高可用。
  • 多集群模式-用于多数据中心场景。

5.2 准备环境-服务器ip说明

nacos(192.168.65.128、192.168.65.129)

mysql(192.168.65.128)

nginx(192.168.65.130)

5.3.linux下 mysql初始化(192.168.65.128)

在 0.7 版本之前,在单机模式时,Nacos 使用嵌入式数据库实现数据的存储,不方便观察数据存储的基本情况。0.7版本之火增加了支持 mysql 数据源能力,具体的操作步骤:

  • 安装数据库,版本要求:5.6.5+
  • 初始化 数据库初始化文件: nacos-mysql.sql

5.4 Linux版 Nacos 

安装 nacos 需要 JAVA_HOME 环境变量,请参考 linux 下安装jdk源码_chenjian723122704的专栏-CSDN博客

Nacos 下载Linux 版 https://github.com/alibaba/nacos/releases/tag/2.0.2

在两台服务器上上传 nacos-server-2.0.2.tar.gz,并解压(我解压到 /usr/soft)。

修改 application.properties 配置文件中 数据库部分:

修改集群配置 conf/cluster.conf 

192.168.65.128:8848
192.168.65.129:8848

启动nginx:切换到 nacos/bin 目录下,执行 startup.sh

./startup.sh

输入网址 http://192.168.65.129:8848/nacos 、http://192.168.65.129:8848/nacos 分表能访问成功说明安装成功。

5.5 Nginx 的配置,由它作为负载均衡器

在 192.168.65.130 安装好nginx。

在 Nginx 配置文件中配置两台 Nacos 服务器的负载均衡,如下图。

启动 nacos

在浏览器输入 http://192.168.65.130/nacos/ ,可以访问到我们的 nacos 页面。

当停止 192.168.65.128、192.168.65.129 中的任何一个 nacos 服务时,http://192.168.65.130/nacos/ 都能正常访问;当两台 nacos 服务都停止时,则访问 http://192.168.65.130/nacos/ 出现报错页。

5.5 改造 cloudalibaba-config-nacos-client3377

在 linux 的 Nacos 增加如下配置

cloudalibaba-config-nacos-client3377 的 bootstrap.yaml 如下:

server:
  port: 3377

spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.65.130:80 #Nacos 服务注册中心
      config:
        server-addr: 192.168.65.130:80 #Nacos 配置中心
        file-extension: yaml  #指定 yaml 格式的配置

application.yaml 如下

spring:
  profiles:
    active: info

启动 cloudalibaba-config-nacos-client3377 正常。访问 http://localhost:3377/config/info ,能正常得到我们的配置。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值