22-07-24 西安 SpringCloud(03) SpringCloud alibaba、Nacos、CAP和Base

发布于:2023-02-16 ⋅ 阅读:(612) ⋅ 点赞:(0)

诡异的实验现象:在你不对实验中的光束做任何观测的时候,光是以波的形式存在的;但当你开始观测光的运动轨迹时,光又变成了粒子形态。

换句话说,你的这个观测行为本身,竟然影响了客观事物!            -------《双缝干涉实验》


Spring Cloud Netflix项目进入维护模式,将模块置于维护模式,意味着SpringCloud团队将不会再向模块添加新功能。

进入维护模式意思就是目前以致以后一段时间SpringCloud netflix提供的服务和功能就这么多了,不再开发新的组件和功能了


SpringCloud alibaba

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

Spring Cloud Alibaba 提供微服务开发一站式解决方案,可以用来:

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

替换Netflix那一套

Sentinel:把流量作为切入点,从流量控制熔断降级、系统负载保护等多个维度保护服务的稳定性。

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

RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。

Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架

Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。

Alibaba Cloud ACM:一款在分布式架构环境中对应用配置进行集中管理和推送的应用配置中心产品。

Alibaba Cloud OSS: 阿里云对象存储服务Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。

Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。

Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。 


Nacos:Dynamic Naming and Configuration Service

一个更易于构建云原生应用的动态服务发现,配置管理和服务管理中心

Nacos = Eureka+Config+Bus

Sentinel:把流量作为切入点,从流量控制熔断降级、系统负载保护等多个维度保护服务的稳定性。

nacos官方文档: home

各注册中心比较


CAP原则

分布式系统设计要满足CAP原则

分布式系统定义:分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统

CAP定理 指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。

CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

CP:在规定时间内达到数据一致性
AP:在规定时间内达到可用性(集群节点能和客户端正常通信)

数据一致性(C):指强一致性,在分布式系统中的所有数据备份,在同一时刻是否同样的值

数据一致性分为强一致性和最终一致性,强一致性指的如果数据不一致,就不对外提供数据服务,保证
用户读取的数据始终是一致的。数据强一致性只需要通过锁机制即可解决,只有当数据同步完成以后才对外提供服务。
而最终一致性要求数据最终同步即可,没有实时性要求。

可用性(A):系统提供的服务要一直处于可用状态。在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求,超出时间范围 认为服务不可用

要求数据需要备份

分区容忍性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。分区容错性是必须保证的

因此在进行分布式架构设计时,必须做出取舍。当前一般是通过分布式缓存中
各节点的最终一致性来提高系统的性能,通过使用多节点之间的数据异步复制技术来实现集群化的数据一致性。

而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们无法避免的。所以我们只能在一致性和可用性之间进行权衡,没有系统能同时保证这三点。要么选择CP、要么选择AP。


3个注册中心的区别

 Zookeeper 保证的是 CP,而 Eureka 保证的则是 AP,Nacos可以支持AP和CP的切换 

Zookeeper 保证的是 CP

Zookeeper取CAP的CP注重一致性,在可用性方面不太好,假如master节点故障,剩余节点会重新leader选举,选举leader的时间太长30~120s,选举期间整个集群都不可用,这就导致在选举期间注册服务瘫痪,漫长选举导致注册不可用,不能容忍。

Eureka 保证的则是 AP

Eureka对以上问题做了优化,所以在设计时就优先保证可用性。取CAP的AP,注重可用性。Eureka各个节点都是平等的,只要有一台Eureka还在就能保证注册服务可用(保证可用性),只不过可能查询到的不是最新的。

Nacos可以支持AP和CP的切换

Nacos从1.0版本选择Ap和CP混合形式实现注册中心,默认情况下采用Ap保证服务可用性,CP形式底层采用Raft协议保证数据的一致性问题。

如果选择为Ap模式,注册服务的实例仅支持临时模式,在网络分区的的情况允许注册服务实例。

选择CP模式可以支持注册服务的实例为持久模式,在网络分区的产生了抖动情况下不允许注册服务实例。

BASE 【我们的妥协】

BASE是对CAP中一致性和可用性权衡的结果

其来源于对大规模互联网系统分布式实践的结论,是基于CAP定理逐步演化而来的,其核心思想是即使无法做
到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达
到最终一致性(Eventual consistency)。

