SpringCloud之Nacos

SpringCloud之Nacos

一、微服务介绍

1. 什么是微服务

  2014年,Martin Fowler(马丁·福勒 ) 提出了微服务的概念,定义了微服务是由以单一应用程序构成的小服务,自己拥有自己的进程与轻量化处理,服务依业务功能设计,以全自动的方式部署,与其他服务使用 HTTP API 通信。同时服务会使用最小的规模的集中管理能力,服务可以用不同的编程语言与数据库等组件实现。

在这里插入图片描述

  马丁·福勒是敏捷联盟的成员,于2001年,同其他16名合著者一起协助创作了“敏捷软件开发宣言”。他负责维护一个bliki网站—一种blog和wiki的混合衍生物,他还使控制反转(Inversion of Control)“依赖注入模式(Dependency Injection)”一词得到普及。

2.架构的演变

  随着互联网的发展,网站应用的规模也不断的扩大,进而导致系统架构也在不断的进行变化,从互联网早起到现在,系统架构大体经历了下面几个过程:

在这里插入图片描述

  1. 单体应用架构

  把所有功能都集中在一个应用中,统一部署,开发成本、部署成本和维护成本低

  • 优点:项目架构简单,适合用户量少的项目,开发成本低,项目部署在一个节点上,维护方便。
  • 缺点:功能集中在一个工程中,对于大型项目比一开发和维护,项目模块紧耦合,单点容错率低,无法对不同的模块功能进行针对性的优化和水平拓展
  1. 垂直应用架构

  所谓垂直应用架构,其实就是把之前的单体应用拆分成多个应用,以提升效率,比如电商系统可以拆分成:电商系统、后台系统、CMS系统

  • 优点:项目拆分实现了流量分担,解决了并发问题,而且可以针对不同模块进行优化和水平拓展,同时不同的系统之间不会互相影响,提高容错率
  • 缺点:系统之间互相存在,无法进行相互调用,系统之间互相独立,会造成一部分功能的冗余
  1. 分布式架构

  随着业务的增加,在垂直应用架构中冗余的业务代码越来越多,就需要将冗余的部分抽取出来,统一做成业务层单独处理,变成一个单独的服务,控制层调用不同的业务层服务就能完成不同的业务功能,具体表现就是一个项目拆分成表现层和服务层两个部分,服务层中包含业务逻辑,表现层只需要处理和页面的交互,业务逻辑都是调用服务层的服务来实现,这就是分布式架构。

  • 优点:抽取公共的功能作为服务层,提高代码复用行。
  • 缺点:系统间耦合度变高,调用关系错综复杂,难以维护。
  1. SOA架构

  分布式架构中的缺点就是调用复杂,而且当服务越来越多,或者当某一个服务压力过大需要水平拓展和负载均衡,对于资源调度和治理就需要用到治理中心SOA(Service Oriented Architecture)为核心来解决,同时治理中心还可以帮助我们解决服务之间协议不同的问题。

  • 优点:使用治理中心(ESB\dubbo)解决了服务见调用关系的自动调节
  • 缺点:服务间会有依赖关系,一旦某个环节出错会影响较大(服务雪崩),服务关系复杂,运维、测试部署困难。
  1. 微服务架构

  微服务架构在某种程度上面架构SOA继续发展的下一步,它更加强调服务的“彻底拆分”,目的就是提高效率,微服务架构中,每个服务必须独立部署同时互不影响,微服务架构更加轻巧,轻量级。

微服务架构与SOA架构的不同

  1. 微服务架构比SOA架构会更加的精细,让专业的人去做专业的。
  2. 目的是提高效率每个服务之间互不影响,微服务架构中,每个服务需要独立部署
  3. SOA架构中可能数据库存储会发生共享,微服务强调每个服务都是单独数据库,保证每个服务之间互不影响。
  4. 微服务项目架构比SOA架构更加适合与互联网公司迅捷开发、快速迭代版本,因为粒度非常精细。

为何使用微服务呢?

在这里插入图片描述

微服务就像集群作战,可以提升性能

在这里插入图片描述

微服务架构:

在这里插入图片描述

  • 优点:服务原子化拆分,独立打包、部署和升级,保证每个微服务清晰的任务划分,利于扩展
  • 缺点:分布式系统开发的技术成本高(容错、分布式事务等),复杂性更高,每个微服务进行分布式独立部署,当进行模块调用的时候,分布式将会变得更加麻烦。

3.Spring Cloud 发展历史

