SpringCloud学习(二)

发布时间 2023-06-18 21:14:54作者: kd最棒

参考:

https://blog.csdn.net/qq_25928447/article/details/123899694?spm=1001.2014.3001.5502

前面了解了微服务的一套解决方案,但是它是基于Netflix的解决方案,实际上的很多框架都已经停止维护了

  • 注册中心:Eureka(属于Netflix,2.x版本不再开源,1.x版本仍在更新)

  • 服务调用:Ribbon(属于Netflix,停止更新,已经彻底被移除)、SpringCloud *Loadbalancer(属于SpringCloud官方,目前的默认方案)

  • 服务降级:Hystrix(属于Netflix,停止更新,已经彻底被移除)

  • 路由网关:Zuul(属于Netflix,停止更新,已经彻底被移除)、Gateway(属于SpringCloud官方,推荐方案)

  • 配置中心:Config(属于SpringCloud官方)

超过半数的组件都已经处于不可用状态,并且部分组件都是SpringCloud官方出手提供框架进行解决.

阿里巴巴作为业界的互联网大厂,给出了一套全新的解决方案,官方网站(中文):

https://spring-cloud-alibaba-group.github.io/github-pages/2021/zh-cn/index.html

目前 Spring Cloud Alibaba 提供了如下功能:

  1. 服务限流降级:支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Dubbo 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。

  2. 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。

  3. 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。

  4. Rpc服务:扩展 Spring Cloud 客户端 RestTemplate 和 OpenFeign,支持调用 Dubbo RPC 服务

  5. 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。

  6. 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。

  7. 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。

  8. 分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。

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

可以看到,SpringCloudAlibaba实际上是对SpringCloud组件增强功能,是SpringCloud的增强框架,可以兼容SpringCloud原生组件和SpringCloudAlibaba的组件。

还是从注册中心入手

Nacos 更加全能的注册中心

Nacos(Naming Configuration Service)是一款阿里巴巴开源的服务注册与发现+配置管理的组件,相当于是Eureka+Config的组合形态。

安装与部署

Nacos服务器是独立安装部署的,因此我们需要下载最新的Nacos服务端程序,下载地址:

https://github.com/alibaba/nacos

下载安装Nacos

  • 直接下载zip文件,接着将文件进行解压.

  • 将解压后的文件放入到项目文件夹中

设置单节点启动

每个环境介绍一种方式

windows环境下:

image

Linux和Mac环境下:

可以在程序文件下使用命令:
bash startup.sh -m standalone

访问管理页面

http://localhost:8848/nacos/index.html (默认端口是8848)

用户和密码都是 nacos

image

服务注册与发现

导入依赖

父工程依赖
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>
      
      	<!-- 这里引入最新的SpringCloud依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2021.0.1</version>
          	<type>pom</type>
            <scope>import</scope>
        </dependency>

     	  <!-- 这里引入最新的SpringCloudAlibaba依赖,2021.0.1.0版本支持SpringBoot2.6.X -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2021.0.1.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
子工程依赖
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

编写配置文件

需要在子工程配置文件中配置Nacos注册中心的地址

server:
  port: 8101
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cloudstudy
    username: test
    password: 123456
  # 应用名称 bookservice
  application:
    name: bookservice
  cloud:
    nacos:
      discovery:
        # 配置Nacos注册中心地址
        server-addr: localhost:8848
  • 配置完成后,启动各服务就可以在Nacos管理页面 服务列表中找到

image

服务调用

  • 使用OpenFeign,实现服务发现远程调用以及负载均衡
导入依赖

需要调用服务的子项目中导入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 这里需要单独导入LoadBalancer依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

之后的调用服务的操作和笔记(一)中使用OpenFeign一样....

设置临时与非临时实例

临时和非临时的区别:

  • 临时实例:和Eureka一样,采用心跳机制向Nacos发送请求保持在线状态,一旦心跳停止,代表实例下线,不保留实例信息

  • 非临时实例(默认为临时实例):由Nacos主动进行联系,如果连接失败,那么不会移除实例信息,而是将健康状态设定为false,相当于会对某个实例状态持续地进行监控

修改服务的配置文件

