一、概念

1.1系统架构的演变

1.1.1 单体项目

Web应用程序发展的早期,大部分web工程(包含前端页面,web层代码,service层代码,dao层代码)是将所有的功能模块,打包到一起并放在一个web容器中运行。


SpringCloud 调用其他module的api springcloud模块间调用_spring

优点:

所有的功能集成在一个项目工程中

项目架构简单,前期开发成本低,周期短,小型项目的首选。

缺点:

全部功能集成在一个工程中,对于大型项目不易开发、扩展及维护。

系统性能扩展只能通过扩展集群结点,成本高、有瓶颈。

技术栈受限。

1.1.2垂直拆分

当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率

从功能结构来拆,谁访问的多谁加集群

缺点:垂直拆分,独立项目之间不能互相调用,比如要用一些公共的功能,只能每个都写一份。


SpringCloud 调用其他module的api springcloud模块间调用_Cloud_02

优点 :

项目架构简单,前期开发成本低,周期短,小型项目的首选。

通过垂直拆分,原来的单体项目不至于无限扩大

不同的项目可采用不同的技术。

缺点 :

对于大型项目不易开发、扩展及维护。

系统间相互独立,重复开发工作(独立项目之间不能互相调用,比如要用一些公共的功能,只能每个都写一份)。

1.1.3 分布式服务

当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式调用是关键。

不同独立的项目,之间可以互相调用


SpringCloud 调用其他module的api springcloud模块间调用_Cloud_03

优点:

将基础服务进行了抽取,系统间相互调用,提高了代码的复用和开发的效率

缺点:

系统间的耦合度提高,关系复杂,难以维护

1.1.4 分布式SOA架构

SOA 全称为 Service-Oriented Architecture ,即面向服务的架构。它可以根据需求通过网络对松散耦合的粗粒度应用组件(服务)进行分布式部署、组合和使用。一个服务通常以独立的形式存在于操作系统进程中。

站在功能的角度,把业务逻辑抽象成可复用、可组装的服务,通过服务的编排实现业务的快速再生,目的:把原先固有的业务功能转变为通用的业务服务,实现业务逻辑的快速复用。

Dubbo

阿里框架,后来停止更新,当当网继续更新DubboX

后来阿里又继续维护了,把它挂到阿帕奇官网了

SpringCloud 调用其他module的api springcloud模块间调用_微服务_04

优点 :

抽取公共的功能为服务,提高开发效率

对不同的服务进行集群化部署解决系统压力

基于ESB/DUBBO减少系统耦合

缺点 :

抽取服务的粒度较大

服务提供方与调用方接口耦合度较高

tips:现在springboot也支持整合Dubbo了

SpringCloud 调用其他module的api springcloud模块间调用_微服务_05

1.1.5 微服务架构

SpringCloud 调用其他module的api springcloud模块间调用_微服务_06

优点 :

通过服务的原子化拆分,以及微服务的独立打包、部署和升级,小团队的交付周期将缩短,运维成本也将大幅度下降

微服务遵循单一原则。微服务之间采用Restful等轻量协议传输。

缺点 :

微服务过多,服务治理成本高,不利于系统维护。

分布式系统开发的技术成本高(容错、分布式事务等)。

1.2 SOA和微服务的关系和区别

SOA (Service Oriented Architecture )“面向服务的架构”:他是一种设计方法,其中包含多个服务, 服务之间通过相互依赖最终提供一系列的功能。一个服务 通常以独立的形式存在与操作系统进程 中。各个服务之间通过网络调用。

微服务架构:其实和 SOA 架构类似,微服务是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需 要彻底的组件化和服务化” ,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。

功能 SOA (Dubbo) 微服务(SpringCloud)

组件大小 大块业务逻辑 单独任务或小块业务逻辑

耦合 通常松耦合 总是松耦合

公司架构 任何类型 小型、专注于功能交叉团队

管理 着重中央管理 着重分散管理

目标 确保应用能够交互操作 执行新功能、快速拓展开发团队

1.3分布式中的远程调用

在微服务架构中,通常存在多个服务之间的远程调用的需求。远程调用通常包含两个部分:序列化和通 信协议。常见的序列化协议包括json 、xml、hession、protobuf、thrift、text、bytes等,目前主流的 远程调用技术有基于HTTP的RESTful接口以及基于TCP的RPC协议。

REST ,即Representational State Transfer的缩写,如果一个架构符合REST原则,就称它为RESTful架构。

RPC (Remote Procedure Call ) 一种进程间通信方式。允许像调用本地服务一样调用远程服务。RPC

框架的主要目标就是让远程服务调用更简单、透明。RPC框架负责屏蔽底层的传输方式(TCP或者 UDP )、序列化方式(XML/JSON/二进制)和通信细节。开发人员在使用的时候只需要了解谁在什么位置提供了什么样的远程服务接口即可,并不需要关心底层通信细节和调用过程。

RESTful

RPC

通讯协议

HTTP

一般使用TCP

性能

略低

较高

灵活度



应用

微服务架构

SOA架构

http是tcp上层的东西,更灵活效率变慢,参考mybatis和jdbc

1.4 分布式中的CAP原理

现如今,对于多数大型互联网应用,分布式系统(distributed system )正变得越来越重要。分布式系统的最大难点,就是各个节点的状态如何同步。CAP 定理是这方面的基本定理,也是理解分布式系统的起点。