Spring Cloud netflix -> Spring Cloud Alibaba

  1. 2020-12-22日Spring 官方博客宣布,Spring Cloud 2020.0.0正式发布。2020.0.0是第一个使用新的版本号命名方案的Spring Cloud 发行版本。在此之前Spring Cloud 使用英国伦敦地铁站的命名方式来命名一个大版本(train version),如果不按照新的版本号命名的话,本次的版本号应该是Ilford。
  2. 更新版本没有什么大惊小怪的,但是本次更新却正式开启了Spring Cloud Netflix 体系的终结进程。Netflix 公司是目前微服务落地中最成功的公司。它开源了诸如EurekaHystrixZuulFeignRibbon 等等广大开发者所知微服务套件,统称为Netflix OSS 。在当时Netflix OSS 成为微服务组件上事实的标准。但是在2018年Netflix 公司宣布其核心组件HystrixRibbonZuulEureka 等进入维护状态 ,不再进行新特性开发,只修BUG。这直接影响了Spring Cloud 项目的发展路线,Spring 官方不得不采取了应对措施,在2019年的在 SpringOne 2019 大会中,Spring Cloud 宣布 Spring Cloud Netflix项目进入维护模式 ,并在2020年移除相关的Netflix OSS 组件。
  3. Spring Cloud Alibaba 成为了主流

在这里插入图片描述

image.png

4. Spring Cloud Alibaba

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

4.1 简介

  Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

  依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

4.2 主要功能

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

4.3 组件介绍

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

4.3 版本说明

https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E

在这里插入图片描述

课程中使用的版本

  • SpringCloud:2020.0.1
  • SpringCloudAlibaba:2021.1
  • SpringBoot:2.4.2
  • NacosServer:2.2.3

二、Nacos介绍

1. Nacos介绍

​ Nacos(Naming Configuration Service) 是一个易于使用的动态服务发现、配置和服务管理平台,用于构建云原生应用程序

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

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

2. 什么是Nacos?

  1. Nacos = 注册中心+配置中心组合

  2. Nacos支持几乎所有主流类型的“服务”的发现、配置和管理,常见的服务如下:

    Kubernetes Service

    gRPC & Dubbo RPC Service

    Spring Cloud RESTful Service

3. 为何使用Nacos?

​ 为何使用注册中心呢?我们以入住酒店的前台为例子,稍微加以解释。先设想一个没有服务前台的酒店,客人入住需要自己寻找合适居住的房间,客人不知道每个房间的情况,无法确定那个房间是打扫干净可以入住,客人只能逐个房间寻找,如果遇到已经居住房客的房间一定很尴尬,显然这是不正常的情况。正常的情况是酒店会安排服务台,酒店打扫干净可以入住的房间会登记注册到服务台,这样客人来住店,只需要在前台就可以查找到可以入住的房间,这样就无需等待快速的入住。显然,服务器提供发注册和发现机制可以让房客快速找到合适的房间,快速解决入住问题。

在这里插入图片描述

​ 采用微服务以后,软件微服务组件各自独立,但最终还要组合为一个整体作为一个软件系统服务于最终客户,这时软件组件之间也需要彼此通讯,彼此调用方法。微服务架构内部发起通讯调用方法的一方成为“服务消费者”,提供远程方法调用的服务器称为“服务提供者”,往往为了提高系统性能,会提供多个服务器作为服务提供者,此时服务消费者找到服务提供者的过程,就类似于用户在找房间的过程。为了帮助服务消费者快速的发现服务提供者,在微服务框架中都会引入注册中心。注册中心类似于酒店的前台,提供在软件服务的注册和发现功能,服务提供者会先在注册中心进行注册,声明可以对外提供服务,而服务消费者只需要在注册中心就可以快速发现找到可以使用的服务,快速使用服务。注册中心实现了服务提供和服务消费的快速撮合功能。

在这里插入图片描述

4. 下载和安装

官网网址:https://nacos.io/zh-cn/index.html

在这里插入图片描述

官网文档网址:https://nacos.io/zh-cn/docs/quick-start.html

注意:使用官网推荐的稳定版本:

在这里插入图片描述

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

下载之后安装过程

  1. 解压以后找到bin目录
    在这里插入图片描述

  2. 执行指令:

    Linux/Unix/Mac

    启动命令(standalone代表着单机模式运行,非集群模式):

    sh startup.sh -m standalone
    

    Windows

    启动命令(standalone代表着单机模式运行,非集群模式):

    startup.cmd -m standalone
    
  3. 结果:

    在这里插入图片描述

  4. 得到结果以后为了验证是否成功开启Nacos,我们需要访问:http://localhost:8848/nacos

