分布式架构设计及理论指导

news2024/11/18 1:50:07

目录

  • 核心概念
    • 分布式
    • 分布式SOA架构
    • 微服务架构
    • 微服务技术对比
  • 服务拆分
    • 拆分思想和原则
    • 创建父类工程
    • 创建子工程
  • 远程调用方式
    • 引入RestTemplate
  • CAP/BASE理论
    • CAP理论
      • 分区容错 (Partition-tolerance)
      • 一致性(Consistency)
      • 可用性(Availability)
    • BASE理论
      • 基本可用
      • 软状态
      • 最终一致性

核心概念

分布式

分布式主要有三个方向分别是分布式计算、分布式存储、分布式系统(应用)
这里我们就重点说一下分布式系统:
分布式系统一定是由多个节点组成的系统。其中,节点指的是计算机服务器,而且这些节点一般不是孤立的,而是互通的。不同的业务模块部署在不同的服务器上或者同一个业务模块分拆多个子业务,部署在不同的服务器上,解决高并发的问题,提供可扩展性以及高可用性,业务中使用分布式的场景主要有分布式存储以及分布式计算。分布式存储中可以将数据分片到多个节点上,不仅可以提高性能(可扩展性),同时也可以使用多个节点对同一份数据进行备份。

分布式环境的特点:

  • 分布性:服务部署空间具有多样性。
  • 并发性:程序运行过程中,并发性操作是很常见的。比如同一个分布式系统中的多个节点,同时访问一个共享资源。数据库、分布式存储。
  • 无序性:进程之间的消息通信,会出现顺序不一致问题。

分布式环境下面临的问题:

  • 网络通信:网络本身的不可靠性,因此会涉及到一些网络通信问题
  • 网络分区(脑裂):当网络发生异常导致分布式系统中部分节点之间的网络延时不断增大,最终导致组成分布式架构的所有节点,只有部分节点能够正常通信
  • 三态:在分布式架构里面多了个状态::成功、失败、超时
  • 分布式事务:ACID(原子性、一致性、隔离性、持久性)
  • 冷备或者热备:冷备份是对数据库进行脱机备份,在备份过程中用户无法访问数据库,但冷备份速度更快更安全。热备份也称为动态备份或在线备份,这种技术可以在系统正常运行时进行备份,但是效率较慢。

分布式SOA架构

SOA(Service-OrientedArchitecture),即面向服务的系统架构,是一个组件模型。
SOA架构主要有三种实体: service provider (服务提供者)、 service requestor (服务使用者)和 service register (服务注册中心)。这三种实体又有三种服务处理功能:Publish(发布)、Find(查找)与 Bind(捆绑)。
在这里插入图片描述

微服务架构

微服务(microservice)是一种软件开发技术是面向服务的体系结构(SOA)架构样式的一种变体,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP的
RESTful API)。每个服务都围绕着具体业务进行构建,并且能够独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据上下文,选择合适的语言、工具对其进行构建。

微服务技术对比

微服务这种方案需要技术框架来落地,全球的互联网公司都在积极尝试自己的微服务落地技术。在国内知名度最高的就是SpringCloud和阿里巴巴的Dubbo。

  • 服务集群: 主要解决高并发的,每一个服务都可能会搭建集群,每一个集群都可能有若干服务器,解决并发问题之余还是提高服务的容错率。
  • 注册中心: 主要微服务管理工作。
  • 配置中心: 为了保证大家更新系统性的配置的时候不用每一个服务器都更改。
  • 服务网关: 请求拦截以及负载均衡。

微服务技术对比:
在这里插入图片描述

服务拆分

拆分思想和原则

  1. 单一职责:不同微服务,不要重复开发相同业务(业务拆分)
  2. 数据独立:不要访问其它微服务的数据库
  3. 面向服务:将自己的业务暴露为接口,供其它微服务调用

在这里插入图片描述

创建父类工程

在微服务中,我们们最多可能存在十几甚至几十个项目,如果我们每一个项目都开一个独立的idea,那么从视觉角度来看就非常不舒服,那么我们可以通过父子工程的方式去进行管理,管理工具就是我们常用的maven这样我们就可以实现maven项目的聚合。但在实际的开发中,可能就是项目独立的。·
在这里插入图片描述
以为这个项目需要做为父类工程使用,这样我们才能把项目聚合在一起,这个项目创建完成之后的src目录就没有用了,我们实际的业务会在各个子项目中去编写业务。所以这里我们可以直接删除。
在这里插入图片描述

因为这个项目我们是父工程, 将来这个项目下面会有很多子工程,所以我们需要将当前工程打包方式改为pom。

<groupId>com.its</groupId>
<artifactId>01-cloud-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 父工程需要指定打包方式为pom -->
<packaging>pom</packaging>

