一文搞定SpringCloud Alibaba全部知识点! 1

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
传统型负载均衡 CLB,每月750个小时 15LCU
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介: 一文搞定SpringCloud Alibaba全部知识点!

1.分布式架构简介

1.1.分布式架构

SOA:Service Oriented Architecture 面向服务的架构,其中包含多个功能,服务之间通过相互依赖最终提供一些列的功能,一个功能,一个服务,各个服务之间通过网络调用。
微服务:将⼀个⼤的单体应⽤进⾏细粒度的服务化拆分,每个拆分出来的服务各⾃独⽴打包部署,各个服务之间 通过⽹络调⽤。

优点:

  • 易开发、理解和维护
  • 独立的部署和启动

缺点:

  • 分布式系统->分布式事务
  • 需要管理多个服务->服务治理

1.2.常见的微服务架构解决方案

  • ServiceComb
  • 华为内部的CSE框架,一个微服务的开源解决方案,文档不多,通信领域比较强。
  • dubbo
  • zookeeper+

SpringCloud

  • 全家桶+轻松嵌⼊第三⽅组件(Netflix 奈⻜)
  • 官⽹:https://spring.io/projects/spring-cloud
  • 通信⽅式:http restful
  • 注册中⼼:eruka
  • 配置中⼼:config
  • 断路器:hystrix
  • ⽹关:zuul/gateway
  • 分布式追踪系统:sleuth+zipkin

Spring Cloud Alibaba

  • 全家桶+阿⾥⽣态多个组件组合+SpringCloud⽀持
  • 官⽹ https://spring.io/projects/spring-cloud-alibaba
  • 通信⽅式:http restful
  • 注册中⼼:nacos
  • 配置中⼼:nacos
  • 断路器:sentinel
  • ⽹关:gateway
  • 分布式追踪系统:sleuth+zipkin

1.3.分布式系统核心组件图


d2e47c4b80b64737912d9b6c9c8c10c2.jpg

2.AlibabaCloud架构环境准备

2.1.创建maven聚合项目

(1)版本说明

3e8fcfca130243cab2f56a8b39eab81c.jpg

(2)创建父工程项目ali-cloud,删除src目录

 <!-- 一般来说父级项目的packaging都为pom,packaging默认类型jar类型-->
    <packaging>pom</packaging>
    <properties>
        <!--JDK版本,如果是jdk8则这里是 1.8-->
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <spring.boot.version>2.3.3.RELEASE</spring.boot.version>
        <spring.cloud.version>Hoxton.SR8</spring.cloud.version>
        <alibaba.cloud.version>2.2.1.RELEASE</alibaba.cloud.version>
        <mybatisplus.boot.starter.version>3.4.0</mybatisplus.boot.starter.version>
        <lombok.version>1.18.16</lombok.version>
        <commons.lang3.version>3.9</commons.lang3.version>
        <commons.codec.version>1.15</commons.codec.version>
        <springfox.boot.starter.version>3.0.0</springfox.boot.starter.version>
        <docker.image.prefix>xdclass-cloud</docker.image.prefix>
        <!--跳过单元测试-->
        <skipTests>true</skipTests>
    </properties>
    <!--锁定版本-->
    <dependencyManagement>
        <dependencies>
            <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies/2.3.3.RELEASE-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies/Hoxton.SR8-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-alibaba-dependencies/2.2.1.RELEASE-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${alibaba.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--mybatis plus和springboot整合-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatisplus.boot.starter.version}</version>
            </dependency>
            <!--https://mvnrepository.com/artifact/org.projectlombok/lombok/1.18.16-->
            <!--scope=provided,说明它只在编译阶段生效,不需要打入包中, Lombok在编译期将带Lombok注解的Java文件正确编译为完整的Class文件-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <!--<scope>provided</scope>-->
            </dependency>
            <!--接口文档依赖-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-boot-starter</artifactId>
                <version>${springfox.boot.starter.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!-- 代码库 -->
    <repositories>
        <repository>
            <id>maven-ali</id>
            <url>http://maven.aliyun.com/nexus/content/groups/public//</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>always</updatePolicy>
                <checksumPolicy>fail</checksumPolicy>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
    <!--module不用添加打包版本信息-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring.boot.version}</version>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>

(3)父工程下创建常量类

<dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--项目中添加 spring-boot-starter-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--数据库连接-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--MybatisPlus驱动-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <!-- 代码自动生成依赖 begin 上线后不需要-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
            <!--<scope>provided</scope>-->
        </dependency>
        <!-- velocity -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
            <!--<scope>provided</scope>-->
        </dependency>
        <!-- 代码自动生成依赖 end-->
        <!--swagger ui接口文档依赖-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
    </dependencies>