在这里插入图片描述

  1. 出现此界面表示已经成功启动Nacos,默认的账号密码是:nacos/nacos

在这里插入图片描述

  1. 到这里就是成功开启了Nacos服务了。

5.Nacos持久化配置

  Nacos默认自带嵌入式数据库derby,所以我们每次创建一个Nacos实例就会有一个derby,当有多个Nacos节点的时候,就会出现一致性问题,所以Nacos支持了外部数据库统一数据管理MySql。

官网地址:https://nacos.io/zh-cn/docs/deployment.html

修改application.properties文件。把MySQL的配置放开

在这里插入图片描述

找到Nacos安装目录下的conf目录中的Sql脚本,然后在数据库中进行执行,先创建db-nacos的数据库

在这里插入图片描述

然后重启服务即可

三、注册中心

​ Nacos可以直接提供注册中心(Eureka)+配置中心(Config),所以它的好处显而易见,我们在前面成功安装和启动了Nacos以后就可以发现Nacos本身就是一个小平台,它要比之前的Eureka更加方便,不需要我们在自己做配置。

​ 服务发现是微服务架构中的关键组件之一。在这样的架构中,手动为每个客户端配置服务列表可能是一项艰巨的任务,并且使得动态扩展极其困难。Nacos Discovery 帮助您自动将您的服务注册到 Nacos 服务器,Nacos 服务器会跟踪服务并动态刷新服务列表。此外,Nacos Discovery 将服务实例的一些元数据,如主机、端口、健康检查 URL、主页等注册到 Nacos。

​ 学习任何知识我们都需要从它的官方文档入手,所以我们直接来看官网给我们提供的文档:https://spring.io/projects/spring-cloud-alibaba#learn

在这里插入图片描述

1.创建父项目

  首先创建一个Maven的父项目。用来聚合管理。并声明了SpringCloud和SpringCloudAlibaba的版本

<properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><spring-cloud-alibaba-version>2021.1</spring-cloud-alibaba-version><spring-cloud.version>2020.0.1</spring-cloud.version>
</properties><dependencyManagement><dependencies><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><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>

2.服务提供者

  然后创建一个服务提供者的模块。父项目为上面创建的项目,同样是一个SpringBoot项目。pom.xml中的完整依赖信息如下:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.boge</groupId><artifactId>NacosProviderExample9001</artifactId><version>0.0.1-SNAPSHOT</version><name>NacosProviderExample9001</name><parent><groupId>com.boge</groupId><artifactId>SpringCloudExample</artifactId><version>1.0-SNAPSHOT</version></parent><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.4.2</spring-boot.version></properties><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><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><mainClass>com.boge.provider.AppProviderStart</mainClass><skip>true</skip></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>

然后在application.yml中添加nacos的配置信息

server:port: 9001
spring:application:name: nacos-providercloud:discovery:server-addr: 127.0.0.1:8848management:endpoint:web:exposure:include:'*'

然后在启动类中添加@EnableDiscoveryClient注解

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

然后添加提供的服务接口

@RestController
public class DemoController {@Value("${server.port}")private String serverPort;@GetMapping(value = "/bobo")public String getServerPort(){return "Hello Nacos Discovery"+serverPort;}
}

注意需要在父项目中标记:

<modules><module>NacosProviderExample9001</module>
</modules>

启动服务我们就可以在Nacos中服务列表中看到注册的服务信息

在这里插入图片描述

3.服务消费者

  同样的我们再创建一个服务消费者的SpringBoot项目。并添加相关的依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.boge</groupId><artifactId>NacosConsumerExample9101</artifactId><version>0.0.1-SNAPSHOT</version><name>NacosConsumerExample9101</name><description>Demo project for Spring Boot</description><parent><groupId>com.boge</groupId><artifactId>SpringCloudExample</artifactId><version>1.0-SNAPSHOT</version></parent><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.4.2</spring-boot.version></properties><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><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><mainClass>com.boge.consumer.AppConsumerStart</mainClass><skip>true</skip></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>

然后在属性文件中添加对应的配置信息

server:port: 9101
spring:application:name: nacos-consumercloud:discovery:server-addr: localhost:8848
service-url:nacos-user-service: http://nacos-provider

同样在父项目中记得添加关系

<modules><module>NacosProviderExample9001</module><module>NacosConsumerExample9101</module>
</modules>

在主启动类中一样添加对应的注解

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

启动消费服务后一样可以在Nacos服务列表中看到注册的服务信息