spring:
  application:
    name: borrowservice
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        # 将ephemeral修改为false,表示非临时实例
        ephemeral: false

当把服务关闭时

  • 非临时实例

image

关闭后

image

  • 临时实例

会直接消失,不会再页面中显示

集群分区

介绍:
在一个分布式应用中,相同服务的实例可能会在不同的机器、位置上启动,比如:用户管理服务,可能在成都有1台服务器部署、重庆有一台服务器部署,而这时,在成都的服务器上启动了借阅服务,那么如果借阅服务现在要调用用户服务,就应该优先选择同一个区域的用户服务进行调用,这样会使得响应速度更快。

image

修改配置文件

spring:
  application:
    name: borrowservice
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        # 修改为重庆地区的集群
        cluster-name: Chongqing
	# 将loadbalancer的nacos支持开启,集成Nacos负载均衡
    loadbalancer:
      nacos:
        enabled: true #开启负债均衡才能开启区域优先
  • 当本区域没有没有可用服务,会调用其他近的服务器

修改权重

  • 除了根据区域优先调用之外,同一个区域内的实例也可以单独设置权重,Nacos会优先选择权重更大的实例进行调用

  • 通过配置权重,某些性能不太好的机器就能够更少地被使用,而更多的使用那些网络良好性能更高的主机上的实例。

有两种方法修改权重

  1. 配置文件
spring:
  application:
    name: borrowservice
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        cluster-name: Chengdu
        # 权重大小,越大越优先调用,默认为1
        weight: 0.5
  1. 直接在管理页面中进行配置

image

配置中心

Nacos 也支持像 SpringCloud Config 一样在bootstrap.yml中配置远程配置文件来获取在远端的配置文件.

  1. 在Nacos中创建配置文件

image

Data ID的格式跟SpringCloud Config 一样,应用名称-环境.yml,如果只编写应用名称,那么代表此配置文件无论在什么环境下都会使用,然后每个配置文件都可以进行分组,也算是一种分类方式

  1. 编写完配置文件发布即可

image

  1. 在项目中导入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  1. 添加bootstrap.yml文件
spring:
  application:
  	# 服务名称和配置文件保持一致
    name: borrowservice
  profiles:
  	# 环境也是和配置文件保持一致
    active: dev
  cloud:
    nacos:
      config:
      	# 配置文件后缀名
        file-extension: yml
        # 配置中心服务器地址,也就是Nacos地址
        server-addr: localhost:8848

配置文件的热更新

Nacos还支持配置文件的热更新,比如我们在配置文件中添加了一个属性,而这个时候可能需要实时修改,并在后端实时更新

例如:

  1. 写入test属性值

image

  1. 添加@RefreshScope注解
@RestController
@RefreshScope   //添加此注解就能实现自动刷新了
public class TestController {

    @Value("${test.txt}")//获取test的txt属性值
    String txt;

    @RequestMapping("/test")
    public String test(){
        return txt;
    }
}

命名空间

Nacos 同样支持命名空间:

就是将配置文件或是服务实例划分到不同的命名空间中,其实就是区分开发、生产环境或是引用归属之类的

image

  • 命名空间ID可用不用写,会自动生成

image

image

实现高可用(搭建集群)

官方文档:

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

image

  • http://ip1:port/openAPI 直连ip模式,机器挂则需要修改ip才可以使用。

  • http://SLB:port/openAPI 挂载SLB模式(内网SLB,不可暴露到公网,以免带来安全风险),直连SLB即可,下面挂server真实ip,可读性不好。

  • http://nacos.com:port/openAPI 域名 + SLB模式(内网SLB,不可暴露到公网,以免带来安全风险),可读性好,而且换ip方便,推荐模式

参考原文:

我们来看看它的架构设计,它推荐我们在所有的Nacos服务端之前建立一个负载均衡,我们通过访问负载均衡服务器来间接访问到各个Nacos服务器。实际上就,是比如有三个Nacos服务器做集群,但是每个服务不可能把每个Nacos都去访问一次进行注册,实际上只需要在任意一台Nacos服务器上注册即可,Nacos服务器之间会自动同步信息,但是如果我们随便指定一台Nacos服务器进行注册,如果这台Nacos服务器挂了,但是其他Nacos服务器没挂,这样就没办法完成注册了,但是实际上整个集群还是可用的状态。

