微服务简单理解与快速搭建

news2024/11/27 0:31:48

分布式和微服务

含义

微服务架构

微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并且可通过全自动部署机制独立部署。这些服务共用一个最小型的集中式的管理,服务可用不同的语言开发,使用不同的数据存储技术。

分布式架构

分布式系统是若干独立计算机的集合,这些计算机对用户来说就像单个相关系统,即整个系统是由不同的计算机组成,而用户是无感知的,就像访问一台计算机一样。这里强调的是系统由不同物理上分离的计算机(服务器)组成。

概念

微服务架构

微服务是设计层面的东西,一般考虑如何将系统从逻辑上进行拆分,也就是垂直拆分。微服务可以是分布式的,即可以将不同服务部署在不同计算机上,当然如果量小也可以部署在单机上。

分布式架构

分布式是部署层面的东西,即强调物理层面的组成,即系统的各子系统部署在不同计算机上。

解决的问题

微服务架构

微服务解决的是系统复杂度问题: 一般来说是业务问题,即在一个系统中承担职责太多了,需要打散,便于理解和维护,进而提升系统的开发效率和运行效率,微服务一般来说是针对应用层面的。

分布式架构

分布式解决的是系统性能问题: 即解决系统部署上单点的问题,尽量让组成系统的子系统分散在不同的机器上进而提高系统的吞吐能力(每秒能处理多少请求)。

部署

微服务架构

微服务的应用可以部署在是同一个服务器,不一定是分散在多个服务器上。微服务架构是一项在云中部署应用和服务的新技术。微服务架构是一种架构模式,它将一个复杂的大型应用程序划分成多个微服务,这些小型服务都在各自独立的进程中运行。

分布式架构

分布式是将一个大的系统划分为多个业务模块,这些业务模块会分别部署到不同的机器上,通过接口进行数据交互。

耦合度

微服务架构

微服务相比分布式服务来说,它的粒度更小,服务之间耦合度更低,由于每个微服务都由独立的小团队负责,因此它敏捷性更高。

分布式架构

分布式服务最后都会向微服务架构演化,这是一种趋势,不过服务微服务化后带来的挑战也是显而易见的,例如服务粒度小,数量大,后期运维将会很难。


问:分布式是否属于微服务?

答案是属于。微服务的意思也就是将模块拆分成一个独立的服务单元通过接口来实现数据的交互。但是微服务不一定是分布式,因为微服务的应用不一定是分散在多个服务器上,他也可以是同一个服务器。这也是分布式和微服务的一个细微差别。

CAP

CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)

可用性(A):保证每个请求不管成功或者失败都有响应。

分区容忍性(P):系统中任意信息的丢失或失败不会影响系统的继续运作。

组件

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

Eureka:注册中心

Zuul、Gateway:服务网关/路由

Ribbon: 负 载 均 衡

Feign:服务调用

Hystrix或Resilience4j:熔断器

微服务环境搭建

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

版本说明 · 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

版本对应关系

版本一定要对应好

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

生产者 服务的被调用方

消费者 服务调用方

创建工程

什么是父子工程

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

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

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

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

父子工程的创建

创建父工程

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo01</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>demo01</name>
    <description>demo01</description>
    <modules>
        <module>comm</module>
        <module>service</module>
    </modules>
    <properties>
        <!-- 声明变量  <java.version></>  取值:${java.version}-->
        <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>
    <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>
    <dependencies>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
创建对应子模块(与父模块)方式相同 

comm        放置实体类

service       放置消费者和生产者

comm
<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>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>demo01</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>comm</artifactId>
    <packaging>jar</packaging>

    <name>comm</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {

    private Integer id;
    private String name;
}
service
<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>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>demo01</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>service</artifactId>
    <packaging>pom</packaging>

    <name>service</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.example</groupId>
            <artifactId>comm</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

       
    </dependencies>
</project>
生产者和消费者

在service项目下新建两个springboot模块

order        消费者

product    生产者

消费者

application.properties

server.port=8081
spring.cloud.nacos.discovery.server-addr=192.168.253.16:8848
spring.application.name=order
feign.sentinel.enabled=true

启动类下新加 http的 Bean注入

@Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

controller