在这里插入图片描述

4.服务调用

  上面我们创建了服务的提供者和服务的消费者。但是都只是完成了服务的nacos注册。并没有串联起来。在我们使用的SpringCloudAlibaba2021版本中移除了Ribbon,因为Ribbon已经停止更新维护了。使用loadBalancer作用新的负载均衡器。我们需要添加新的依赖

        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>

然后需要配置RestTemplate来实现远程调用

@EnableDiscoveryClient
@SpringBootApplication
public class AppConsumerStart {public static void main(String[] args) {SpringApplication.run(AppConsumerStart.class, args);}@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}}

然后在服务调用的接口中的获取RestTemplate对象。并完成相关的逻辑

@RestController
public class DemoController {@Autowiredprivate RestTemplate restTemplate;/*** 消费者去访问具体服务,这种写法可以实现* 配置文件和代码的分离*/@Value("${service-url.nacos-user-service}")private String serverURL;@GetMapping(value = "consumer/nacos")public String getDiscovery(){System.err.println(serverURL);return restTemplate.getForObject(serverURL+"/bobo",String.class);}
}

说明:getForObject方法的参数的含义

第一个参数url表示被调用的目标Rest接口位置

	1. url的第一部分是在Nacos中注册的服务提供者名称,如果多个服务提供者注册相同名称,Ribbon会自动寻找其中一个服务提供者,并且调用接口方法。这个就是负载均衡功能。2. url后半部是控制器的请求路径。

第二个参数是返回值类型

  1. JavaBean类型或者JavaBean数组类型,如果控制器返回的是List集合,需要使用数组类型接收。

第三个参数是可变参数

  1. 是传递给url的动态参数,使用参数时候需要在url上需要使用{1}、{2}、{3}进行参数占位,这样传递的参数就会自动替换占位符。

启动服务后访问测试:http://localhost:9101/consumer/nacos

在这里插入图片描述

看到上面的返回信息说明访问成功了。

5.OpenFeign服务调用

  OpenFegin是一个声明式的服务调用组件。本质上是封装的Ribbon实现的。

在这里插入图片描述

然后添加相关的依赖

        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>

然后创建对应的Feign接口

@FeignClient(name = "nacos-provider")
public interface ProviderService {@GetMapping(value = "/bobo")public String getServerPort();
}

然后在启动类中添加@EnableFeignClients(basePackages = "com.boge.consumer.feign")注解。指定我们存放Feign接口的位置

@EnableFeignClients(basePackages = "com.boge.consumer.feign")
@EnableDiscoveryClient
@SpringBootApplication
public class AppConsumerStart {public static void main(String[] args) {SpringApplication.run(AppConsumerStart.class, args);}@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}}

然后在controller中通过OpenFeign实现服务的远程调用

@RestController
public class DemoController {@Autowiredprivate ProviderService providerService;@GetMapping(value = "consumer/nacos2")public String getDiscovery2(){System.err.println("--->"+serverURL);return restTemplate.getForObject(serverURL+"/bobo",String.class);}}

启动服务后访问测试:http://localhost:9101/consumer/nacos2

在这里插入图片描述

6.注册中心对比

服务注册与发现框架CAP模型控制台管理社区活跃度
EurekaAP支持低(2.x版本闭源)
ZookeeperCP不支持
ConsulCP支持
NacosAP/CP支持

CAP模型

​ 计算机专家 埃里克·布鲁尔(Eric Brewer)于 2000 年在 ACM 分布式计算机原理专题讨论会(简称:PODC)中提出的分布式系统设计要考虑的三个核心要素:

  • 一致性(Consistency):同一时刻的同一请求的实例返回的结果相同,所有的数据要求具有强一致性(Strong Consistency)
  • 可用性(Availability):所有实例的读写请求在一定时间内可以得到正确的响应
  • 分区容错性(Partition tolerance):在网络异常(光缆断裂、设备故障、宕机)的情况下,系统仍能提供正常的服务

  以上三个特点就是CAP原则(又称CAP定理),但是三个特性不可能同时满足,所以分布式系统设计要考虑的是在满足P(分区容错性)的前提下选择C(一致性)还是A(可用性),即:CP或AP

CP原则

一致性 + 分区容错性原则

​ CP 原则属于强一致性原则,要求所有节点可以查询的数据随时都要保持一直(同步中的数据不可查询),即:若干个节点形成一个逻辑的共享区域,某一个节点更新的数据都会立即同步到其他数据节点之中,当数据同步完成后才能返回成功的结果,但是在实际的运行过程中网络故障在所难免,如果此时若干个服务节点之间无法通讯时就会出现错误,从而牺牲了以可用性原则(A),例如关系型数据库中的事务。

