微服务(一)
目录
一、概念
1、单体架构
2、微服务
3、springcloud
二、微服务的拆分
1、微服务的拆分原则
1.1 什么时候拆
1.2 怎么拆
2、服务调用
2.1 resttemplate
2.2 远程调用
一、概念
1、单体架构
单体架构(monolithic structure):顾名思义,整个项目中所有功能模块都在一个工程中开发;项目部署时需要对所有模块一起编译、打包;项目的架构设计、开发模式都非常简单。
当项目规模较小时,这种模式上手快,部署、运维也都很方便,因此早期很多小型项目都采用这种模式。
但随着项目的业务规模越来越大,团队开发人员也不断增加,单体架构就呈现出越来越多的问题:
-
团队协作成本高:试想一下,你们团队数十个人同时协作开发同一个项目,由于所有模块都在一个项目中,不同模块的代码之间物理边界越来越模糊。最终要把功能合并到一个分支,你绝对会陷入到解决冲突的泥潭之中。
-
系统发布效率低:任何模块变更都需要发布整个系统,而系统发布过程中需要多个模块之间制约较多,需要对比各种文件,任何一处出现问题都会导致发布失败,往往一次发布需要数十分钟甚至数小时。
-
系统可用性差:单体架构各个功能模块是作为一个服务部署,相互之间会互相影响,一些热点功能会耗尽系统资源,导致其它服务低可用。
2、微服务
微服务(Microservices)是一种软件架构风格,它将一个大型应用程序拆分为一组小型、独立的服务,每个服务运行在自己的进程中,并通过轻量级的通信机制(如HTTP/REST或消息队列)进行通信。每个服务通常专注于完成一个特定的业务功能,并且可以独立部署、扩展和维护。
微服务架构,首先是服务化,就是将单体架构中的功能模块从单体应用中拆分出来,独立部署为多个服务。同时要满足下面的一些特点:
-
单一职责:一个微服务负责一部分业务功能,并且其核心数据不依赖于其它模块。
-
团队自治:每个微服务都有自己独立的开发、测试、发布、运维人员,团队人员规模不超过10人(2张披萨能喂饱)
-
服务自治:每个微服务都独立打包部署,访问自己独立的数据库。并且要做好服务隔离,避免对其它服务产生影响
在微服务中可以将不同的模块交给不同的团队开发并且独立部署
那么,单体架构存在的问题有没有解决呢?
-
团队协作成本高?
-
由于服务拆分,每个服务代码量大大减少,参与开发的后台人员在1~3名,协作成本大大降低
-
-
系统发布效率低?
-
每个服务都是独立部署,当有某个服务有代码变更时,只需要打包部署该服务即可
-
-
系统可用性差?
-
每个服务独立部署,并且做好服务隔离,使用自己的服务器资源,不会影响到其它服务。
-
综上所述,微服务架构解决了单体架构存在的问题,特别适合大型互联网项目的开发,因此被各大互联网公司普遍采用。大家以前可能听说过分布式架构,分布式就是服务拆分的过程,其实微服务架构正式分布式架构的一种最佳实践的方案。
当然,微服务架构虽然能解决单体架构的各种问题,但在拆分的过程中,还会面临很多其它问题。比如:
-
如果出现跨服务的业务该如何处理?
-
页面请求到底该访问哪个服务?
-
如何实现各个服务之间的服务隔离?
3、springcloud
Spring Cloud 是一个基于 Spring Boot 的微服务框架,它提供了一系列工具和库,帮助开发者快速构建和部署微服务架构的应用程序。Spring Cloud 提供了许多常见的微服务模式和组件,如服务发现、配置管理、负载均衡、断路器、API 网关等。
微服务拆分以后碰到的各种问题都有对应的解决方案和微服务组件,而SpringCloud框架可以说是目前Java领域最全面的微服务组件的集合了。
而且SpringCloud依托于SpringBoot的自动装配能力,大大降低了其项目搭建、组件使用的成本。对于没有自研微服务组件能力的中小型企业,使用SpringCloud全家桶来实现微服务开发可以说是最合适的选择了!
目前SpringCloud最新版本为2022.0.x
版本,对应的SpringBoot版本为3.x
版本,但它们全部依赖于JDK17,目前在企业中使用相对较少。
SpringCloud版本 | SpringBoot版本 |
2022.0.x aka Kilburn | 3.0.x |
2021.0.x aka Jubilee | 2.6.x, 2.7.x (Starting with 2021.0.3) |
2020.0.x aka Ilford | 2.4.x, 2.5.x (Starting with 2020.0.3) |
Hoxton | 2.2.x, 2.3.x (Starting with SR5) |
Greenwich | 2.1.x |
Finchley | 2.0.x |
Edgware | 1.5.x |
Dalston | 1.5.x |
二、微服务的拆分
1、微服务的拆分原则
服务拆分一定要考虑几个问题:
-
什么时候拆?
-
如何拆?
1.1 什么时候拆
一般情况下,对于一个初创的项目,首先要做的是验证项目的可行性。因此这一阶段的首要任务是敏捷开发,快速产出生产可用的产品,投入市场做验证。为了达成这一目的,该阶段项目架构往往会比较简单,很多情况下会直接采用单体架构,这样开发成本比较低,可以快速产出结果,一旦发现项目不符合市场,损失较小。
如果这一阶段采用复杂的微服务架构,投入大量的人力和时间成本用于架构设计,最终发现产品不符合市场需求,等于全部做了无用功。
所以,对于大多数小型项目来说,一般是先采用单体架构,随着用户规模扩大、业务复杂后再逐渐拆分为微服务架构。这样初期成本会比较低,可以快速试错。但是,这么做的问题就在于后期做服务拆分时,可能会遇到很多代码耦合带来的问题,拆分比较困难(前易后难)。
而对于一些大型项目,在立项之初目的就很明确,为了长远考虑,在架构设计时就直接选择微服务架构。虽然前期投入较多,但后期就少了拆分服务的烦恼(前难后易)。
1.2 怎么拆
之前我们说过,微服务拆分时粒度要小,这其实是拆分的目标。具体可以从两个角度来分析:
-
高内聚:每个微服务的职责要尽量单一,包含的业务相互关联度高、完整度高。
-
低耦合:每个微服务的功能要相对独立,尽量减少对其它微服务的依赖,或者依赖接口的稳定性要强。
高内聚首先是单一职责,但不能说一个微服务就一个接口,而是要保证微服务内部业务的完整性为前提。目标是当我们要修改某个业务时,最好就只修改当前微服务,这样变更的成本更低。
一旦微服务做到了高内聚,那么服务之间的耦合度自然就降低了。
当然,微服务之间不可避免的会有或多或少的业务交互,比如下单时需要查询商品数据。这个时候我们不能在订单服务直接查询商品数据库,否则就导致了数据耦合。而应该由商品服务对应暴露接口,并且一定要保证微服务对外接口的稳定性(即:尽量保证接口外观不变)。虽然出现了服务间调用,但此时无论你如何在商品服务做内部修改,都不会影响到订单微服务,服务间的耦合度就降低了。
明确了拆分目标,接下来就是拆分方式了。我们在做服务拆分时一般有两种方式:
-
纵向拆分
-
横向拆分
所谓纵向拆分,就是按照项目的功能模块来拆分。例如商城项目中,就有用户管理功能、订单管理功能、购物车功能、商品管理功能、支付功能等。那么按照功能模块将他们拆分为一个个服务,就属于纵向拆分。这种拆分模式可以尽可能提高服务的内聚性。
而横向拆分,是看各个功能模块之间有没有公共的业务部分,如果有将其抽取出来作为通用服务。例如用户登录是需要发送消息通知,记录风控数据,下单时也要发送短信,记录风控数据。因此消息发送、风控数据记录就是通用的业务功能,因此可以将他们分别抽取为公共服务:消息中心服务、风控管理服务。这样可以提高业务的复用性,避免重复开发。同时通用业务一般接口稳定性较强,也不会使服务之间过分耦合。
然而当我们拆分完成到不同的模块之后我们又会遇到一个新的问题,那就是当拆分为不同的微服务之后我们如何跨服务调用其他服务的接口?
2、服务调用
当我们将前端的nginx启动之后你就会惊讶的发现为什么获取不了后端的数据了,明明拆分之前还好好的,这是因为将单体项目拆分成了不同的服务了,然而不同的服务之间是不能直接调用其它服务的三层架构中的功能的。如果想要调用该如何实现呢?首先要明白服务之间调用也是要用HTTP请求或者REST,那么我们如何发送HTTP请求到其他服务呢?
2.1 resttemplate
Spring给我们提供了一个RestTemplate的API,可以方便的实现Http请求的发送。其中提供了大量的方法,方便我们发送Http请求,例如:
可以看到常见的Get、Post、Put、Delete请求都支持,如果请求参数比较复杂,还可以使用exchange方法来构造请求。
在使用之前需要先将resttemplate注入到ioc容器中,做如下配置
package com.hmall.cart.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RemoteCallConfig {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}
2.2 远程调用
示例如下:
可以看到,利用RestTemplate发送http请求与前端ajax发送请求非常相似,都包含四部分信息:
-
请求方式
-
请求路径
-
请求参数
-
返回值类型
Java发送http请求可以使用Spring提供的RestTemplate,使用的基本步骤如下:
-
注册RestTemplate到Spring容器
-
调用RestTemplate的API发送请求,常见方法有:
-
getForObject:发送Get请求并返回指定类型对象
-
PostForObject:发送Post请求并返回指定类型对象
-
put:发送PUT请求
-
delete:发送Delete请求
-
exchange:发送任意类型请求,返回ResponseEntity
-
使用过之后我们会发现这种方法跨服务调用有很多的劣势,比如我们直接将url写死了,就不能灵活的调用其他的功能了、再者就是这种方法比较繁琐需要很多的参数。在下面我们会借助nacos服务注册中心实现服务之间的调用,这样实现会比较方便而且不会出现上述问题。
相关文章:

微服务(一)
目录 一、概念 1、单体架构 2、微服务 3、springcloud 二、微服务的拆分 1、微服务的拆分原则 1.1 什么时候拆 1.2 怎么拆 2、服务调用 2.1 resttemplate 2.2 远程调用 一、概念 1、单体架构 单体架构(monolithic structure):顾名…...

Uniapp时间戳转时间显示/时间格式
使用uview2 time 时间格式 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 <text class"cell-tit clamp1">{{item.create_time}} --- {{ $u.timeFormat(item.create_time, yyyy-mm-dd hh:MM:ss)}} </text>...

C++类和对象(中)【下篇】
🌟个人主页:落叶 🌟当前专栏: C专栏 目录 赋值运算符重载 运算符重载 赋值运算符重载 日期类实现 运算符重载<和运算符重载 运算符重载进行复用 运算符重载< 运算符重载> 运算符重载> 运算符重载! 获取某年某月的天数…...

【亿美软通-注册/登录安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...

数据分析学习之学习路线
前言 我们之前通过cda认证了解到数据分析行业,但是获取到证书,并不代表着,我们已经拥有的数据分析的能力,所以通过系统的学习数据分析需要掌握的能力,并学习大佬们的分析经验、分析思路,才是成为数据分析师…...

Oracle逻辑备份脚本【生产环境适用】
1 说明 从Oracle10g开始,引入了数据泵(Data Pump),是一种高效的数据传输工具,它通过导出(Export)和导入(Import)的方式帮助用户迁移数据。 在Oracle的产品设计中&#…...
Python范例总结
一、基础功能 1、操作符 and 拥有更高优先级,会先行运算。优先级顺序为 NOT、AND、OR。 2、列表 1)列表拼接 l1 [1,2,3] l2 [4,5,6]# 方法1 # l1 l1 l2# 方法2 # l1[len(l1):len(l1)] l2# 方法3 l1.extend(l2) print(l1) 3、函数 1)范…...

