微服务的定义
个人理解
其实微服务就是DDD + cloud native
DDD:
提供了微服务的理论基础,一个大型复杂的服务可以按照其对外提供的业务功能划分成相对独立的小服务。注意这个小是相对而言的,每一个小服务其实就是一个独立的子域(subdomain),它应该足够大以便能够提供一个完整的上下文以及囊括这个上下文的通用语言。这儿其实是设计微服务最容易出错的地方,
1, 避免业务领域的过度拆分。如果你设计了2个子服务,发现他们之间的关系非常复杂,比如商品和订单,这俩概念在业务上几乎总是成对出现的,把他们拆分只会破坏概念的完整性,形成一个分布式的单体系统,没有好处只有坏处。当你不确定是不是应该拆分服务的时候,说明你还没有足够的理由支撑你这么做,应该等到服务边界变得更加清晰之后再做决策。记住:模块化的单体服务并不需要太大的努力就可以改造成微服务,毕竟微服务只是把模块分开部署了而已。
2,避免按照技术或者使用的工具拆分出所谓的公共服务。之前在shopee有个例子,有好几个服务都需要对数据进行排序,于是就有人想做一个sorting service。其实排序功能非常简单,只是有的时候对数据的一致性要求很高,有时候对性能的要求又很高。解决方案都是靠数据库排序+redis排序。抽出一个单独的sortingService其实很不合理,因为sortingService不可能同时提供高性能(比如百万qps)和高一致性的保证,这违背了cap定律。同时系统里面多出来了一个依赖,sortingService成了单点瓶颈,有可能一个不重要的服务耗尽了sortingService的资源而导致更重要的服务请求失败。并且还有可能牵扯到权限和数据安全的问题。总之,这种不包含业务逻辑的功能不适合作为一个单独的服务来建立,而更适合做成一个common library,只有调用方才能决定性能和一致性之间的取舍,并且每个服务都有单独的资源(数据库+redis本身就广泛存在,不大可能会引入额外的依赖),不存在互相影响的弊端。
3,同一个服务也可以分开部署。考虑性能的特殊情况。比如一个图片服务,它能提供图片的上传修改功能和和查询功能。图片的上传需要大量的内存,修改需要大量的cpu,而查询是一个非常轻量级的操作。
上传:IO密集 (异步请求队列)
修改:IO + GPU 密集 (异步请求队列)
查询:qps大 (同步)
这种情况下,有个折中的方案。提供上传修改查询的代码明显是一个domain的,所以他们肯定是放在一个service一个代码仓库里面,但是在部署的时候,我们可以部署三类实例,一类实例只处理上传图片请求,把这类实例放在大内存机器上,一类实例只接受修改图片请求,部署在大内存+GPU机器上,还有一类部署在普通机器上,只处理查询请求。通过api gateway + instance tag来路由前端的请求。
Cloud Native:
很多讲微服务架构的文章其实都是在讲cloud native的技术,其实这一部分应该在微服务架构确定以后再考虑,主要研究的是服务的治理和通信的问题。都是一些很具体的解决方案。比如注册,发现,路由,鉴权,tracing, metrics, logs, circuit breaker, rpc, messag queue 等等。在做架构设计的时候,不应该舍本逐末,一上来就陷入到这些技术细节之中。首先应该用DDD的方法做好业务逻辑的拆分,等到服务的拆分完成以后,再考虑服务之间的协作(如果你发现两个服务交互太多,说明你拆的太细了,而如果你发现一个服务内某些资源之间很少相互依赖,说明你该考虑拆分了,请重新审视你的DDD domain mapping),这时候就要用到cloud native的这些技术了。
Martin Flower的理解
原文
核心观点,微服务是一种架构风格,它对软件的划分,以及项目组织和管理都有很大的影响。它没有具体的定义(我发现软件领域很多概念都是描述性的定义而不是准确的定义,比如RESTFUL,比如设计模式)。
In short, the microservice architectural style [1] is an approach
to developing a single application as a suite of small services,
each running in its own process and
communicating with lightweight mechanisms,
often an HTTP resource API
These services are built around business capabilities
and independently deployable by fully automated deployment machinery.
Martin简洁的描述了微服务的三个特性:
一组服务,独立进程(分开部署),轻量级通信,围绕业务能力拆分,自动化部署(离不开cloud native和ci/cd)。
These frustrations have led to the microservice architectural style:
building applications as suites of services.
As well as the fact that services are independently deployable and scalable,
each service also provides a firm module boundary, even allowing for different services to be written in different programming languages.
They can also be managed by different teams .
微服务就是好:
1,独立部署,独立扩容
2,更严格的模块边界
3,每个服务都可以独立演进
We do not claim that the microservice style is novel or innovative,
its roots go back at least to the design principles of Unix.
But we do think that not enough people consider a microservice architecture and
that many software developments would be better off if they used it.
UNIX的模块化思想:每次只做一件事并且把它做好,或者相关联的KISS原则,真的是无处不在。因为所有复杂问题的解决方案都是一样的:把它拆分成更小的,没那么复杂的问题,然后逐个解决。
好了进入正题,微服务的九大特征:
Componentization via Services
Our definition is that a component is a unit of software
that is independently replaceable and upgradeable.
由于可以独立的替换和升级,所以要求模块是高内聚低耦合的。
We define libraries as components that are linked into a program and called using in-memory function calls,
while services are out-of-process components who communicate with a mechanism such as a web service request, or remote procedure call
模块是在内存里面的函数调用,但是service需要网络通信。性能变差了但是更安全了。
good:
1,独立部署和升级
2,更好的故障隔离。
3,更强制的模块接口
bad:
1, 性能不好
2,接口设计更麻烦,并且更加的粗粒度
Organized around Business Capabilities (重点)
按照技术能力进行划分:前端,后端,DBA,但是通常任何一个业务流程都包含这三者的变更,也就是任何一点改动都牵扯到大量的沟通,并且每个团队都要对业务了解,这样的效率和负担显然不理想。
按照业务能力进行划分:每个团队都负责自己的那一部分业务,包括开发该业务需要的所有技术工作,包括前段后端和DB。这样业务的变更只会影响到一个团队,一个service。
按照业务能力组建的团队具有更明确的业务边界。
Products not Projects
这个其实是上一条的扩展吧。以前程序员只关心写代码,代码写完就认为完成了,其实不是这个样的,我们要对整个产品负责,我build了这个feature,还要保证它在线上符合预期的工作,you build it, you run it。这并不是要求人人都是全栈工程师,而是说一个team应该作为一个整体,交互end to end的产品给用户。team内部可能各有所长和分工,但是team所有成员都必须对他们负责的产品足够了解。
Smart endpoints and dumb pipes
这一点是相对于SOA来说的,微服务提供轻量级的通信协议和使用简单消息队列。RPC本身和message queue不理解其中的消息,只是作为通信管道来使用。这是跟SOA很大的区别,但是我们也没用过SOA,所以没感觉。
Decentralized Governance
每个服务可以有不同的技术实现。通常我们不会这么做。
Decentralized Data Management
每个service有自己的domain logic,自然也要维护自己的domain data。由于数据被分散了,无法join查表,所以可能需要使用到event sourcing和data rebuild在一个service里面建立另一个service的data snapshot。
由于分布式事务很难实现,所以CQRS和最终一致性被采纳。这些都是DDD的概念
这里也提到了一个service就应该对应一个domain context, DDD天然的应用到了微服务
Infrastructure Automation
由于微服务的特性,人工测试和部署已经不现实了,所以要依赖现代的cicd技术。
Design for failure
由于function call变成了RPC,必须时刻做好错误处理和隔离。timeout和circuit break成为常态。
Evolutionary Design
单体模式是用简单方法解决简单的问题
微服务使用复杂的方法解决复杂的问题
为了避免过度设计,并且业务也是天然的倾向于越来越复杂,从单体服务转化为微服务也成了一件很自然的是。另外微服务也是按照DDD的思想来组织的,业务的变化导致微服务的增减也是常事。
Evolutionary design recognizes the difficulties of getting boundaries right and thus
the importance of it being easy to refactor them.
But when your components are services with remote communications,
then refactoring is much harder than with in-process libraries.
Moving code is difficult across service boundaries,
any interface changes need to be coordinated between participants,
layers of backwards compatibility need to be added,
and testing is made more complicated.
模块比service更容易重构,所以拆分微服务别太随意。
Another issue is If the components do not compose cleanly,
then all you are doing is shifting complexity from inside a component to the connections between components
就像我说的,不要企图用一个common service去解决一个技术上的问题, 微服务是拆分复杂度不是转移复杂度。没有业务逻辑的service是没有存在价值的,避免创造蹩脚的公共服务!
One reasonable argument we've heard is that you shouldn't start with a microservices architecture.
Instead begin with a monolith, keep it modular, and split it into microservices once the monolith becomes a problem. (Although this advice isn't ideal, since a good in-process interface is usually not a good service interface.)
相关文章:
微服务的定义
个人理解 其实微服务就是DDD cloud native DDD: 提供了微服务的理论基础,一个大型复杂的服务可以按照其对外提供的业务功能划分成相对独立的小服务。注意这个小是相对而言的,每一个小服务其实就是一个独立的子域(subdomain),它应…...
什么是C语言中的异常和错误处理机制?
异常和错误处理机制是编程中重要的概念,它们允许您在程序执行过程中处理不可预测的情况和错误。在C语言中,没有内置的异常处理机制,但可以通过一些编程技巧和库来实现错误处理。在本文中,我们将探讨C语言中的异常和错误处理机制&a…...

某某盾-滑块验证-自动获取validate值-(逆向js+python)
我是标题 1.从get?网站获取滑块图片以及token1.1获取fp值1.2 获取cb值1.3 模拟发包 2.获取滑块移动距离3.发包获取最终的validate值3.1轨迹生成3.2 check网站发包3.3 获取data值 4.结论 本实验是根据某某盾示例网站 主要分为两个部分 1.从get?网站获取滑…...

C++:set和map的使用
set和map的使用 1.关联式容器2.key模型和key_value模型3.set3.1一些注意点3.2set的使用3.3习题 4.multiset5.map5.1一些注意点5.2map的使用5.3习题 6.multimap 1.关联式容器 序列式容器:比如我们之前讲的vector、string、list等均为序列式容器,特点是按…...

同城售后系统退款业务重构心得 | 京东云技术团队
一、重构背景 1.1、退款 到家、小时购、天选退款有2套结构,代码逻辑混乱; 其中小时购、天选部分售后单是和平生pop交互退款,部分是和售后中台交互退款;并且兼容3套逻辑; 痛点:代码繁重,缺乏…...

【计算机网络笔记】TCP连接管理(图解三次握手和四次挥手)
系列文章目录 什么是计算机网络? 什么是网络协议? 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能(1)——速率、带宽、延迟 计算机网络性能(2)…...

C++ 初阶 类和对象(中)
前言:C初阶系列,每一期博主都会使用简单朴素的语言将对应的知识分享给大家,争取让所有人都可以听懂,C初阶系列会持续更新,上学期间将不定时更新,但总会更的 目录 一、构造函数 1.1为什么要有构造函数&…...

【漏洞复现】Metinfo5.0.4任意文件包含漏洞复现
感谢互联网提供分享知识与智慧,在法治的社会里,请遵守有关法律法规 文章目录 1、蚁剑直接连接图片马2、读取敏感目录3、读取php源码4、执行PHP命令5、包含木马写Shell (图片马制作新方法) 以 metinfo_5.0.4为例 该环境的文件上传…...

【计算机网络实验/wireshark】tcp建立和释放
wireshark开始捕获后,浏览器打开xg.swjtu.edu.cn,网页传输完成后,关闭浏览器,然后停止报文捕获。 若捕获不到dns报文,先运行ipconfig/flushdns命令清空dns缓存 DNS报文 设置了筛选条件:dns 查询报文目的…...

STM32:I²C通信原理概要
一、IIC通信原理 IIC通信和串口通信有一定的相似之处,都有一根共地线和两根数据线。但是传递外部信息,串口有两根数据线可以进行双向通信,也就是全双工通信。而在IIC通信下,其中一条数据线是用于提供同步时钟脉冲的时钟线(SCL)&am…...
【开题报告】基于 Spring Boot 的在线预约导游系统的设计与实现
1.引言 在旅游行业中,导游起到了重要的作用,他们为游客提供了专业的旅游服务和相关信息。然而,传统的导游预约方式可能存在一些问题,如信息不透明、预约流程繁琐等。因此,我们计划开发一个基于 Spring Boot 的在线预约…...

如何使用ps制作ico图标文件
如何使用ps制作ico图标文件 Chapter1 如何使用ps制作ico图标文件Chapter2 ICOFormat.8bi(Photoshop Ico、Cur插件)的下载使用1. ICOFormat.8bi的作用2. ICOFormat.8bi使用 Chapter3 ps手机计算机图标教程,手绘设计精美手机APP软件图标的PS教程步骤 01 制…...
【Linux】logrotate实现“日志文件定时分割“
问题背景 项目部署的过程中,经常会需要查看程序的执行日志。我之前的做法都是用nohup ... > xxx.log 2>&1 &将日志保存到xxx.log文件中的。但是问题是,程序有时会运行很长时间,一直保存在一个文件里,文件会越来越大…...

Android可绘制资源概览(背景、图形等)
关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、drawable 分类3.1 Bitmap fileXML …...
力扣2095.删除链表的中间节点(java快慢指针)
Problem: 2095. 删除链表的中间节点 文章目录 思路解题方法复杂度Code 思路 利用快慢指针,快指针每次走两步,慢指针每次走一步(循环退出条件是fast指针不为空同时fast.next不为空),但是我们容易发现这样到最后slow指针…...
【Vue-Element-Admin】table添加自定义索引
通过给 typeindex 的列传入 index 属性,可以自定义索引。该属性传入数字时,将作为索引的起始值。也可以传入一个方法,它提供当前行的行号(从 0 开始)作为参数,返回值将作为索引展示。 <el-table:data&q…...

0008Java安卓程序设计-ssm基于Android平台的健康管理系统
文章目录 **摘要**目录系统实现开发环境 编程技术交流、源码分享、模板分享、网课教程 🐧裙:776871563 摘要 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,…...
Mac 禁用一些高占用cup的进程
什么是CrashReporter? CrashReporter在应用程序崩溃的任何时候都会运行,它旨在保存应用程序状态,以帮助开发人员找出应用程序崩溃原因。基本上,一个进程是启动、崩溃(并调用CrashReporter),然后…...

layui form表单 调整 label 宽度
这个可以调整所有label .layui-form-label {width: 120px !important; } .layui-input-block {margin-left: 150px !important; }情况是这样的,表单里有多个输入框,只有个别label 是长的,我就想调整一下个别长的,其它不变 <di…...

轻量封装WebGPU渲染系统示例<12>- 基础3D对象实体(源码)
当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/main/src/voxgpu/sample/PrimitiveEntityTest.ts 此示例渲染系统实现的特性: 1. 用户态与系统态隔离。 细节请见:引擎系统设计思路 - 用户态与系统态隔离-CSDN博客 2. 高频调用与低频调用隔…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...

Linux-进程间的通信
1、IPC: Inter Process Communication(进程间通信): 由于每个进程在操作系统中有独立的地址空间,它们不能像线程那样直接访问彼此的内存,所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...