AP原则

可用性原则 + 分区容错性原则

​ AP原则属于弱一致性原则,在集群中只要有存活的节点那么所发送来的所有请求都可以得到正确的响应,在进行数据同步处理操作中即便某些节点没有成功的实现数据同步也返回成功,这样就牺牲一致性原则(C 原则)。

​ 使用场景:对于数据的同步一定会发出指令,但是最终的节点是否真的实现了同步,并不保证,可是却可以及时的得到数据更新成功的响应,可以应用在网络环境不是很好的场景中。

Nacos的AP/CP

​ Nacos无缝支持一些主流的开源生态,同时再阿里进行Nacos设计的时候重复的考虑到了市场化的运作(市面上大多都是以单一的实现形式为主,例如:Zookeeper使用的是 CP、而 Eureka采用的是AP),在Nacos中提供了两种模式的动态切换。

在这里插入图片描述

Nacos 何时选择切换模式

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

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

  3. 切换命令(默认是AP):

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

注意:临时和持久化的区别主要在健康检查失败后的表现,持久化实例健康检查失败后会被标记成不健康,而临时实例会直接从列表中被删除。

四、配置中心

1.基础配置

1.1 添加依赖

  我们需要添加Nacos作为配置中心的依赖信息

<dependency> <groupId> com.alibaba.cloud </groupId> <artifactId> spring-cloud-starter-alibaba-nacos-config </artifactId> 
</dependency>

1.2 配置信息

  然后我们需要在bootstrap.yaml中配置配置中心的相关信息。注意的是这里我们要配置两个,因为Nacos同SpringCloud-config一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动。

​ springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application

​ 分别要配置的是,这里bootstrap.yml配置好了以后,作用是两个,第一个让3377这个服务注册到Nacos中,第二个作用就是去Nacos中去读取指定后缀为yaml的配置文件:

# nacos配置
server:port: 3377spring:application:name: nacos-config-clientcloud:nacos:discovery:server-addr: localhost:8848 #Nacos服务注册中心地址config:server-addr: localhost:8848 #Nacos作为配置中心地址file-extension: yaml #指定yaml格式的配置

application.yml

spring:profiles:active: dev # 表示开发环境

1.3 主启动类

  在主启动类上添加对应的注解

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

1.4 业务类

​ 这里的@RefreshScope实现配置自动更新,意思为如果想要使配置文件中的配置修改后不用重启项目即生效,可以使用@RefreshScope配置来实现

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

1.5 Nacos的配置规则

​ 在 Nacos Spring Cloud 中,dataId 的完整格式如下(详情可以参考官网 https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html):

${prefix}-${spring.profiles.active}.${file-extension}
  1. prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
  2. spring.profiles.active 即为当前环境对应的 profile,注意:spring.profiles.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}(不能删除)
  3. file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 propertiesyaml 类型。
  4. 通过 Spring Cloud 原生注解 @RefreshScope 实现配置自动更新:
  5. 所以根据官方给出的规则我们最终需要在Nacos配置中心添加的配置文件的名字规则和名字为:

s p r i n g . a p p l i c a t i o n . n a m e − {spring.application.name}- spring.application.name{spring.profiles.active}.${file-extension}

nacos-config-client-dev.yaml

微服务名称-当前环境-文件格式

在这里插入图片描述

1.6 配置创建

  然后在nacos中添加相关的配置信息

在这里插入图片描述

在这里插入图片描述

config: info: nacos config center,version = 1

然后在配置中心就会看到刚刚发布的配置

在这里插入图片描述

1.7 自动配置更新

  修改Nacos配置,不需要重启项目即可自动刷新.

在这里插入图片描述

修改版本号为2,点击发布

在这里插入图片描述

测试访问即可,注意在SpringBoot2.4之后需要显示的添加如下的依赖。bootstrap.yaml 才会生效

<!-- SpringBoot2.4之后要让 bootstrap.yaml 文件生效我们需要添加该依赖 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

2.综合应用

2.1 DataID

  在实际的开发中我们需要面对各种不同的环境。比如开发环境。测试环境和生产环境。不同的环境下我们的配置信息是有差异的。这时我们就可以通过spring.profile.active来指定不同的环境来对应不同的配置文件。

