spring cloud -1

本文介绍了SpringCloudAlibaba,一个集成多种功能的微服务解决方案,涵盖了服务治理、注册发现、限流降级、配置管理、API网关、分布式事务等内容,以及在实际项目中的应用和优势。

1.简介

Spring Cloud是Spring旗下的项目之一,官网地址:Spring Cloud/ Spring最擅长的就是集成,把世界上最好的框架拿过来,集成到自己的项目中。

Spring Cloud也是一样,它将现在非常流行的一些技术整合到一起,实现了诸如:配置管理,服务发现,智能路由, 负载均衡,熔断器,控制总线,集群状态等功能;协调分布式环境中各个系统,为各类服务提供模板性配置。其主要 涉及的组件包括:

核心组件

Cloud                               alibaba

注册中心:eureka            nacos

路由:zuul                          gateway

断路器:hystrix                       sentinel

配置中心:config                      nacos

负载均衡:Ribbon                    loadbalancer

调用:feign                           openfeign

分布式事务:                          seata(@GlobalTransactional)

1.1微服务 架构常见的问题

一旦采用微服务系统架构,就势必会遇到这样几个问题:

  • 这么多小服务,如何管理他们?(服务治理 注册中心[服务注册 发现 剔除])
  • 这么多小服务,他们之间如何通讯?(restful rpc)
  • 这么多小服务,客户端怎么访问他们?(网关 GateWay)
  • 这么多小服务,一旦出现问题了,应该如何自处理?(容错)

A-->B-->C--D---E sentinel

  • 这么多小服务,一旦出现问题了,应该如何排错? (链路追踪)

sluth

对于上面的问题,是任何一个微服务设计者都不能绕过去的,因此大部分的微服务产品都针对每一 个问题提供了相应的组件来解决它们

1.2微服务机构的常见概念

服务治理

服务治理就是进行服务的自动化管理,其核心是服务的自动注册与发现。

服务注册:服务实例将自身服务信息注册到注册中心。

服务发现:服务实例通过注册中心,获取到注册到其中的服务实例的信息,通过这些信息去请求它们提 供的服务

服务剔除:服务注册中心将出问题的服务自动剔除到可用列表之外,使其不会被调用到

服务调用

RestTemplate

服务网关

随着微服务的不断增多,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个 服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信可能出现:

  • 客户端需要调用不同的url地址,增加难度
  • 在一定的场景下,存在跨域请求的问题
  • 每个微服务都需要进行单独的身份认证

针对这些问题,API网关顺势而生。 API网关直面意思是将所有API调用统一接入到API网关层,由网关层统一接入和输出。一个网关的 基本功能有:统一接入、安全防护、协议适配、流量管控、长短链接支持、容错能力。有了网关之后, 各个API服务提供团队可以专注于自己的的业务逻辑处理,而API网关更专注于安全、流量、路由等问 题

服务容错

在微服务当中,一个请求经常会涉及到调用几个服务,如果其中某个服务不可用,没有做服务容错 的话,极有可能会造成一连串的服务不可用,这就是雪崩效应。 我们没法预防雪崩效应的发生,只能尽可能去做好容错。

服务容错的两个核心思想是:

  • 不被上游请求压垮
  • 不被下游响应拖垮

链路追踪

随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务。互联 网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程 语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。因此,就需要对一次请求涉及的 多个服务链路进行日志记录,性能监控即链路追踪

1.3主要功能 

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

服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。

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

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

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

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

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

1.4 spingCloud Alibaba 核心组件 

配置中心 nacos : springcloud config

服务治理中心nacos : Eurke

Nacos (配置中心与服务注册与发现)

Nacos实现了服务的配置中心与服务注册发现的功能,Nacos可以通过可视化的配置降低相关的学习与维护成本,实现动态的配置管理与分环境的配置中心控制。 同时Nacos提供了基于http/RCP的服务注册与发现功能。

Sentinel (分布式流控)

Sentinel是面向分布式微服务架构的轻量级高可用的流控组件,以流量作为切入点,从流量控制,熔断降级,系统负载保护等维度帮助用户保证服务的稳定性。常用与实现限流、熔断降级等策略。

RocketMQ (消息队列)/RabbitMq/kafka

RocketMQ基于Java的高性能、高吞吐量的消息队列,在SpringCloud Alibaba生态用于实现消息驱动的业务开发,常见的消息队列有Kafka、RocketMQ、RabbitMQ等,相关的比较文档可以自行去翻阅。

Seata (分布式事务)

既然是微服务的产品,那么肯定会用到分布式事物。Seata就是阿里巴巴开源的一个高性能分布式事物的解决方案。

Dubbo (RPC)

Dubbo已经在圈内很火了,SpringCloud Alibaba基于上面提到的Nacos服务注册中心也同样整合了Dubbo。

 1.5为什么使用 springCloud Alibaba

我认为 Spring Cloud Alibaba 的优势有以下几点:

阿里巴巴强大的技术输出能力

阿里巴巴无疑是国内开源技术领域的最有影响力的公司之一,已经有Dubbo、Druid,FastJson等成功的开源组件,

再加上阿里不遗余力的推广,社区发展也非常快。

集成Dubbo,利用Dubbo在微服务领域的超高人气

Dubbo是国内应用最广的分布式服务框架之一,基于Dubbo改造的Dubbox等也有很多公司在使用,

Spring Cloud Alibaba对Dubbo做了比较好的集成,可以吸引不少使用Dubbo的开发者。