接下来看看BASE中的三要素

  1. Basically Available(基本可用

    基本可用是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。 电商大促时,为了应对访问量激增,部分用户可能会被引导到降级页面,服务层也可能只提供降级服务。这就是损失部分可用性的体现。

  2. Soft state(软状态)

    软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据至少会有三个副本,允许不同节点间副本同步的延时就是软状态的体现。mysql replication的异步复制也是一种体现。

  3. Eventually consistent(最终一致性

    最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。

BASE模型是传统ACID模型的反面,不同于ACID,BASE强调牺牲高一致性,从而获得可用性,数据允许在一段时间内的不一致,只要保证最终一致就可以了


Nacos 服务发现与配置管理

1、安装运行Nacos

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

  • 替代Eureka做服务注册中心
  • 替代Config做服务配置中心  【放配置文件的服务器

安装运行Nacos

官网下载·:Release 1.4.2 (Apr 29th, 2021) · alibaba/nacos · GitHub

解压安装包(没有中文,没有空格的目录),运行bin目录下的命令  startup.cmd -m standalone

默认:MODE="cluster"集群方式启动,如果单机启动需要设置-m standalone参数,否则,启动失败。

当然也可以这样做:
修改startup.cmd文件中的第26行,改为:set MODE="standalone"以后双击启动即可

注意:要是像我这样改动了/conf/application.properties

把nacos持久化为mysql,得先启动mysql服务

在Linux中启动mysql服务:     systemctl start mysqld

原样是这样的

db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false
db.user=root
db.password=123456

之后访问  http://localhost:8848/nacos

默认账号密码都是nacos,登录后的页面如下。看着挺清爽的。

老师说:独立运行,这玩意多好,Eureka还要创建项目


2、Nacos作为注册中心(服务发现)

创建工程  cloudalibaba-provider-payment9001

1、引入的核心依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2.2.0.RELEASE</version>
</dependency>

2、写配置文件

   nacos默认5秒发送一次心跳
   nacos服务端认为超过三次没有发送心跳的服务宕机了(15秒)

server:
  port: 9001

spring:
  application:
    name: nacos-payment-provider
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #配置Nacos地址

management:
  endpoints:
    web:
      exposure:
        include: '*'  #默认只公开了/health和/info端点,要想暴露所有端点只需设置成星号

3、主启动

启动类或配置类加上注解@EnableDiscoveryClient

 4、在controller层写一个控制器方法【伏笔,以后会用到】

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

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

启动该工程 cloudalibaba-provider-payment9001,看看nacos的变化


3、Nacos的负载均衡

1、创建Nacos服务消费者工程 cloudalibaba-consumer-nacos-order83

1、最核心依赖也是

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

2、写配置文件

 消费者访问的是哪个微服务名称,而不是具体的地址,为负载均衡准备 

server:
  port: 83

spring:
  application:
    name: nacos-order-consumer
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
#消费者将要去访问的微服务名称(注册成功进nacos的微服务提供者【可选】,注意:nacos-payment-provider含有IP和端口)
service-url:
  nacos-user-service: http://nacos-payment-provider

3、主启动

4、使用RestTemplate 完成远程调用

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

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

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

2、copy出来一个9002工程

3、查看nacos控制台并在浏览器页面测试

4、完工测试轮询负载均衡

 我们去访问消费端  http://localhost:83/consumer/payment/nacos/1


4、Nacos作为配置中心

1、新建模块  cloudalibaba-config-nacos-client3377

1、最核心依赖(其他依赖一概不管)

<!--nacos-config 配置中心-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--nacos-discovery注册中心-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2、

Nacos在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动,springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于application

创建配置文件 bootstrap.yml

server:
  port: 3377

spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #服务注册中心地址
      config:
        server-addr: localhost:8848 #配置中心地址
        file-extension: yaml #指定yaml格式的配置(yml和yaml都可以)
        group: DEV_GROUP
        namespace: 14957e59-e90f-4ad8-bb84-b27908692933

application.yml中激活

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

3.主启动 

4.在controller层

  • 新加了一个注解,@RefreshScope, 动态获取配置中心的配置文件内容
  • @Value("${config.info}") 在本地的配置文件是没有的,对应远端的配置文件nacos-config-client-dev.yaml
@RestController
@RefreshScope   //通过SpringCould原生注解@RefreshScope实现配置自动更新
public class ConfigClientController{
    @Value("${config.info}") //对应nacos配置:nacos-config-client-dev.yaml
    private String configInfo;

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

2、Nacos中的dataid的组成格式与SpringBoot配置文件中的匹配规则

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

服务名-激活的文件-文件扩展名
故对应 : nacos-config-client-dev.yaml

Data Id 就是文件名nacos-config-client-dev.yaml

3、测试

1、启动的时候如果报错

检查配置文件,在该命名空间该分组下要有计算出来的配置文件才行

2、 成功启动后,在浏览器输入地址测试

3、在nacos控制台修改nacos-config-client-dev.yaml的内容

 刷新页面,发现直接就拿到了,正是controller上这个注解的功劳@RefreshScope, 动态获取配置中心的配置 文件内容

4、Nacos 分类配置(开发环境、测试环境、生产环境)

 默认情况:Namespace=public,Group=DEFAULT_GROUP,默认Cluster是DEFAULT

Namespace主要用来实现隔离 

比组更大的分类。---命名空间(里面有很对个组)

比方说我们现在有三个环境:开发、测试、生产环境,我们就可以创建三个Namespace,不同的 Namespace之间是隔离的。

namespace:id

Group默认是DEFAULT_GROUP

Group可以把不同的微服务划分到同一个分组里面去。Service就是微服务;一个Service可以包含多个Cluster(集群),Nacos默认Cluster是DEFAULT,Cluster是对指定微服务的一个虚拟划分。

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


5、Nacos持久化和集群配置

Nacos默认自带的是嵌入式数据库derby,从derby到mysql切换配置步骤

1、在最后面加上,这里连接的linux的mysql,版本是5.7的

db.num=1
db.url.0=jdbc:mysql://192.168.2.108:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false
db.user=root
db.password=123456

2、使用SQLyog连接上linux的mysql,执行sql脚本创建11个表和数据库。

当时创建的数据库多加了空格,真是看了好久看不出来。。。绝望


生产环境配置

1个nginx+3个nacos注册中心+1个mysql

linux上配置nacos集群

为什么要做nacos的集群呢?确保高可用。

这一块很乱,因为这一块我必须吐槽老师的笔记,相当的糟糕。可能总共要15步,笔记只写出来5步,还是上下不接的那种。太他吗糟心了

我还是跟着老师的视频以及老师的帮助下搭建完了。步骤实在太多,记住不啊,说个大概吧

1、下载nacos的linux版本,并使用xftp5拖到创建好的目录下 /opt/tool/nacoscluster

2、解压缩后就是 nacos这个目录了。(并没有你看到的nacos8848,nacos8849,nacos8850)

开始一顿修改,(大概就是改了这些了,不记得那么清楚了)

1、nacos/conf/application.properties.

2、把nacos/conf/cluster.conf.example文件重命名为cluster.conf

 并修改里面的内容为

 3.修改 nacos/bin/.startup.sh,修改内存大小(在93行)

修改后的结果为,当然他喵在这里多加了个:,导致一致启动nacos出问题

再一顿复制,复制完再修改端口号

复制出来nacos8848,nacos8849,nacos8850 

nacoscluster/nacos8850/conf/application.properties中修改端口号

3、启动,查看这个日志文件看nacos有没有正常启动

cat /opt/tool/nacoscluster/nacos8848/logs/start.out

 接着把另外俩个也启动

4、 在浏览器登录任意节点查看集群

 


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

1、vim /usr/local/nginx/conf/nginx.conf

upstream nacoscluster{ 
    server 192.168.137.150:8848;
    server 192.168.137.150:8849;
    server 192.168.137.150:8850;
}

server{               
    listen 1111;
    server_name 192.168.137.150;
    location / {
         proxy_pass http://nacoscluster;                        
    }

2、启动nginx

截止到此处,1个Nginx+3个nacos注册中心+1个mysql


测试

1、在可视化控制台public下新建一个配置

2、 修改配置文件,注意服务的注册中心地址和配置中心地址都改为了nginx的地址

 3、浏览器访问

真牛逼啊

本文含有隐藏内容,请 开通VIP 后查看