比如我们上面的案例是dev开发环境。那么对应的配置文件的名称就是nacos-config-client-dev.yaml.然后我们把对应的环境切换到test测试环境。那么对应的配置文件的名称就是nacos-config-client-test.yaml.然后我们在nacos中创建该配置文件

在这里插入图片描述

在这里插入图片描述

项目的spring.profile.active也需要变动下

在这里插入图片描述

然后测试访问

在这里插入图片描述

2.2 Group

  上面我们通过DataID来配置我们的配置信息。这种场景是把项目中的所有信息都配置在了一个配置文件中。这个会造成配置信息非常多。不便于管理这时我们可以根据配置信息的类别通过Group来对配置信息进行分组。我们可以把配置信息中的MyBatis的和数据库的相关配置信息都单独的区分出来。在创建配置文件的时候指定分组即可。我们前面创建的使用的是默认分组DEFAULT_GROUP.

MYBATIS组: 注意:DataID还是一致的

在这里插入图片描述

DB

在这里插入图片描述

然后在项目中我们指定对应的分组即可

在这里插入图片描述

测试访问即可:

在这里插入图片描述

2.3 namespace

   上面的group方案可以基于配置信息的内容做划分。但是在实际的项目环境中。项目环境是比较复杂的。不同的项目不同的模块会有很多相似或者交叉的。这时我们可以通过namespace来实现环境之间的隔离。

  namespace默认是public,这个我们不能删除。我们直接新建两个namespace: OA和CRM
在这里插入图片描述

在这里插入图片描述

上面的命名空间的ID我们是用的自动生成的即可。

在CRM的命名空间下创建配置文件

在这里插入图片描述

在这里插入图片描述

然后在OA的命名空间下创建配置文件

在这里插入图片描述

然后在代码中完成相关的配置

在这里插入图片描述

然后在bootstrap.yaml中配置命名空间

server:port: 7777
spring:application:name: nacos-config-clientcloud:nacos:discovery:server-addr: localhost:8848 #Nacos服务注册中心地址config:server-addr: localhost:8848 #Nacos作为配置中心地址file-extension: yaml #指定yaml格式的配置group: MYBATIS # 指定groupnamespace: 4445ef5b-1851-40ee-851d-8a811de16134 # 指定 namespace

测试即可看到期望的结果:

在这里插入图片描述

2.4 配置拆分

  上面的讲解中我们的DataID还是统一的。我们可以通过group的方式来拆分不同的配置信息。当然我们还可以通过配置拆分的形式。我们定义不同类型的配置文件。比如:

在这里插入图片描述

然后在项目中我们特别指导改配置信息即可

server:port: 7777
spring:application:name: nacos-config-clientcloud:nacos:discovery:server-addr: localhost:8848 #Nacos服务注册中心地址config:server-addr: localhost:8848 #Nacos作为配置中心地址file-extension: yaml #指定yaml格式的配置# group: prod # 指定groupnamespace: 4445ef5b-1851-40ee-851d-8a811de16134 # 指定 namespace# 可以配置多个配置集extension-configs[0]: # 配置拆解data-id: mybatis-config.yamlgroup: prodrefresh: true

访问测试:

在这里插入图片描述

搞定!

2.5 三者的关系

  命名空间(Namespace)、配置分组(Group)和配置集ID(Data ID)是Nacos中的三个概念,用于进行资源管理和配置管理。

它们的区别和作用如下:

命名空间(Namespace):定义:用于隔离和管理不同的资源,每个命名空间有唯一的标识符。作用:资源隔离、权限控制、环境隔离。配置分组(Group):定义:用于对配置进行分类管理,每个配置分组有唯一的标识符。作用:配置分类、配置隔离、动态刷新。配置集ID(Data ID):定义:用于唯一标识一个配置集,每个配置集有唯一的Data ID。作用:配置集的唯一标识、配置集的分类管理、配置集的动态刷新。

  在使用Nacos时,可以根据具体的需求和场景,合理使用命名空间、配置分组和配置集ID来进行资源和配置的管理。

五、Nacos集群搭建

1.集群结构

  Nacos的集群环境我们采用这种结构:3个Nacos注册中心+1个MySql

在这里插入图片描述

2.Nacos集群

  我们在windows上安装3个Nacos节点。分配配置相关信息

application.properties: 持久化数据到mysql中

在这里插入图片描述

修改 cluster.conf.examplecluster.conf然后在里面写上相关的集群节点信息

#2023-12-01T14:34:17.038
192.168.1.111:8848
192.168.1.111:8868
192.168.1.111:8888