云原生趋势,集成阿里云商业化组件

云原生(Cloud Native)是今年技术领域特别热门的一个词,云原生是一种专门针对云上应用而设计的方法,用于构建和部署应用,以充分发挥云计算的优势。

Spring Cloud Alibaba 集成了阿里云的商业化组件,可以说天然支持云原生特性。

2.实战

2.1微服务环境搭建

最新的版本对应关系可以参考网址:

版本说明 · alibaba/spring-cloud-alibaba Wiki · GitHub

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

版本对应关系:

版本一定要对应好

在微服务架构中,最常见的场景就是微服务之间的相互调用。我们以电商系统中常见的用户下单

例来演示微服务的调用:客户向订单微服务发起一个下单的请求,在进行保存订单之前需要调用商品微服务查询商品的信息。

我们一般把服务的主动调用方称为服务消费者,把服务的被调用方称为服务提供者

生产者 服务的被调用方

消费者 服务调用方

在这种场景下,订单微服务就是一个服务消费者, 商品微服务就是一个服务提供者。

2.2创建工程

技术栈:

基础框架:SpringBoot

持久层框架:MyBatisPlus

数据库:MySql

什么是父子工程

父子工程说白了就是利用Maven的继承,依赖传递性来为我们省略一些重复的配置,通常配置在父模块中,为子模块提供使用,这样可以做到一处声明,处处使用。

为什么需要继承制(父子工程)?

可能有的人该说了,我写个项目打成jar包让另一个项目引入,这样就可以达到依赖统一管理了呀,当然你可能忘了这一点,由于非 compile 范围的依赖信息是不能在“依赖链”中传递的,所以有需要的工程只能单独配置。

假如有三个子项目junit都使用的4.0版本,由于4.9版本出了一些新功能,我们想要让他们全升级到4.9,那么到各个工程中手动修改无疑是非常不可取的。使用继承机制就可以将这样的依赖信息统一提取到父工程模块中进行统一管理。

父子工程的创建

创建父工程

创建父工程和创建一般的 Java 工程操作一致,唯一需要注意的是:打包方式处要设置为 pom。

<relativePath/>设定一个空值默认值为../pom.xml 表示将始终从父级仓库中获取,不从本地路径获取

MAVEN构建jar包时候查找顺序:relativePath元素中的地址–本地仓库–远程仓库

1.pom文件

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.2</version>
    <relativePath/> <!-- lookup parent from repository -->
</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-cloud.version>2020.0.1</spring-cloud.version>
    <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
</properties>
<!--版本管理,不引入jar 包-->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <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>
    </dependencies>
</dependencyManagement>

dependencyManagement里只是声明依赖,并不实现引入,而dependencies相对于dependencyManagement,所有声明在dependencies里的依赖都会自动引入,并默认被所有的子项目继承。

如果dependencies里的dependency自己没有声明version元素,那么maven就

会到dependencyManagement里面去找有没有对该artifactId和groupId进行过版本声明,如果有,就继承它,如果

没有就会报错,告诉你必须为dependency声明一个version

如果dependencies中的dependency声明了version,那么无论dependencyManagement中有无对该jar的version声明,都以dependency里的version为准。

基础工程:

基础工程就是存放实体信息的工程

实体信息:Product:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {
    private int id;
    private String name;

    private Double price;
    private Integer kucun;
}

Result

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result<T> {

    /**
     * 编码
     */
    private Integer code = 200;
    /**
     * 信息
     */
    private String msg = "";
    /**
     * 数据
     */
    private T data;



    //

    // 静态方法
    public static <T>  Result success(T t){
        return new Result<T>(200,"操作成功",t);
    }

    // 静态方法
    public static <T>  Result fail(T t){
        return new Result<T>(500,"操作失败",t);
    }

    // 静态方法
    public static <T>  Result accessDefined(T t){
        return new Result<T>(403,"没有权限操作",t);
    }


}

Pom文件:

<dependency>
    <!--            引入 组合包  -->
    <groupId>com.example</groupId>
    <artifactId>sys-comm</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

生产者

@RestController
@RequestMapping("pro")
public class ProductController {

    //根据商品 id 查询商品信息返回
    @GetMapping("{id}")
    public Result getProById(@PathVariable Integer id){
        Product product = new Product();
        if(id==1){
           product= new Product(1,"test",80d,100);
        }else {
           product= new Product(id,"test",80d,100);
        }
        return Result.success(product);
    }


}

订单

@RestController
@RequestMapping("order")
public class OrderController {
    @Resource
    private RestTemplate restTemplate;

    //根据 商品id  查询商品的信息
    @GetMapping("{pid}")
    public Result order(@PathVariable Integer pid){
        //1.根据商品 的id 查询商品的价格  库存
        Result forObject = restTemplate.getForObject("http://localhost:8084/pro/" + pid, Result.class);

        Object data = forObject.getData();//==product
            //product  对象时候 转换
        ObjectMapper objectMapper= new ObjectMapper();
        Product product = objectMapper.convertValue(data, Product.class);
      


        //2.pid  price  存订单
        return Result.success(product);
    }


}
//启动类
@SpringBootApplication

public class OrderAPPlication {
    public static void main(String[] args) {
        SpringApplication.run(OrderAPPlication.class);
    }
    //RestTemplate  集成
    @Bean
    public RestTemplate getRestTemplate(){

        return  new RestTemplate();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值