// 远程调用
    @Resource
    private RestTemplate restTemplate;

    @GetMapping("order/{pid}")
    public Object addOrder(@PathVariable Integer pid) {
        Product forObject = restTemplate.getForObject("http://localhost:8082/pro/" + pid, Product.class);
        return forObject;
    }

生产者

application.properties

server.port=8082
spring.cloud.nacos.discovery.server-addr=192.168.253.16:8848
spring.application.name=product

controller

@GetMapping("pro/{id}")
    public Product getProById(@PathVariable Integer id){
        return  new Product(id,"test"+id);

    }

xml把 parent 改为 service即可 

消费者生产者一样

    <parent>
        <groupId>com.example</groupId>
        <artifactId>service</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

请求 order/id 请求页面json数据为生产者数据,配置完成

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

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

相关文章

解密网络世界的秘密——Wireshark Mac/Win中文版网络抓包工具

在当今数字化时代&#xff0c;网络已经成为了人们生活和工作中不可或缺的一部分。然而&#xff0c;对于网络安全和性能的监控和分析却是一项重要而又复杂的任务。为了帮助用户更好地理解和解决网络中的问题&#xff0c;Wireshark作为一款强大的网络抓包工具&#xff0c;应运而生…

springboot+maven多环境动态配置,以及编译失败的解决方案