(4)创建order-service、video-service、user-service

    <dependencies>
        <dependency>
            <groupId>net.xdclass</groupId>
            <artifactId>common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>


58d6796880f64d319e38470899dc8ce4.jpg

2.2.配置MyBatis

(1)分别在order-service、user-service、video-service的yml文件中加入mybatis配置

server:
  port: 8001 #(端口号)
spring:
  application:
    name: user-service #(服务名称)
  #数据库配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.10.88:3306/user?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai #(配置数据库地址)
    username: root
    password: 123456
#配置plus打印sql日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

(2)测试Mybatis

  • VideoServiceImpl
@Service
public class VideoServiceImpl implements VideoService {
    @Autowired
    private VideoMapper videoMapper;
    @Override
    public Video findById(int id) {
        return videoMapper.findById(id);
    }
}
  • VideoMapper
public interface VideoMapper {
    @Select("select * from video where id = #{id}")
    Video findById(int id);
}
  • VideoController
@RestController
@RequestMapping("/api/v1/video")
public class VideoController {
    @Autowired
    private VideoService videoService;
    @GetMapping("/find_video/{video_id}")
    public JsonData findVideo(@PathVariable("video_id") int id){
        System.out.println(id);
        Video video = videoService.findById(id);
        return JsonData.buildSuccess(video);
    }
}
  • 测试



2d505d7e0c06417c8863b10dd822919e.jpg

3.RestTemplate服务间调用

(1)订单微服务主类注入RestTemplate

@SpringBootApplication
@MapperScan("net.xdclass.mapper")
public class OrderApplication {
    public static void main(String[] args){
        SpringApplication.run(OrderApplication.class);
    }
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

(2)Controller中调用

@RestController
@RequestMapping("/api/v1/order")
public class OrderController {
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/save/{video_id}")
    public JsonData save(@PathVariable("video_id") int id){
        Video video = restTemplate.getForObject("http://localhost:7001/api/v1/video/find_video/" + id, Video.class);
        System.out.println("video:"+video);
        VideoOrder videoOrder = new VideoOrder();
        videoOrder.setCreateTime(new Date());
        videoOrder.setVideoImg(video.getCoverImg());
        videoOrder.setVideoImg(video.getCoverImg());
        videoOrder.setVideoTitle(video.getTitle());
        return JsonData.buildSuccess(videoOrder);
    }
}

3.Nacos服务治理

3.1.服务注册中心简介

(1)什么是注册中心

服务注册:服务提供者provider,启动的时候想注册中心上报自己的网络信息.
服务发现:服务消费者consumer,启动的时候想注册中心上报自己的网络信息,拉取provider的相关网络信息.
核心:服务管理,注册中心有个注册表,心跳机制动态维护,服务实例在启动时注册到服务表,关闭时注销.

(2)为什么要用

微服务应用和机器越来越多,调用方需要知道接口的网络地址,如果靠配置文件的方式去控制网络地址,对于动态新增机器,维护带来很大问题,主流的注册中心:zookeeper、Eureka、consul、etcd、Nacos。

(3)nacos的特性


a54d6f3cbed141288f55b0e1d109ca36.jpg

3.2.Nacos注册中心实战

(1)安装部署Nacos

#上传Nacos压缩包到服务器,解压
unzip nacos-server-1.3.2.zip
#配置jdk、maven环境,解压jdk、maven安装包
#jdk
JAVA_HOME=/usr/local/jdk8
export JAVA_HOME
CLASSPATH=.:$JAVA_HOME/lib
export CLASSPATH
PATH=$PATH:$JAVA_HOME/bin:$CLASSPATH
export PATH
#maven
MAVEN_HOME=/usr/local/maven
export MAVEN_HOME
PATH=$PATH:$MAVEN_HOME/bin
export PATH

(2)启动Nacos

cd /usr/local/nacos/bin
./startup.sh
#启动后会发现启动不成功,因为nacos默认是以集群方式启动的,要修改启动方式

7bef0cff8acb49bbbaa02d47ccfafa7b.jpg

#需修改配置文件
export MODE="standalone"

9181307644664b4890c0bd972df8fbb2.jpg

(3)开放防火墙端口,nacos默认端口8848,重启防火墙

firewall-cmd --add-port=8848/tcp --permanent
firewall-cmd --reload


ab546e2b12d046b5a0728ef564cd2435.jpg

(4)Nacos访问页面,默认账号密码为nacos




4bdadf8d1fa847938f0bc1def15de309.jpg

3.3.微服务配置Nacos

(1)yml文件中配置服务注册

spring:
  application:
    name: order-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.10.88:8848 #nacos地址

(2)主类配置@EnableDiscoveryClient注解

@EnableDiscoveryClient


f5b7c49f38e74e71a5ebd0f98fc8afc4.jpg

(3)验证服务注册

56543f6d5b54415fb111e4c2f4cb9a5a.jpg

3.5.微服务间服务调用案例

@RestController
@RequestMapping("/api/v1/order")
public class OrderController {
    @Autowired
    private DiscoveryClient discoveryClient;
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/save/{video_id}")
    public JsonData save(@PathVariable("video_id") int id){
//        Video video = restTemplate.getForObject("http://localhost:7001/api/v1/video/find_video/" + id, Video.class);
        //list获取服务的元数据信息,包括IP,端口,服务名称等等
        List<ServiceInstance> list = discoveryClient.getInstances("video-service");
        ServiceInstance serviceInstance = list.get(0);
        Video video = restTemplate.getForObject("http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+
                "/api/v1/video/find_video?id="+id,Video.class);
        System.out.println("video:"+video);
        VideoOrder videoOrder = new VideoOrder();
        videoOrder.setCreateTime(new Date());
        videoOrder.setVideoImg(video.getCoverImg());
        videoOrder.setVideoImg(video.getCoverImg());
        videoOrder.setVideoTitle(video.getTitle());
        return JsonData.buildSuccess(videoOrder);
    }

4.Ribbon负载均衡策略

4.1.什么是Ribbon

Ribbon是⼀个客户端负载均衡⼯具,通过Spring Cloud封装,可以轻松和AlibabaCloud整合。

订单微服务开启Ribbon,添加注解@LoadBalanced
@Bean
@LoadBalanced
public RestTemplate restTemplate() { return new RestTemplate();}

controller中要修改成服务名称调用,ribbon是根据服务名称调用的


23be1358d2344368a2c8523c8bc73c17.jpg

4.2.Ribbon源码分析

(1)大体流程