所以这里就需要在所有Nacos服务器之前搭建一个SLB(服务器负载均衡),这样就可以避免上面的问题了。但是我们知道,如果要实现外界对服务访问的负载均衡,我们就得用比如之前说到的Gateway来实现,而这里实际上我们可以用一个更加方便的工具:Nginx,来实现(之前我们没讲过,但是使用起来很简单,放心后面会带着大家使用)

关于SLB最上方还有一个DNS(我们在计算机网络这门课程中学习过),这个是因为SLB是裸IP,如果SLB服务器修改了地址,那么所有微服务注册的地址也得改,所以这里是通过加域名,通过域名来访问,让DNS去解析真实IP,这样就算改变IP,只需要修改域名解析记录即可,域名地址是不会变化的。

因为学习这里就用第二种举例.

创建并配置数据库

在单节点的情况下,Nacos实际上是将数据存放在自带的一个嵌入式数据库中.

在多节点集群模式下,肯定是不能各存各的,所以,Nacos提供了MySQL统一存储支持,只需要让所有的Nacos服务器连接MySQL进行数据存储即可,官方也提供好了SQL文件。

image

导入数据库

nacos-mysql.sql 直接导入到数据库

image

创建nacos集群服务器

  • 在linux中创建两个Nacos服务器(需要 jdk8 以上的版本)
  1. 将之前下载的Nacos压缩包上传到linux,然后解压缩

  2. 修改 conf/ 中的application.properties 文件

### Default web server port:
server.port=8801

#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql

### Count of DB:
db.num=1

### Connect URL of DB:
db.url.0=jdbc:mysql://cloudstudy.mysql.cn-chengdu.rds.aliyuncs.com:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=nacos
db.password.0=nacos
  1. 修改集群配置,需要重命名一下文件名

mv cluster.conf.example cluster.conf

  1. 修改 cluster.conf

ip地址为内网 ip

image

  1. 修改一下Nacos的内存分配以及前台启动,直接修改startup.sh文件

image

  1. 将nacos复制一份,并将端口修改为8802,接着启动这两个Nacos服务器

添加SLB

  • 这里用Nginx做反向代理(需要安装Nginx)

Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。它相当于在内网与外网之间形成一个网关,所有的请求都可以由Nginx服务器转交给内网的其他服务器。

修改Nginx配置文件
#添加刚刚创建好的两个nacos服务器
upstream nacos-server {
        server 10.0.0.12:8801;
        server 10.0.0.12:8802;
}

server {
        listen   80; #监听的端口
        server_name  1.14.121.107;

        location /nacos {
                proxy_pass http://nacos-server;
        }
}
重启Nginx,访问页面

image

修改服务Nacos地址

将服务Nacos地址都修改为nginx配置文件中的 server_name+listen:

例如: 1.14.121.107:80

Sentinel 流量防卫兵

微服务存在的雪崩问题,也就是说一个微服务出现问题,有可能导致整个链路直接不可用,这种时候就需要进行及时的熔断和降级,这些策略,之前通过使用Hystrix来实现。

SpringCloud Alibaba也有自己的微服务容错组件,但是它相比Hystrix更加的强大。

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。

  • 完备的实时监控:Sentinel 同时提供实时的监控功能。可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。

  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。

  • 完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

安装与部署

Sentinel 与 Nacos 一样,说独立安装部署的

下载地址:

https://github.com/alibaba/Sentinel/releases

直接下载jar包

image

在项目中创建一个文件夹,直接将jar包放入文件夹

image

添加运行配置

  • Sentinel默认端口为 8080

image

启动之后,就可以访问到Sentinel的监控页面了

用户名和密码都是sentinel,地址:http://localhost:8858/#/dashboard

服务连接控制台

导入依赖

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

编写配置文件

spring:
  application:
    name: userservice
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
      	# 添加监控页面地址即可
        dashboard: localhost:8858

刚开始,监控页面还没有服务显示(懒加载机制),需要访问一次服务

image

监控的内容非常的多,包括时间点QPS(每秒查询率)响应时间等数据。

流量控制