这里注意,我们在修改端口的时候一定要有一定的偏移量,因为Nacos2.0本身新增了占用端口,所以我们在设置端口号的时候注意要避开,不要占用端口,以下是官网截图:

在这里插入图片描述

三个节点服务。注意不要放在有中文的目录下

在这里插入图片描述

然后分配启动三个服务即可

在这里插入图片描述

然后分配登录测试

在这里插入图片描述

然后把我们前面写的服务提供者和服务消费者注册到nacos中

在这里插入图片描述

然后可以看到相关的注册信息

在这里插入图片描述

3.Nginx负载均衡

  上面我们配置了3个nacos的服务节点。具体调用哪个节点来注册我们可以通过nginx更好的来实现管理。我们下载个windows 版本的nginx:http://nginx.org/en/download.html

在这里插入图片描述

修改nginx.conf文件。添加负载均衡的配置


#user  nobody;
worker_processes  1;events {worker_connections  1024;
}http {include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;upstream nacos {server 192.168.1.111:8848;server 192.168.1.111:8868;server 192.168.1.111:8888;}#gzip  on;server {listen       80;server_name  192.168.1.111;#charset koi8-r;#access_log  logs/host.access.log  main;location / {proxy_pass http://nacos;}}
}

然后通过start nginx 来启动nginx服务

在这里插入图片描述

然后启动成功。同时我们可以在服务中也通过nginx来负载

在这里插入图片描述

启动后发现服务也正常的注册成功了

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/29317.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot集成websocket实现webrtc功能

1.什么是webrtc&#xff1f; WebRTC 是 Web 实时通信&#xff08;Real-Time Communication&#xff09;的缩写&#xff0c;它既是 API 也是协议。WebRTC 协议是两个 WebRTC Agent 协商双向安全实时通信的一组规则。开发人员可以通过 WebRTC API 使用 WebRTC 协议。目前 WebRTC…

WPF学习(4)--SCICHART学习

一、项目创建过程 1.下载SCICHART插件 2.选中第一个&#xff0c;确保引用中有我们要用的 二、示例代码 1.前端代码 <Window x:Class"SciChart.Examples.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"h…

centos 7无需token编译安装freeswitch 1.10.11 ——筑梦之路

准备工作 安装编译工具和依赖包 yum update -y sudo yum install epel-release vim tcpdump net-tools.x86_64 -y sudo yum install gcc-c sqlite-devel zlib-devel libcurl-devel pcre-devel speex-devel ldns-devel libedit-devel openssl-devel git -y yum install yasm n…

DFS 迷宫

个人感觉DFS没有递归那么烧脑 简单迷宫 如何接受二维数组 先构建A[MAXN][MAXN]&#xff0c;人后二重循环 #include <iostream> #include <vector> #include <cmath> #include <string> #include <cstring> using namespace std; const int N…

微型操作系统内核源码详解系列五(2):cm3下栈的初始化

系列一&#xff1a;微型操作系统内核源码详解系列一&#xff1a;rtos内核源码概论篇&#xff08;以freertos为例&#xff09;-CSDN博客 系列二&#xff1a;微型操作系统内核源码详解系列二&#xff1a;数据结构和对象篇&#xff08;以freertos为例&#xff09;-CSDN博客 系列…

windows反弹shell的方法

什么是正向shell和反向shell 首先说&#xff0c;正向shell是控制端主动连接被控制端&#xff0c;通过目标主机开放一个监听端口等待其他主机访问&#xff0c;从而获得对目标主机的shell访问&#xff0c;优点是控制端可以整个控制目标主机&#xff0c;但缺点会受到防火墙的连&a…

手机usb共享网络电脑没反应的方法

适用于win10电脑&#xff0c;安卓手机上可以 开启usb网络共享选择&#xff0c;如果选择后一直跳&#xff0c;让重复选择usb选项的话&#xff0c;就开启 开发者模式&#xff0c;进到 开发者模式 里设置 默认usb 共享网络 选项 &#xff0c;就不会一直跳让你选。 1.先用数据线 连…

如何通过Appium连接真机调试

1、打开appium&#xff0c;点击启动appium服务器&#xff08;如图1&#xff09; 2、appium启动成功后&#xff0c;点击放大镜启动检查会话&#xff08;如图2&#xff09; 3、填写真机设备信息和APP的package、activity,点击启动会话&#xff08;如图3&#xff09; 4、打开运行A…

数据结构-十大排序算法集合(四万字精讲集合)