一、前言 在我们的项目开发过程中一般会有多套的环境&#xff0c;比如比较常见的会有三套&#xff1a; dev &#xff08;研发环境&#xff09;&#xff0c;test(测试环境)&#xff0c;prod&#xff08;生产环境&#xff09;。 application.yml 是主配置文件&#xff0c;当在不…

Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信您对这篇博客也感兴趣o (ˉ▽ˉ&#xff1b;) &#x1f4dc;redis和缓存及相关问题和解决办法 什么是缓存预热、缓存穿透、缓存雪崩、缓存击穿 目录 1、复习 MySQl 事务的特性 2、Redis 事务特性 2.1、原子…

Debug知识点解析!超实用教程

一、Debug简介 二、IDEA中的Debug步骤 2.1 步过调试按钮(F8) 2.2 步入调试按钮(F7) 2.3 强制步入调试按钮(Alt Shift EZ) 2.4 步出调试按钮(Shift F8) 2.5 回退断点 2.6 运行到光标处&#xff08;F9&#xff09; 2.7 计算表达式按钮(Alt F8) 三、条件断点 在断点处右…

Project IDX简介——这是一项改进全栈、多平台应用程序开发的试验

如今&#xff0c;将应用程序从零开发到生产环境&#xff08;尤其是在移动、网络和桌面平台上运行良好的应用程序&#xff09;感觉就像构建一台 Rube Goldberg 机器。您必须在无尽的复杂性海洋中航行&#xff0c;将各种技术堆栈粘合在一起&#xff0c;以引导、编译、测试、部署和…

基于逐次变分模态分解(SVMD)联合小波阈值去噪

代码原理 逐次变分模态分解 (Iterative Variational Mode Decomposition, IVMD) 是一种信号分解方法&#xff0c;它可以将一个时域信号分解为若干个本征模态函数&#xff08;Intrinsic Mode Functions, IMF&#xff09;。它通过迭代寻找信号的本征模态函数和残差部分&#xff…

Ladybug 全景相机, 360°球形成像,带来全方位的视觉体验

360无死角全景照片总能给人带来强烈的视觉震撼&#xff0c;有着大片的既视感。那怎么才能拍出360球形照片呢&#xff1f;它的拍摄原理是通过图片某个点位为中心将图片其他部位螺旋式、旋转式处理&#xff0c;从而达到沉浸式体验的效果。俗话说“工欲善其事&#xff0c;必先利其…

.net core中前端vue HTML5 History 刷新页面404问题

放到启动的应用程序的最后面 app.Run(async (context) > {context.Response.ContentType "text/html";await context.Response.SendFileAsync(Path.Combine(env.WebRootPath, "index.html")); });https://blog.csdn.net/lee576/article/details/88355…

强化学习:原理与Python实战||一分钟秒懂人工智能对齐

文章目录 1.什么是人工智能对齐2.为什么要研究人工智能对齐3.人工智能对齐的常见方法延伸阅读 1.什么是人工智能对齐 人工智能对齐&#xff08;AI Alignment&#xff09;指让人工智能的行为符合人的意图和价值观。 人工智能系统可能会出现“不对齐”&#xff08;misalign&…

647. 回文子串 516.最长回文子序列

647. 回文子串 题目&#xff1a; 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串&#xff0c;即使是由相…

ubuntu18.04配置Java环境与安装RCS库

一、安装包 安装包 二、JAVA环境 java无需安装&#xff0c;只需要下载解压&#xff0c;然后配置正确的路径到环境变量种即可使用。 1.创建文件JAVA mkdir JAVA 2.将安装包复制到该文件夹下&#xff0c;并解压缩 tar -zxvf tar -zxvf jdk1.8.0_191.tar.gz 3.在home路径下…

ubuntu小技巧30--23.10桌面版安装钉钉启动报错undefined symbol: FT_Get_Color_Glyph_Layer

ubuntu小技巧30-- 23.10桌面版安装钉钉启动报错undefined symbol: FT_Get_Color_Glyph_Layer 介绍解決方法说明 介绍 近期在电脑上安装了 ubuntu 23.10桌面版本, 安装最新版钉钉后无法正常打开软件&#xff0c;报错 undefined symbol: FT_Get_Color_Glyph_Layer &#xff0c;具…

sqlyog安装和网址

网址Downloads webyog/sqlyog-community Wiki GitHub 1. 2. 3. 4. 5. 6. 7.

手写一个starter

文章目录 starter命令规则项目演示新建工程Pom引入依赖定义属性配置定义自动配置类配置EnableAutoConfiguration业务实现项目中使用 什么是Starter&#xff1f;Starter其实就是我们经常在maven中的导入的各种模块&#xff0c;自定义Starter可以快速的满足开发的需求&#xff0c…

SOME/IP学习笔记3

目录 1.SOMEIP Transformer 1.1 SOME/IP on-wire format 1.2 协议指定 2. SOMEIP TP 2.1 SOME/IP TP Header 3.小结 1.SOMEIP Transformer 根据autosar CP 相关规范&#xff0c;SOME/IP Transformer主要用于将SOME/IP格式的数据序列化&#xff0c;相当于一个转换器。总体…

1、NPC 三电平SVPWM simulink仿真

1、SVPWM时间计算函数&#xff0c;是从matlab的SVPWM3L_TimingCalculation.p文件中反汇编出来的函数&#xff1a; function [TgABC_On ,TgABC_Off ,Sn ]SVPWM3L_TimingCalculation_frompfile (Vref ,DeltaVdc ,Fsw ) %#codegen %coder .allowpcode (plain ); TgABC_On [0 ,0 ,…

超级 App 的前端框架也可以足够轻量

小程序技术自微信2016年提出并大力推动&#xff0c;如今已经成为了中国前端研发的“潮流”&#xff0c;或者说是“趋势”。早期&#xff0c;微信小程序是微信公众平台推出的一种应用形态。微信小程序开放平台允许开发者在微信内直接开发和发布应用&#xff0c;用户无需下载安装…

使用Python轻松实现科研绘图

当撰写在学术期刊上发表的文章时&#xff0c;图表的布局和风格应符合预定义的格式要求。这样可以确保该出版物的所有文章都具有一致的风格&#xff0c;并且任何包含的图表在打印时都是高质量的。 Python在科学界广泛使用&#xff0c;并提供了创建科学绘图的好方法。然而&#…

如何正确使用 JavaScript 中的 slice() 方法

在 JavaScript 中&#xff0c;slice() 是一个常用的数组方法&#xff0c;用于从现有数组中提取一部分元素&#xff0c;然后返回一个新的数组。它是一个非常有用的工具&#xff0c;可以帮助你在不改变原始数组的情况下操作数组的子集。本文将介绍 slice() 的基本概念、使用方法、…

云课五分钟-02第一个代码复现-终端甜甜圈C++

前篇 云课五分钟-01课程在哪里-无需安装网页直达- 代码复现通过云课&#xff0c;会非常快捷。 视频 云课五分钟-02第一个代码复现-终端甜甜圈C 文本 如何使用g 使用g编译和链接C程序的基本步骤如下&#xff1a; 编写源代码&#xff1a;首先&#xff0c;你需要编写C源代码&…