接下来我们还要在父工程中完成版本的管理,pom文件如下:

  • SpringBoot父启动器
  • 统一管理jar包版本
  • 实际导入的依赖
  • maven插件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <packaging>pom</packaging>
    <modules>
        <module>user-service</module>
        <module>order-service</module>
        <module>cloud_demo_comms</module>
        <module>eureka-demo</module>
        <module>cloud_feignApi</module>
    </modules>

    <groupId>org.example</groupId>
    <artifactId>cloud_demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 1 SpringBoot的默认默认引用的父类 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <!-- 文件拷贝时的编码 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <!-- 编译时的编码 -->
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <!--        java-->
        <java.version>1.8</java.version>
        <!--        spring.cloud-->
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
        <!-- MyBatis-plus系列 -->
        <mybatis-plus.version>3.5.3.1</mybatis-plus.version>
        <mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version>
        <velocity-engine-core>2.2</velocity-engine-core>
        <!--数据库驱动版本-->
        <mysql.version>8.0.16</mysql.version>
        <!--工具包-->
        <hutool.version>5.7.10</hutool.version>
        <!--分页工具-->
        <pagehelper.version>1.3.0</pagehelper.version>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <!-- 2引入声明的依赖(引入但并不使用) 提前引入的目的是子项目再次使用可以不是书写版本号 -->
    <dependencyManagement>
        <dependencies>
            <!-- SpringCloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <!--Maven 父子项目结构和 Java 继承一样,都是单继承,一个子项目只能制定一个父pom。
                很多时候,我们需要打破这种 单继承,就使用type+import -->
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- mybatis-plus -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <!-- 代码生成工具 -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-generator</artifactId>
                <version>${mybatis-plus-generator.version}</version>
            </dependency>
            <!-- 代码生成模板 -->
            <dependency>
                <groupId>org.apache.velocity</groupId>
                <artifactId>velocity-engine-core</artifactId>
                <version>${velocity-engine-core}</version>
            </dependency>
            <!-- mysql数据连接驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!--3 直接继承的依赖,所以子项目默认继承 -->
    <dependencies>
        <!-- 单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

</project>

到此父类工程我们创建完成!

创建子工程

在这里插入图片描述

远程调用方式

引入RestTemplate

将restTemplate的实例注册到IOC容器中:

@SpringBootApplication
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class);
    }
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

在order的业务层我们拿到注册的restTemplate并查询用户:

@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private OrderService orderService;
    @Autowired
    private RestTemplate restTemplate;
    /**
     * 根基ID查询
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public Order byId(@PathVariable("id") Long id) {
         Order order = orderService.getById(id);
         User user = restTemplate.getForObject("http://localhost:8080/user/" + order.getUserId(), User.class);
         order.setUser(user);
        return order;
    }

输出结果:

{
"id": 101,
"userId": 1,
"name": "Apple 苹果 iPhone 12 ",
"price": 699900,
"num": 1,
"user": {
"id": 1,
"username": "武松",
"address": "湖南省衡阳市"
}
}

到此我们完成了两个项目之间的调用。

CAP/BASE理论

CAP理论

分区容错 (Partition-tolerance)

大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partition)。分区容错的意思是,区间通信可能失败。比如,一台服务器放在中国,另一台服务器放在美国,这就是两个区,它们之间可能无法通信.
在这里插入图片描述
上图中,G1 和 G2 是两台跨区的服务器。G1 向 G2 发送一条消息,G2 可能无法收到。系统设计的时候,必须考虑到这种情况。
一般来说,分区容错无法避免,因此可以认为 CAP 的 P 总是成立。CAP 定理告诉我们,剩下的 C 和 A无法同时做到。

一致性(Consistency)

Consistency 中文叫做”一致性”。意思是,写操作之后的读操作,必须返回该值。举例来说,某条记录是v0,用户向 G1 发起一个写操作,将其改为 v1。
在这里插入图片描述
接下来,用户的读操作就会得到 v1。这就叫一致性。
在这里插入图片描述
问题是,用户有可能向 G2 发起读操作,由于 G2 的值没有发生变化,因此返回的是 v0。G1 和 G2 读操作的结果不一致,这就不满足一致性了。
在这里插入图片描述
为了让 G2 也能变为 v1,就要在 G1 写操作的时候,让 G1 向 G2 发送一条消息,要求 G2 也改成v1。
在这里插入图片描述
这样的话,用户向 G2 发起读操作,也能得到 v1。

可用性(Availability)

Availability 中文叫做”可用性”,意思是只要收到用户的请求,服务器就必须给出回应。
用户可以选择向 G1 或 G2 发起读操作。不管是哪台服务器,只要收到请求,就必须告诉用户,到底是v0 还是 v1,否则就不满足可用性。
Consistency 和 Availability 的矛盾
一致性和可用性,为什么不可能同时成立?答案很简单,因为可能通信失败(即出现分区容错)。
如果保证 G2 的一致性,那么 G1 必须在写操作时,锁定 G2 的读操作和写操作。只有数据同步后,才能重新开放读写。锁定期间,G2 不能读写,没有可用性不。
如果保证 G2 的可用性,那么势必不能锁定 G2,所以一致性不成立。
综上所述,G2 无法同时做到一致性和可用性。系统设计时只能选择一个目标。如果追求一致性,那么无法保证所有节点的可用性;如果追求所有节点的可用性,那就没法做到一致性。

BASE理论

基本可用

基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性—-注意,这绝不等价于系统不可用。比如:
(1)响应时间上的损失。正常情况下,一个在线搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障,查询结果的响应时间增加了1~2秒
(2)系统功能上的损失:正常情况下,在一个电子商务网站上进行购物的时候,消费者几乎能够顺利完成每一笔订单,但是在一些节日大促购物高峰的时候,由于消费者的购物行为激增,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面

软状态

软状态指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时

最终一致性

最终一致性强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/548404.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】继承/虚拟继承/菱形虚拟继承

继承 继承的概念继承体系中对象赋值转换继承方式对继承后的访问限定&#xff08;重定义-同名隐藏&#xff09;继承体系中派生类的默认成员函数友元函数、静态成员在继承中的特点菱形继承和菱形虚拟继承 继承的概念 为了让代码可以复用&#xff0c;当前类可以继承其他类的成员变…

阿里云OSS存储空间绑定自定义域名,浏览器通过自定义域名预览文件

阿里云官方文档&#xff1a; 如何绑定自定义域名_对象存储-阿里云帮助中心 华东1&#xff08;杭州&#xff09;地域创建了名为monkey的存储空间 Bucket&#xff1a;monkey Endpoint&#xff1a;oss-cn-hangzhou.aliyuncs.com 上传文件默认域名的url: https://monkey.oss-cn-han…

微信小程序nodejs+vue课程推荐报名学习分享平台uniapp

本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c; 整个开发过程首先对课程分享平台进行需求分析&#xff0c;得出课程分享平台主要功能。接着对课程分享平台 进行总体设计和详细设计。总体设计主要包括小程序功能设计、小程序总体结构设计、小程序…

Python数据可视化小结

1. 引言 原始形式的数据对大多数人来说可能都是枯燥乏味的&#xff0c;但是如果掌握正确的可视化工具&#xff0c;给人的印象就会变得引人入胜。本文通过实际例子&#xff0c;让我们利用数据可视化工具来探索不一样的数据体验。 闲话少说&#xff0c;我们直接开始吧&#xff…

推荐3款超好用的海报设计软件!

在现代社会&#xff0c;海报设计已经成为了一种非常重要的视觉传达方式。如果你需要制作一个引人注目的海报&#xff0c;但却没有设计师的技能和经验&#xff0c;那么在线海报设计图片软件就是你的最佳选择。下面我们将介绍 5 款最受欢迎的在线海报设计图片软件&#xff0c;它们…

qt中使用QGIS实现二次开发导入shp格式地图(MSVC2019_64bit+qt5.15+qgis)

在qt开发过程中可能要导入自定义格式的图层地图&#xff0c;那么可以把这些数据导入qgis然后导出为shp格式文件&#xff0c;然后下载qgis源码&#xff0c;在qt项目中配置环境变量导入qgis有关的头文件&#xff0c;然后再引入shp数据格式的地图。 qgis处理数据 QGIS安装 QGIS…

oracle数据库当中用户的创建,添加,授权,以及表的创建与表的简单介绍,以及在oracle数据库当中的约束以及约束条件的简单介绍

系列文章目录 (3条消息) oracle数据库简介 文章目录 系列文章目录 前言 一、用户的创建 1.1、创建命令 1.2、给予scott用户权限 1.3、以scott用户进行连接登录 二、表和表的设计原则 2.1、表的概念 2.1.1、表是从属于用户的 2.1.2、表是逻辑表(概念表)&#xff0c;不…

[比赛简介]Predict Student Performance from Game Play

比赛链接&#xff1a;https://www.kaggle.com/competitions/predict-student-performance-from-game-play/overview 比赛简介 本次比赛的目标是实时预测学生在基于游戏的学习中的表现。您将开发一个在最大的游戏日志开放数据集之一上训练的模型。 您的工作将有助于推进对基于…

Next.js ---未完待续....

Next.js 1.介绍2.体会服务器端渲染2.1为什么这就服务器端渲染了&#xff1f; 3.如何判断是否是服务器端渲染&#xff1f;--- 响应头信息4.文件名路由5.如何启动项目*另外1.Next.js 是基于 Webpack 的框架&#xff1f;1.1所以无需手动编译 TypeScript 代码 1.介绍 Next.js 是一…

【C++】C++泛型编程 | 模板初阶

&#x1f9d1;‍&#x1f393;个人主页&#xff1a;简 料 &#x1f3c6;所属专栏&#xff1a;C &#x1f3c6;个人社区&#xff1a;越努力越幸运社区 &#x1f3c6;简 介&#xff1a;简料简料&#xff0c;简单有料~在校大学生一枚&#xff0c;专注C/C/GO的干货分…

LT8711UXE1,Type-C/DP1.2 转 HDMI2.0,内置HDCP,支持4k 60Hz向下兼容

1. 描述 LT8711UXE1 是一款高性能 Type-C/DP1.2 至 HDMI2.0 转换器&#xff0c;设计用于将 USB Type-C 源或 DP1.2 源连接到 HDMI2.0 接收器。LT8711UXE1 集成了一个符合 DP1.2 标准的接收器和一个符合 HDMI2.0 标准的发射器。此外&#xff0c;还包括两个用于 CC 通信的 CC 控…

研发/IT工程师双视角测评8大仿真平台,结果……

上一篇&#xff0c;我们围绕着亿万研发工程师的梦想&#xff0c;考察了市面上几乎所有类型的工业仿真平台&#xff0c;深度评测了他们本质究竟是什么&#xff0c;适用场景有哪些&#xff0c;分别能给研发和IT工程师们减轻多少工作量。 据此&#xff0c;我们搭建了一个工业仿真…

C++/PTA 神坛

C/PTA 神坛 题目要求解题前提及思路凹包算法概念步骤 解题思路 代码tan(y/x)及tan2(y,x)函数 总结 题目要求 在古老的迈瑞城&#xff0c;巍然屹立着 n 块神石。长老们商议&#xff0c;选取 3 块神石围成一个神坛。因为神坛的能量强度与它的面积成反比&#xff0c;因此神坛的面…

记录:自回归 模型在记忆 全随机序列 的潜变量 统计量爆炸现象

只是一个记录 8层12头512维度的 GPT 模型&#xff0c;使用它来记忆 10000 条 512长度 的无序序列&#xff0c;vocab_size 为100。 模型要自回归生成这些序列&#xff0c;不可能依赖局部推理&#xff0c;必须依赖全局视野&#xff0c;即记住前面的序列。 然后统计 最后一个no…

HF宣布在transformers库中引入首个RNN模型:RWKV,一个结合了RNN与Transformer双重优点的模型

RWKV是一个结合了RNN与Transformer双重优点的模型架构。由香港大学物理系毕业的彭博首次提出。简单来说&#xff0c;RWKV是一个RNN架构的模型&#xff0c;但是可以像transformer一样高效训练。今天&#xff0c;HuggingFace官方宣布在transformers库中首次引入RNN这样的模型&…

QGC局域网内连接PX4模拟器JMAVSim

环境 QGroundControl 开源地面站系统; 代码地址: https://github.com/mavlink/qgroundcontrolPX4 开源飞控系统; 代码地址: https://github.com/PX4/PX4-Autopilot QGC可以直接下载运行包. PX4 请根据代码中的说明,进行环境的配置和运行. 通过代码去build地面站和PX4的步骤见官…

【Linux 之五】 Linux中使用fdisk命令实现磁盘分区

最近由于工作的需要&#xff0c;初步研究了uboot中的fastboot实现方式。研究fastboot不可避免的需要了解磁盘分区的相关知识点&#xff0c;在linux下可以使用fdisk命令实现磁盘的分区。好了&#xff0c;下面步入正题。 1. 查看帮助信息&#xff08;fdisk --help&#xff09; …

计算机网络 - 传输层

Transport-Layer Services Transport layer, 传输层主要是完成进程(proces)到进程(process)之间的通讯的. 在传输层之下的IP协议, 提供的是best-effort的传输, 也就是对信息的正确性没有保证, 也就是IP的协议是unreliable的, TCP的协议是在IP协议至少提供可靠的数据传输. UDP…

Word批量更改图片环绕方式与=尺寸大小

前提&#xff1a;一份Word文档里面有100张图片&#xff0c;有大有小&#xff0c;需要将100张图片更改为统一大小&#xff0c;宽度与高度均为5厘米&#xff0c;同时环绕方式也需要改成四周型。 默认Word图片的默认环绕方式为嵌入型&#xff0c;需要统一更改为四周型&#xff0c;…