前言 1&#xff0c;数据结构排序篇章是一个大的工程&#xff0c;这里是一个总结篇章&#xff0c;配备动图和过程详解&#xff0c;从难到易逐步解析。 2&#xff0c;这里我们详细分析几个具备教学意义和实际使用意义的排序&#xff1a; 冒泡排序&#xff0c;选择排序&#xff0c…

Swift Combine — Subject Publishers(PassthroughSubject CurrentValueSubject)

本文主要介绍一下Subject&#xff0c;Subject 本身也是一个 Publisher&#xff0c;其定义如下&#xff1a; public protocol Subject<Output, Failure> : AnyObject, Publisher {func send(_ value: Self.Output)func send(completion: Subscribers.Completion<Self.…

【漏洞复现】泛微OA E-Cology ln.FileDownload 任意文件读取漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

JAVA开发 选择本地的文件,控制台输出选择的文件名

打开文件选择器对话框&#xff0c;控制台输出选择的文件 1、展示效果2、实现代码3、JFileChooser类 1、展示效果 2、实现代码 import javax.swing.*; import java.io.*; import java.text.SimpleDateFormat; import java.util.Date;public class GenerateCompress {public sta…

强大的api管理系统Storm Core API_V1.1免授权源码

强大的api管理系统Storm Core API_V1.1免授权源码&#xff0c;带用户key和ip白名单功能 可设置付费操作等 更新日志 此次更新功能比较多 1.完善个人中心页面 2.完善注册登录页面 3.完善key功能 4.增加ip白名单功能 5.以及一些其他小小的美化 6.模板dxx的图片可单个自定…

AWS——01篇(AWS入门 以及 AWS之EC2实例及简单实用)AWS

AWS——01篇&#xff08;AWS入门 以及 AWS之EC2实例及简单实用&#xff09; 1. 前言 2. 创建AWS账户 3. EC2 3.1 启动 EC2 新实例 3.1.1 入口 3.1.2 设置名称 选择服务 3.1.3 创建密钥对 3.1.4 网络设置——安全组 3.1.4.1 初始设置 3.1.4.2 添加安全组规则&#xff08;开放新…

【Linux】MySQL下载与安装

1. 下载压缩包 官网下载 2. 解压 上传并解压好放在指定位置 创建soft文件夹 mkdir /soft上传文件&#xff0c;在该目录下再创建一个mysql文件夹&#xff0c;将安装包解压到新文件夹中 mkdir /soft/mysql-8.3.0 tar -xvf mysql-8.3.0-1.el9.x86_64.rpm-bundle.tar -C mysq…

C语言 | Leetcode C语言题解之第162题寻找峰值

题目&#xff1a; 题解&#xff1a; int findPeakElement(int* nums, int numsSize) {int ls_max0;for(int i1;i<numsSize;i){if(nums[ls_max]>nums[i]);else{ls_maxi;}}return ls_max; }

2024上海初中生古诗文大会倒计时4个月:单选题真题和独家解析

现在距离2024年初中生古诗文大会还有4个多月时间&#xff0c;我们继续来看10道选择题真题和详细解析&#xff0c;以下题目截取自我独家制作的在线真题集&#xff0c;都是来自于历届真题&#xff0c;去重、合并后&#xff0c;每道题都有参考答案和解析。 为帮助孩子自测和练习&…

演示:WPF开发的Diagram自动化流程图应用

一、目的&#xff1a;演示Diaram应用功能 二、预览 三、功能列表 功能模块 通用测试 流程图 仪器仪表 机器人 网络通信测试 PLC测试 轮毂生产线流程测试 图像处理 目标检测 绘图 思维导图 图表 流程图功能 模板管理 工程管理 模块许可管理 工具栏 开始 停止 删除 清除 …

RabbitMQ实践——对不可路由的消息的处理方法

大纲 无备用&#xff08;Alternate&#xff09;交换器构建交换器、队列和绑定关系测试代码抛弃不可路由消息返还不可路由消息 有备用&#xff08;Alternate&#xff09;交换器创建带备用&#xff08;Alternate&#xff09;交换器的交换器mandatory非mandatory 总结 在实际工作中…

【DevOps】Elasticsearch 数据跨集群同步方案

目录 1、Elasticsearch Cross-Cluster Replication (CCR) 1.1、优点 1.2、缺点 1.3、步骤 1.4、示例 2. Logstash 或其他 ETL 工具 2.1、优点 2.2、缺点 2.3、步骤 3. Apache Kafka 或 RabbitMQ 3.1、优点 3.2、缺点 3.3、步骤 4、使用 Reindex API 进行跨集群同…