CAP理论由 Eric Brewer在ACM研讨会上提出,而后CAP被奉为分布式领域的重要理论。分布式系统的 CAP理论,首先把分布式系统中的三个特性进行了如下归纳:

Consistency (一致性):数据一致更新,所有数据的变化都是同步的

Availability (可用性):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求

Partition tolerance (分区容忍性):某个节点的故障,并不影响整个系统的运行

通过学习CAP理论,我们得知任何分布式系统只可同时满足二点,没法三者兼顾,既然一个分布式系统无法同时满足一致性、可用性、分区容错性三个特点,所以我们就需要抛弃一样, 在一个分布式系统当中,分区容忍性是必须满足的。

CA 放弃分区容错性,加强一致性和可用性,其实就是传统的关系型数据库的选择

AP 放弃一致性(这里说的一致性是强一致性),追求分区容错性和可用性,这是很多分布式系统设计时的选择,例如很多NoSQL系统就是如此

CP放弃可用性,追求一致性和分区容错性,基本不会选择,网络问题会直接让整个系统不可用

1.5 SpringCloud概述

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基 础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉 了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发具 包。

Spring Cloud的本质是在 Spring Boot 的基础上,增加了一堆微服务相关的规范,并对应用上下文 (Application Context )进行了功能增强。既然 Spring Cloud 是规范,那么就需要去实现,目前Spring Cloud 规范已有 Spring官方,Spring Cloud Netflix ,Spring Cloud Alibaba等实现。通过组件化的方式,Spring Cloud将这些实现整合到一起构成全家桶式的微服务技术栈。

Spring Cloud Netflix组件 (Netflix公司)----我们主要讲这一套:停止更新

组件名称 作用

Eureka 服务注册中心

Ribbon 客户端负载均衡

Feign/OpenFeign 声明式服务调用

Hystrix 客户端容错保护

Zuul API服务网关

Spring Cloud Alibaba组件 (图形界面)

组件名称 作用

Nacos 服务注册中心

Sentinel (断路器) 客户端容错保护

Spring Cloud原生及其他组件

组件 作用

Consul 服务注册中心

Config 分布式配置中心

Gateway API服务网关

Sleuth/Zipkin 分布式链路追踪

携程 Appolo 注册中心

二、搭建

SpringCloud版本

SpringCloud采用了英国伦敦地铁站的名称来命名,并由地铁站名称字母A -Z依次类推的形式来发布迭代版本。

Springcloud和Springboot之间的依赖关系如何看

https://start.spring.io/actuator/info

SpringCloud Hoxton.SR1

SpringBoot 2.2.2.RELEASE

注意:springcloud和springboot的版本号要对应

SpringCloud 调用其他module的api springcloud模块间调用_Cloud_07

2.0 父项目

控制依赖版本

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <mysql.version>5.1.35</mysql.version>
        <mybatis.spring.boot.verison>2.1.0</mybatis.spring.boot.verison>
        <druid.spring.boot.starter.version>1.1.10</druid.spring.boot.starter.version>
        <spring.boot.version>2.2.2.RELEASE</spring.boot.version>
        <spring.cloud.version>Hoxton.SR1</spring.cloud.version>
    </properties>

    <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>
            <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>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.spring.boot.starter.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.verison}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2.1 创建公共项目

公共调用的一些实体类,方法等

SpringCloud 调用其他module的api springcloud模块间调用_微服务_08

添加实体加序列化

SpringCloud 调用其他module的api springcloud模块间调用_微服务_09

2.2 基础服务—dao层模块—8081

SpringCloud 调用其他module的api springcloud模块间调用_Cloud_10

SpringCloud 调用其他module的api springcloud模块间调用_spring cloud_11

2.3 业务功能—调用dao层模块的模块–7071

依赖中添加8081

SpringCloud 调用其他module的api springcloud模块间调用_Cloud_12

定义微服务的名字

SpringCloud 调用其他module的api springcloud模块间调用_Cloud_13

RestTemplate:项目之间调用就靠它

SpringCloud 调用其他module的api springcloud模块间调用_spring_14

调用8081的项目

SpringCloud 调用其他module的api springcloud模块间调用_微服务_15

restful风格增删改查

SpringCloud 调用其他module的api springcloud模块间调用_spring_16

7071给8081的添加数据会丢失

SpringCloud 调用其他module的api springcloud模块间调用_spring_17

原因:请求格式不对,restful模块之间的请求都是json串,接收不了

解决方法:在8081加个注解,这样8081就能正常将json串转换成对象了

SpringCloud 调用其他module的api springcloud模块间调用_spring cloud_18

此时7071ok,但8081有会出问题,415类型不对

原因:加了@RequestBody后,8081不能识别普通的post请求了,只能接收标准的json串

SpringCloud 调用其他module的api springcloud模块间调用_spring cloud_19

解决方法:这时要给8081传标准的json串,@RequestBody就是把标准的json串转成对象

SpringCloud 调用其他module的api springcloud模块间调用_Cloud_20

  1. @RequestBody,也可以给同步用,但必须是post请求,且只能用String来接收
  2. SpringCloud 调用其他module的api springcloud模块间调用_spring_21

  3. 异步必须指定类型是json串,配合@RequestBody转成对象;注意必须用SpringCloud 调用其他module的api springcloud模块间调用_Cloud_22.post,因为不能指定contentType为json;json串必须都用双引号引起来

SpringCloud 调用其他module的api springcloud模块间调用_微服务_23

分页

SpringCloud 调用其他module的api springcloud模块间调用_Cloud_24