谈谈我对微服务的理解2.0
文章目录
- 一、引出问题
- 二、微服务
- 2-1、微服务的技术
- 2-2、微服务的目的
- 三、微服务的拆分
- 四、不连表查询
- 五、微服务的好处
- 六、微服务的坏处
- 七、应付当下
这篇文章原本叫《如何做到不连表查询》,因为我对这个事一直耿耿于怀。在上家公司我经常被连表折磨(连的多性能差),最多的有二三十张。20年看阿里Java开发手册里面提到表连接不要超过三张,我一直把这个当作笑话。直到入职这家新公司,现在有四个多月了,我没连一张表。
年初的时候,看完了《凤凰架构》,上个月看完了《微服务架构设计模式》,加上这段时间的思考,对微服务有了新的理解。
一、引出问题
举一个例子,在上家公司有一个列表叫线索列表,列表展示的字段有60多个,离谱的的是这里面很多字段都要筛选。下面的每一个字段都要去关联一张或多张表才可以做到筛选
- 是否关注公众号
- 是否添加企微
- 用户标签
- 最后一次call时间
- 意向分
- 用户触达次数
- 重点客户标签
- …
在离职不久前,还接到了一个离谱的需求:要求记录用户的每次访问标记,并且可以支持随意标记搜索,比如用户访问了A、B、C、D, 那么搜索其中任意一个就都可以搜索出来这个用户。
这些表里面有很多是百万、千万级别的。之所以系统还能运行,全靠硬件。
不可否认,经过一轮轮的折磨,我的SQL功底要强了不少。
二、微服务
2-1、微服务的技术
我翻看我之前写的博客,找到我最开始学微服务是在20年2月,发布了一篇名为《SpringCloud项目整合【eureka+ribbon+zuul+hystrix+hystrix dashboard】》的博客。
其实就如这篇博客的名字一样,最开始的微服务是Cloud,它的代表是很多对应的组件,我把这一套称之为微服务1.0。对于微服务1.0我并没有实战经验,因为在我学完它不久之后我发现了微服务1.1也就是(SpringCloud Alibaba)。
为什么说SpringCloud Alibaba是1.1,因为本质上它和微服务1.0很相似,每一个组件,在Cloud Alibaba里面都有一个与之对应的组件。21年4月,我写一篇SpringCloud Alibaba整合的博客,完整的SpringCloud Alibaba我是没有用过,但用过一些它的组件,比如现在公司的服务注册与发现用的是Nacos。
21年9月,我入职了一家新公司,这家公司用的是Kubernetes,这是微服务2.0。在23年3月我写了一篇谈谈我理解的SpringCloud和Kubernetes的区别, Kubernetes相较于Cloud那一套有了很大的改进,Cloud的一切都是嵌入到代码里面,而Kubernetes意在剥离这些东西,在使用Kubernetes的时候,我们的微服务本质上就是一个SpringBoot的单体项目一样(当然这个很大一部分原因是我们没有解决微服务里面所有的问题,比如服务降级限流这些)。
最近我又在书里面看到了未来的方向,服务网格和无服务器。从单体到微服务的演变过程中带了很多的问题,如:注册与发现、负载、全局配置、分布式事务、服务的熔断降级、服务之间的通信等。
在Cloud里面每一个问题,都有对应着一个技术组件,在Kubernetes 里也有对应的组件,但Kubernetes里面的组件相较于Cloud的来说它藏的深一点了,比如服务的注册发现、服务的负载上了Kubernetes就自动完成了。
其实上面的这些问题和业务本身没多大关系,我所理解的服务网格就是进一步弱化这些组件,让这些问题的解决变成一个通用的方案,以后只需要把我们写的服务(一个干净的boot服务)丢到服务网格中,就自然了拥有了这些功能。(这只是我暂时的一个理解,等我学习了之后后续会再出一篇博客来讲解)
2-2、微服务的目的
开始的开始我们用的是单体,所有的代码都写在一个服务,修改任何东西都是牵一发而动全身的,不利于系统的稳定和快速的开发,我理解这个就是微服务出现的目的。
上面讲了微服务会带来很多的问题,从而需要引入很多新的组件来解决这些问题,每一个组件都是一个新的技术。然后大家都被带偏了——去追求新的技术,很长一段时间(或许就是写这篇文章之前)微服务在我的脑海里就等于各个组件。
所以我们疲于奔命,学完一个又一个组件,但心里却不承认微服务,只觉得它很复杂,给我们的开发带来了更多的问题,而它的好处又体会不了太多。这是因为我们忽略的微服务最重要的是服务的拆分,而不是这些个组件。
好吧,其实大家不去学习服务拆分,转而学各个组件,这是对的。因为服务拆分很虚,且和业务强相关,面试也不问,面试问的更多的还是各个组件。
三、微服务的拆分
讲道理,我不太会微服务的拆分,因为我刚刚才意识到服务拆分的重要性,而服务拆分和业务强相关,不像技术组件那么具体,会与不会一眼鉴定。但我也可以讲讲我最近关于服务拆分的一点感悟。
以往我们的开发前后端产品这三个角色其实是很割裂的,大家都忙各自的。然而要想让微服务拆分的好是需要这三方一起配合,尤其是产品相当重要,产品可以不懂技术,但不可以不懂系统。
服务拆分有一个简单的点就是,各个服务维护自己的表,比如A服务想要获取B服务的数据,一定是要B服务提供接口,而不能是A服务去直接连B服务的表,如果某个特别复杂的业务必须要连表才可以,那就弄一个聚合服务出来,对于各个服务的表的增、删、改一定要控制在自己的服务里。
每个服务经过一段时间的开发都相对稳定,但新的服务也会一直有,新服务总免不了要去查询旧服务的数据,然而旧服务的增删改查早就准备好了,接口都是现成的,直接用即可。(以前我老大告诉我这个的时候,我说那得提供多少个接口啊,现在看来还是太年轻。其实所需的接口不会很多,有些表是不需要对外提供的)
每个服务都只维护自己的数据,跨服务去拿数据其实是有代价的,产品要知道哪个数据属于哪个服务(或者说是哪个模块),而不能一股脑的觉得数据都在数据库,随便拿,随便组合,如果是这样就会把系统做烂。
注:使用dubbo看似和openFegin一样,都是和本地一样的调用,但实际上差别很大openFegin还是用的Http协议,dubbo的性能要强很多。这就为组装数据提供了有力的帮助。
四、不连表查询
想想我们的系统真的有那么复杂吗?报表不应该属于业务系统,让报表去查业务系统它很容易导致数据库崩溃,抛开报表,我们的系统是不是就真的只有增删改查了?
需要连表的地方也就只有列表和详细。
我们要把列表理解成展示某个资源的地方(一个资源的数据应该存在一张表里面),作如下思考:
- 这个字段是否真的有必要在列表展示(列表长度有限,寸土寸金),是否真的有人去看
- 纵观阿里云控制台列表发现几乎没有一个列表让你可以不限制条件去搜索的
- 搜索的时候真的需要模糊吗?想一想作为系统的使用者,假如有个通过用户手机号来搜索的功能,你去哪里拿到用户一半的手机号
- 如果真的有个别要展示其它服务的数据,就通过rpc获取,然后组装到列表中去
- 字典数据统一先查询,再通过内存匹配
再举一个实际的例子,我们是做医疗系统的,有一个很重要的数据“病人”,所有的数据都是围绕这个病人来的,大部人业务数据都冗余了病人的id,但大部人业务的列表都要基于病人的手机号、唯一编号、姓名来查询,我们是怎么做的呢?
- 正常情况下,我的第一反应就是 left join user 搞定,如果是这样,那你就多连了一张表,而且这个user表在其它服务是没资格去访问它的
- 我们提供一个三合一的Dubbo接口,先通过这个接口返回病人的id,再去业务表in这个id,这样in的数据永远不会多
对于详情,一个详情能展示多少个资源的信息呢?千万不要让资源污染(各个资源的数据放一起),一个详情接口可以返回很多资源的数据,但不应该放在一个实体里面,应该是很多个实体。而每一个资源都是单表的查询。
所以聊下来,全都是单表的查询,会存在什么性能呢?每一个数据的出入口都统一了,不会出现乱拿数据的现象,系统的维护性自然就高了。
这看起来一点也不简单,实际上也非常的困难。需要上下齐心一致,对每个角色的要求也很高。当然这并非不可实现,我现在的公司就是这样实践的。
五、微服务的好处
按照上面的拆分后,最大的一个好处就是,写代码变得很简单了,不会再有任何的性能问题,也不存在什么困难的问题,个人只需要当好螺丝钉,好好的写自己的业务代码就好了,幸福指数会很高。
它甚至比单体服务还要简单很多,试想一下,所有的操作都是单表的,最多就是做一下数据的聚合,这有多简单?这个也不是百分百的好处,相对连表就可以得出数据,它需要多次的rpc来组合数据(前期的开发会慢一些)。
六、微服务的坏处
这里我只说个人的坏处,它和好处是呼应的,试想一下,在这种环境下长时间的写代码你会有什么进步?除非你是微服务的掌舵人。
看似代码变得很简单,但它对人设计要求会高一些,你提供的Dubbo接口是给别人用的,你不能随意更改,在设计阶段需要多思考。
最近公司的前端在做一个事情就是,写Node作为聚合服务,让Node去调用后台的A、B服务来做数据的聚合。(这个好像也是阿里开创的)如果只是简单的数据聚合为什么还要Java呢?
而在不知多远的未来,服务网格和无服务的到来之后,Java不知是否还有用武之地。
不过也不必过于担心,但就目前国内来讲,大概率不会,因为老板和甲方是不讲道的,它们不懂微服务,这会导致你压根无法拆分成微服务,或者即便是拆分了,也无法维护起来,最终还是回归到了单体微服务(虽然拆分成了多个服务,实际上写的还是单体代码)。
拆分不合理的微服务,本质上就不是微服务,它不但没有给你带来好处,相反会带来很多的负担,服务多,入口乱七八糟的,很难维护。
七、应付当下
人在江湖生不由己,吃饭第一,如果没办法说服业务方,或者没有给力的团队,也有一些很拙劣的办法来达到业务目的。
在连表到了极限的时候,还可以尝试一些其它的办法。比如列表要展示是否关注公众号,可以把这个字段冗余到主表里面,每次用户关注/取消关注都实时去更新主表的字段。
具体的操作有两种方式
- 埋点,在关注/取消关注的地方发出一个事件,让线索服务感知然后去更新
- 监控数据库(本质上也就是监控binlog),当数据库的这个字段发生了变动发出事件,这个有很多的工具 比如 maxwell
这种方式也只能解决一对一的关系数据,如果是一对多还是要连表来查询。但是我们同样可以洗表,把N张表、洗成一张。
这种代价其实是很大的,要维护数据的一致性。
另外一个相对好点的方式是用搜索引擎,比如ES、MongoDB它们并非传统的关系型数据库,数据扩展性相对高一些,但依旧要面临数据的一致性问题。
相关文章:

谈谈我对微服务的理解2.0
文章目录 一、引出问题二、微服务2-1、微服务的技术2-2、微服务的目的 三、微服务的拆分四、不连表查询五、微服务的好处六、微服务的坏处七、应付当下 这篇文章原本叫《如何做到不连表查询》,因为我对这个事一直耿耿于怀。在上家公司我经常被连表折磨(连…...

ECCV 2024前沿科技速递:GLARE-基于生成潜在特征的码本检索点亮低光世界,低光环境也能拍出明亮大片!
在计算机视觉与图像处理领域,低光照条件下的图像增强一直是一个极具挑战性的难题。暗淡的光线不仅限制了图像的细节表现,还常常引入噪声和失真,极大地影响了图像的质量和可用性。然而,随着ECCV 2024(欧洲计算机视觉会议…...

前端低代码必备:FrontendBlocks 4.0版本重磅发布,助力Uniapp-X原生APP开发
项目介绍 本软件是一款强大的所见即所得前端页面设计器,是低代码开发领域的基础设施,生成的代码不依赖于任何框架,实测可以将前端布局工作的耗时减少80%以上,最关键的是,它实现了人人都可以写前端页面的梦想。 不用写…...

如何将PyCharm 中使用 PDM 管理的 Django 项目迁移到 VS Code 并确保一切正常工作?
嗨,我是兰若姐姐,相信很多小伙伴都遇到过这种情况,使用pycharm用习惯了,想换个编辑器,比如换成vscode,今天就告诉大家,如果轻松切换到vscode 步骤 1:在 VS Code 中打开项目 打开 V…...

认识Android Handler
“Android Handler” 通常指的是 Android 开发中的 Handler 类,它是 Android SDK 的一部分,用于管理消息队列和线程之间的通信。它在 Android 开发中非常有用,特别是在计划消息和可运行对象(Runnables)在未来某个时间点…...

如何在 Ubuntu VPS 上安装 Cassandra 并运行单节点集群
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 介绍 Cassandra,或者说 Apache Cassandra,是一个高度可扩展的开源数据库系统,在多节点设置上能够实…...

Golang | Leetcode Golang题解之第316题去除重复字母
题目: 题解: func removeDuplicateLetters(s string) string {left : [26]int{}for _, ch : range s {left[ch-a]}stack : []byte{}inStack : [26]bool{}for i : range s {ch : s[i]if !inStack[ch-a] {for len(stack) > 0 && ch < stack…...

pxe的实验
首先搭好实验环境、 如果没有安装好图形,则需要用yum groups list找到有“GUI”的然后用yum groups " " 把含有GUI的复制到双引号里安装 然后再执行init 5 打开图形 Kickstart 如果dnf用不了改成yum 然后在用yum install httpd -y 安装好http的软件 之后…...

复杂智能软件系统开发
软件开发技术总是伴随着计算技术的时代问题向前发展,随着智能计算时代的到来,软件界需要回应智能软件开发的问题。 大型机时代,软件开发的主要问题是软件开发的效率和质量问题,用机器指令或汇编语言编写软件,效率低、质量差。随着高级程序设计语言的出现及其自动编译技术…...

kickstart自动安装脚本
当安装Linux操作系统时,安装过程会需要回答很多关于设定的问题 这些问题必须手动选择,否则无法进行安装。当只安装1台Linux系统,手动选择设定工作量比较轻松,当安装多台Linux,这些设定需要重复多次,这些重复…...

linux运维一天一个shell命令之grep详解
一、概念 grep 是 Linux 和 Unix 系统中一个非常常用的命令行工具,用于搜索文本文件中的特定模式。它支持正则表达式,并能在文件中快速查找匹配的行 二、正则表达式 1.概念 正则表达式(Regular Expressions,简称 regex 或 reg…...

COMSOL金属氢化物-放氢过程
在此记录下放氢过程的软件设置思路 1、采用的是"达西定律""层流" 物理场,其中"层流"物理场选择了”弱可压缩流动“,这里主要是选择”可压缩流动“的话,算出来的瞬时流量值跟实测差距太大了。 2、设置"达西…...

(四)软件性能测试
1. 性能测试包含的方法有哪些(至少列举5种)? 正确回答通过率:69.0%[ 详情 ] 推荐指数: ★★★★★ 试题难度: 中级 性能测试大致分为以下六类 1、验收性能测试: 通过模拟生产运行的业务压力量…...

萱仔大模型学习记录5-langchain实战
前面我的bertlora微调已经跑出了不错的结果,我也学会了如何在bert上使用Lora进行微调,我后续会补充一个医疗意图识别的项目于这个系列,现在这个医疗意图识别代码还暂时不准备公开。我就继续按照我的计划学习一番LangChain。 LangChain是一个用…...

安装使用netron
1.安装netron pip install netron2.使用以下命令,然后打开浏览器查看。 netron netron --host 0.0.0.0 --port 6780 netron "model_path" --host 0.0.0.0 --port 67803.在jupyterlab中使用 github有人推荐的方法,jupyterlab部署在本地的可以用…...

JDFrame 一款比 Java 8 Stream 更灵活的数据处理工具
一、JDFrame 介绍 在大数据处理领域,Apache Spark以其强大的分布式计算能力和丰富的数据处理API而广受好评。然而,在许多日常的软件开发场景中,我们面临的数据量可能并不需要Spark这样的分布式系统来处理。相反,我们更希望有一种…...

《Android系统开发中高级定制专栏导读》
《Android系统开发中高级定制专栏导读》 欢迎来到【Android系统开发中高级定制‘】专栏!在这里,将深入探讨Android系统开发与定制的方方面面,涵盖从系统接口定制、权限管理、系统应用配置、驱动入门配置等多个领域。无论你是刚接触Android系…...

LeetCode 114. 二叉树展开为链表
更多题解尽在 https://sugar.matrixlab.dev/algorithm 每日更新。 组队打卡,更多解法等你一起来参与哦! LeetCode 114. 二叉树展开为链表,难度中等。 DFS 解题思路:先用 DFS 遍历二叉树,将树的结果存放在 List 中&am…...

78.子集
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 :总 // 注释的都为后来思考不必要的 class Solution {List<List<Integer…...

历史标签如何时间迁移?
本文解析的论文是: Lin, C.; Du, P.; Samat, A.; Li, E.; Wang, X.; Xia, J. Automatic Updating of Land Cover Maps in Rapidly Urbanizing Regions by Relational Knowledge Transferring from GlobeLand30. Remote Sens. 2019, 11, 1397. https://doi.org/10.33…...

Jenkins参数化构建
目录 一. 准备ansible 二. Gitlab新建子项目 三. Jenkins建立任务,进行初步配置 四. 导入nginx主机的公钥 五. 配置ansible执行脚本 六. 构建测试 一. 准备ansible 在jenkins主机中安装ansible [rootjenkins ~]# yum install -y epel-release [rootjenkins…...

函数实例讲解(三)
文章目录 常用的三个数学函数1、绝对值函数ABS2、取整数部分INT3、求余数函数MOD 求极值函数max、min1、Max2、Min 附加条件下求平均数1、AVERAGE2、AVERAGEIF3、AVERAGEIFS VLOOKUP与COLUMN1、VLOOKUP2、COLUMN 查找函数LOOKUP1、基础语法2、向量形式3、数组形式 常用的三个数…...

如何选择适合自己的编程语言?大学新生入门编程最佳路径指南
编程已成为当代大学生的必备技能,但面对众多编程语言和学习资源,新生们常常感到迷茫。如何选择适合自己的编程语言?如何制定有效的学习计划?如何避免常见的学习陷阱?本文将为你提供详细的指导,为你的大学生…...

编程的法则 依赖倒置原则 (Dependency Inversion Principle)包括如何实践
编程的法则 依赖倒置原则 (Dependency Inversion Principle)包括如何实践 flyfish 2017-07-19 2024-07-18 在软件工程中,存在着层次结构,其中上层的业务逻辑依赖于下层的实现细节。如果是直接的依赖关系可能会导致问题…...

[数据集][目标检测]肾结石检测数据集VOC+YOLO格式1299张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):1299 标注数量(xml文件个数):1299 标注数量(txt文件个数):1299 标注…...

pxe安装部署
RHEL7为例: ifconfig查看ip 一.环境配置 1.配置软件仓库: mkdir /rhel7 mount /dev/cdrom /rhel7 echo mount /dev/cdrom /rhel74 >> /etc/rc.d/rc,local chmod x /etc/rc.d/rc.local 2.关闭火墙和selinux,下载…...

Linux用户-sudo命令
作者介绍:简历上没有一个精通的运维工程师。希望大家多多关注我,我尽量把自己会的都分享给大家,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux是一个多用户多任务操作系统,这意味着它可以同时支持多个用户登录并使用系统。…...

Unity强化工程 之 SpriteEditer Multiple
本文仅作笔记学习和分享,不用做任何商业用途 本文包括但不限于unity官方手册,unity唐老狮等教程知识,如有不足还请斧正 1. SpriteEditer Multiple Automatic slicing - Unity 手册 这是用于裁剪图集的模式 应用之后精灵编辑器会看到Slice亮…...

大数据Flink(一百零九):阿里云Flink的基本名称概念
文章目录 阿里云Flink的基本名称概念 一、层次结构 二、概念说明 1、工作空间(Workspace) 2、项目空间(Namespace) 3、资源(Resource) 4、草稿(Draft&#…...

如何利用AI工具延长摸鱼时间、准点下班?
你好同学,我是沐爸,欢迎点赞、收藏和关注!个人知乎、公众号"沐爸空间" 俗话说,不会摸鱼的程序猿不是好的程序猿。同学,你是不是也在为不能准点下班、每天加班、没有时间提升自己而烦恼? 接下来…...