若依生成主子表
一、准备工作 确保你已经部署了若依框架,并且熟悉基本的开发环境配置。同时,理解数据库表结构对于生成代码至关重要。 主子表代码结构如下(字表中要有一个对应主表ID的字段作为外键,如下图的customer_id) -- ------…...

dotnet4.0编译问题
因为最近在写cobaltstrike的execute-assembly内存加载的c#项目 用visual studio2022编译,最低net只能用6.0版本的,并且execute-assembly不支持 我想使用4.x版本进行编译,因为visual studio不支持,那么使用命令行进行编译 因为要用…...

研一奖学金计划2024/9/23有感
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、需要认真上课的1.应用数理统计(开卷考试)2.最优化方法(开卷考试)3.跨文化交际(主题演讲20课堂讨…...
html知识点框架
一、HTML基础 HTML简介 HTML是一种超文本标记语言,用于创建网页和网页应用。HTML5是公认的下一代Web语言,极大地提升了Web在富媒体、富内容和富应用等方面的能力。HTML基本结构 基本的HTML文档结构包括<!DOCTYPE html>, <html>, <head&g…...

SpringBoot的应用
目录 一、springboot的应用 1、创建springboot项目 2、乱码问题配置 3、springboot日志配置 4、springboot整合mybatis 二、配置文件讲解及测试 1、全局配置文件参数读取 1.1 全局配置文件的位置 1.2 配置文件的读取 1.2.1 导包 1.2.2 编写配置对象Bean 1.2.3 编写配置文件 1.2…...

Spring源码学习:SpringMVC(3)mvcannotation-driven标签解析【RequestMappingHandlerMapping生成】
目录 前言mvc:annotation-driven标签概述mvc:annotation-driven标签解析【RequestMappingHandlerMapping生成】AnnotationDrivenBeanDefinitionParser#parse (解析入口)RequestMappingHandlerMapping的实例化类图afterPropertiesSetAbstractHandlerMetho…...

2024 Redis 全部
1. 单机部署 1.1 检查环境,创建目录。 # 本地运行,不需要考虑安装的原因,可以卸载防火墙 # 关闭防火墙 systemctl stop firewalld.service# 查看防火强状态 firewall-cmd --state# redis 是基于gcc 环境的,查看是否有 gcc 环境 …...
[SDX35+WCN6856]SDX35 + WCN6856 WiFi可以up起来之后无法扫描到SSID
SDX35 SDX35介绍 SDX35设备是一种多模调制解调器芯片,支持 4G/5G sub-6 技术。它是一个4nm芯片专为实现卓越的性能和能效而设计。它包括一个 1.9 GHz Cortex-A7 应用处理器。 SDX35主要特性 ■ 3GPP Rel. 17 with 5G Reduced Capability (RedCap) support. Backward compati…...

VisualStudio如何卸载Resharper插件?
本来按理说,卸载插件应该就是在扩展下的已安装插件中,找到该插件,点一下就会出现卸载的按钮的。 没想到这个Resharper这么吊,卸载按钮居然是个灰色的,意思就是此路不通,有特权的。 那么这种情况下&#x…...

Unity Debug时出现请选择unity实例
Unity Debug时出现请选择unity实例 问题描述 出现请选择unity实例,并且选择框里为空。 出现原因 你打开了两个Unity工程,在附加时,不知道加在哪个Unity工程上。 解决方法 在调试窗口中点击“附加Unity调试程序”,然后在弹出…...

国庆出行新宠:南卡Pro5骨传导耳机,让旅途不再孤单
国庆长假即将来临,对于热爱旅行和户外运动的朋友们来说,一款适合旅行使用的耳机无疑是提升旅途体验的神器。今天,我要向大家推荐一款特别适合国庆出行的耳机——南卡Runner Pro5骨传导耳机。作为一名热爱旅游的体验者,我强烈推荐南…...
2024.09.18 leetcode 每日一题
二进制求和 给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。 https://leetcode.cn/problems/add-binary/description/ 代码一,尝试使用笨办法,会造成溢出 class Solution { public:string addBinary(string a, string …...

快递物流短信API接口代码
官网:快递鸟 API参数 用户信息类 一.短信模版 1.接口说明 使用快递鸟短信功能时,预先设置好短信模板和对应的发送规则,快递鸟短信API将根据设置的好的模板和规则,进行短信的发送和反馈。 (1)仅支持Json格式。 (2)请求指令810…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...