  • 首先请求通过注册中心获取provider的列表
  • 通过一定的策略选择一个节点
  • 在返回给RestTemplate进行调用

(2)Ribbon的作用主要在于第二步选择节点

  • 首先请求进来先进入注解


01a62abec8d64eb8a485a1910cde6123.jpg

  • 点进LoadBalancerClient接口

3300813c3eea4d20b5c07499fb1999a5.jpg

点进LoadBalancerClient的实现类RibbonLoadBalancerClient,只有这一个实现类


478b8ffb77c9454faaa71b232b766473.jpg

  • 主要看getServer方法是选择负载均衡策略的方法


2df63bb886824e989866c782515bc642.jpg


18f045a68f634aabad24e2fc89019e2d.jpg


648ed5d18bb243c3994fba00d270fbaf.jpg

  • loadBalancer默认传的是DynamicServerListLoadBalancer,但是DynamicServerListLoadBalancer没有chooseServer方法,所以掉用的是父类BaseLoadBalancer的。


54693e16e2bb404d93e16cf84559e930.jpg


edbbdb824ad3439486d0baefc4af1d1d.jpg

  • 默认BaseLoadBalancer定义的rule就是RoundRobinRule规则


2f3d54ef993f40d7af60749351d2d861.jpg

d28d7c4d3de24908986031cef2aa67c1.jpg

(3)RibbonLoadBalancerClient继承体系


57faedd9ff4e426fa16628f3f6e61f37.jpg

4.3.Ribbon负载均衡策略调整

(1)Ribbon支持的负载均衡策略

策略类 命名 描述
RandomRule 随机策略 随机选择Server
RoundRobinRule 轮询策略 按照顺序选择server(默认)
RetryRule 重试策略 当选择server不成功,短期内尝试选择一个可用的server
AvailabilityFilteringRule 可用过滤策略 过滤一直失败并被标记为circuit tripped的server,过滤掉那些高并发连接的server
WeightedResponseTimeRule 响应时间加权重策略 根据server的响应时间分配权重,以响应时间作为权重,响应时间越短的服务器被选中的概率越⼤,综合了各种因素,⽐如:⽹络,磁盘,io等,都直接影响响应时间
ZoneAvoidanceRule 区域权重策略 综合所在区域的性能,和server的可用性,轮询选择server

(2)配置yml

#使用随机负载均衡策略
video-service:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule


f60dc38cc01b4bff9293cf70bbb938ec.jpg

e2b3fc1d65fd4bee9412085739ea981f.jpg

(3)测试、分别启动三个VideoServer:9001、9006、9007


1597b04ece304454b55ab3246ffba4db.jpg


42f26e12bb59469489411de9f5300950.jpg

a50698136abe423d95f865f64b85530a.jpg


0031faae738c4fc1b8362897eb57c033.jpg

策略选择:

  • 如果每个机器配置一样,则建议不修改策略(推荐)
  • 如果部分机器配置强,则可以改为WeightedResponseTimeRule





相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
SpringCloudAlibaba API 开发者
新版-SpringCloud+SpringCloud Alibaba
新版-SpringCloud+SpringCloud Alibaba
|
1月前
|
JSON SpringCloudAlibaba Java
Springcloud Alibaba + jdk17+nacos 项目实践
本文基于 `Springcloud Alibaba + JDK17 + Nacos2.x` 介绍了一个微服务项目的搭建过程,包括项目依赖、配置文件、开发实践中的新特性(如文本块、NPE增强、模式匹配)以及常见的问题和解决方案。通过本文,读者可以了解如何高效地搭建和开发微服务项目,并解决一些常见的开发难题。项目代码已上传至 Gitee,欢迎交流学习。
125 1
Springcloud Alibaba + jdk17+nacos 项目实践
|
22天前
|
消息中间件 自然语言处理 Java
知识科普:Spring Cloud Alibaba基本介绍
知识科普:Spring Cloud Alibaba基本介绍
55 2
|
30天前
|
Dubbo Java 应用服务中间件
Dubbo学习圣经:从入门到精通 Dubbo3.0 + SpringCloud Alibaba 微服务基础框架
尼恩团队的15大技术圣经,旨在帮助开发者系统化、体系化地掌握核心技术,提升技术实力,从而在面试和工作中脱颖而出。本文介绍了如何使用Dubbo3.0与Spring Cloud Gateway进行整合,解决传统Dubbo架构缺乏HTTP入口的问题,实现高性能的微服务网关。
|
2月前
|
人工智能 前端开发 Java
Spring Cloud Alibaba AI,阿里AI这不得玩一下
🏀闪亮主角: 大家好,我是JavaDog程序狗。今天分享Spring Cloud Alibaba AI,基于Spring AI并提供阿里云通义大模型的Java AI应用。本狗用SpringBoot+uniapp+uview2对接Spring Cloud Alibaba AI,带你打造聊天小AI。 📘故事背景: 🎁获取源码: 关注公众号“JavaDog程序狗”,发送“alibaba-ai”即可获取源码。 🎯主要目标:
83 0
|
3月前
|
人工智能 前端开发 Java
【实操】Spring Cloud Alibaba AI,阿里AI这不得玩一下(含前后端源码)
本文介绍了如何使用 **Spring Cloud Alibaba AI** 构建基于 Spring Boot 和 uni-app 的聊天机器人应用。主要内容包括:Spring Cloud Alibaba AI 的概念与功能,使用前的准备工作(如 JDK 17+、Spring Boot 3.0+ 及通义 API-KEY),详细实操步骤(涵盖前后端开发工具、组件选择、功能分析及关键代码示例)。最终展示了如何成功实现具备基本聊天功能的 AI 应用,帮助读者快速搭建智能聊天系统并探索更多高级功能。
1331 2
【实操】Spring Cloud Alibaba AI,阿里AI这不得玩一下(含前后端源码)
|
1月前
|
负载均衡 Java API
【Spring Cloud生态】Spring Cloud Gateway基本配置
【Spring Cloud生态】Spring Cloud Gateway基本配置
37 0
|
3月前
|
Java Spring
【Azure Spring Cloud】Spring Cloud Azure 4.0 调用Key Vault遇见认证错误 AADSTS90002: Tenant not found.
【Azure Spring Cloud】Spring Cloud Azure 4.0 调用Key Vault遇见认证错误 AADSTS90002: Tenant not found.
|
3月前
|
Java Spring 容器
【Azure Spring Cloud】在Azure Spring Apps上看见 App Memory Usage 和 jvm.menory.use 的指标的疑问及OOM
【Azure Spring Cloud】在Azure Spring Apps上看见 App Memory Usage 和 jvm.menory.use 的指标的疑问及OOM
|
3月前
|
存储 Java Spring
【Azure Spring Cloud】Azure Spring Cloud服务,如何获取应用程序日志文件呢?
【Azure Spring Cloud】Azure Spring Cloud服务,如何获取应用程序日志文件呢?