大白话聊聊微服务——人人都能看懂的演进过程

SH的全栈笔记      2022-02-16     285

关键词:

这篇博客的本意是希望看到这篇文章的读者能够很轻松的理解我想表达的意思。但程序向的分享经常会不经意间就贴上了代码,很可能就会让人看的很懵。而且我认为分享一个东西,只有对方真正明白了其中的逻辑,才是有意义的分享。所以接下来我会尝试用大家都能理解的语言来聊一聊”微服务“。

【写在前面】

那么,什么是微服务呢?你不一定知道微服务,但是你一定知道麦某劳,而且知道麦某劳有个甜品站。你可能会问,甜品站和微服务有什么关联呢?

让我们先假设不把甜品站独立出来,而是普通的麦某劳店。经营一段时间你会发现,这个地方虽然人流量很大,也有顾客,但是顾客的需求80-90%都集中在甜品,导致甜品供不应求,而其余的菜品则没多少人购买。但是把这个店关了吗?那也不行,始终是有流量的。

所以综合考虑下来,方案就是把甜品这个“模块”从整个店中独立出来,单独对外提供服务。这样既能保住流量,也能避免浪费。

最开始的“整家麦某劳”店对应的概念就是单体应用,后面独立出的“甜品站”就是从单体应用中抽离出的“微服务”。不知道什么是单体应用和微服务是什么没关系,不知道单体应用为什么、以及如何转变成微服务的也没关系,让我们通过一个故事来完整的理解这个概念。

假设正在阅读这篇文章的你,拥有一家饭店。

0.【梦开始的地方】

你盘下了一个店面想卖炸鸡和甜品,于是你简单的把店装修了一下,购置了相关的设备,然后雇了厨师、服务员等相关的工作人员,就开始挂上招牌对外营业了,

0.1 店面

就是我们平常去使用的各种C端产品,如果你没有一个概念,那么可以直接把它理解成钉钉、微信这样一个我们日常都在用的APP就好,它们就是C端产品。

店的招牌(比如肯打鸡和麦某劳)就可以理解为我们平常APP里所能看到的,所能使用的东西,我们叫它客户端。

整个实体店就可以理解为开篇提到的“单体应用”,为客户提供实际的服务。

0.2 装修和购置设备

对应的是我们的开发团队,从产品经理接到客户的需求开始,根据需求整理好原型图,不停的跟客户沟通交流细节,反复的修改原型图,最终定下来的需求。

然后我们的UI同学介入,根据原型图出UI图,并最终确定下来。然后就是前端和后端的开发同学根据原型图中的逻辑,和UI图的样式细节开始迭代开发,并最终将产品上线。

0.3 炸鸡和甜品

有了前面麦某劳的例子,这个应该很好理解。炸鸡和甜品其实就是作为一个C端产品,提供给用户的不同种类的服务。

例如我们日常在用的钉钉,可以用来聊天、开视频会议和预定会议室。

1.【渐入佳境】

随着你不断的推出新的菜品,以及分量足,性价比高,朋友之间口口相传—“那家苍蝇馆子还可以”,也留住了大量回头客。慢慢的,来店里吃饭的客人越来越多,后厨渐渐忙不过来了。很多慕名而来的客人由于等了太长时间仍然没有上菜,更有甚者连座位没有。客人对美食的渴望转化成了失望和愤怒,于是反手就是一个超级差评。

1.1 不断的推出新的菜品

代表我们的产品迭代,不断的推出新功能,以此来为用户提供更多元化的服务,吸引更多的用户来使用我们的产品。例如疫情期间,钉钉在在线学习这块推出了很多新的功能。

1.2 朋友间的口口相传

则代表的是部分用户开始代替广告这种传播途径,开始了社群内的用户自传播。这是很多产品都想达到的目的,把产品的潜力挖掘到极致,让产品说话,为自己代言。

比起漫天飞的广告,这种来自朋友们的推荐,更加受到用户的信任。

1.3 关于差评

“后厨忙不过来”是指用户数量上涨,日常的请求数就会随之增多,而单个服务实例在某个时间单位内能够处理请求的数量是有限的(也就是后厨人数有限,就那么几个厨师,能做的菜数量也有限),这也直接导致了部分用户请求十分缓慢,甚至直接无法访问(后厨实在忙不过来了,有些客人就要等很久)。而用户对于产品的耐心是十分有限的,出现这种情况会导致部分甚至大量用户流失。

2.【蜂拥而至】

随着差评越来越多,你渐渐坐不住了。你觉得再这么下去你可能就要凉了,于是你想,厨师不够用那就多招几个嘛,于是雷厉风行的你贴出了招聘启事,然后顺利的招到了人。

人的问题解决了,那还有座位的问题。之前你没有想到会有这么人多来光顾,所以店里面的桌子和椅子摆的很宽松,但是实际上重新规划一下,还是能够多放好几张桌子的,这样一来就能够同时容纳更多人在店里用餐。

2.1 多招人

我们每个服务所能使用的资源是有限制的,例如你可以给你的JVM设置最大堆内存为1G,也可以加到2G。啊?什么是JVM?不重要,让我们重新理解前面一句话。2个厨师一分钟可以做5个菜,你转手再招2个厨师,那一分钟就可以做10个菜,这对应的概念是扩容,也就是增加服务器能够支配的运行资源,服务器就能够处理更多的请求,服务更多的用户。

2.2 重新规划桌椅摆放

刚开始开发时没有到用户会有这么大体量,所以大部分的API没有做什么优化,整个服务端应用的框架也搭建的很随意,因为上线的时间很紧,这可能会造成应用在维护性、扩展性和性能上的弊端。

通俗点来说就是,当时为了店里摆放好看,追求网红风,桌椅之间摆的太宽了,但是后来人多了,外面一堆人排队,店里面却熙熙攘攘,但是实际上你却是已经“坐满了”。

这种情况十分不利于后续的迭代的。所以对应到开发中的概念就是,对代码和框架进行重构,优化算法,让API尽量少占用系统资源,降低响应延迟,从而提高整个服务的服务能力。这样一来,服务实例就能扛住更多的请求。

3.【山穷水尽】

虽然多招了几个厨师,也重新规划了店里桌椅摆放,但是随着时间的推移,每天来店里吃饭的人还是越来越多,厨师已经不能再招了,已经没有那么多灶台了。之前的“差评热潮”又开始在店里上演。你想着,虽然店里火爆是好事,但是每天有那么多的人来店里看到没有位置就走了,这不是有钱赚不了吗?

而且很多目标用户在第三方网站上看到了这些差评,将会直接影响到客户是否愿意来店里,这会使你丧失大量的隐藏客户。于是你开始了轰轰烈烈的开分店业务,在附近又开了一家店。还是一样的配方,就是这个味~

3.1 开分店

开分店对应的概念是多实体部署,就是把一个同样的服务再部署一个,这样一来来自用户的流量就从一个服务扛变成了两个服务扛。

分店就可以把原本要把总店塞爆的流量给接过去,缓解了压力。

4.【柳暗花明】

随着时间的推移,分店越开越多,生意自然也是蒸蒸日上。但是你作为一个能够不只看表面的布局者,你发现了实际上的情况并没有表现出来的那么好。

有些区域人流量大,而有些区域虽然人流量大,但是对店感兴趣的人不多,甚至分店周围根本没有什么人。而有些地方的分店则异常火爆。虽然热门的店赚的钱能够抵上冷门的店的亏损,但是追求完美的你认为这种情况必须要得到改善,因为这始终是存在对资源的浪费。

所以经过一番调研,你决定在中心区域开一个顾客中心,所有想来餐厅的人都统一的来顾客中心,由顾客中心的人根据各个分店的火爆情况来分批次的把顾客送过去。这样一来,也就解决了有些店火爆,而有些店冷清的情况了。

4.1 人流量分布不均匀

这种情况主要发生在服务端运行了多个实例,那也就对于多个IP地址,而要调用哪个是由客户端来决定的,如果设计的不够好,就会出现某些时候某些实例成为热点实例,甚至出现“差评”实例这种情况,而其余实例则没有承担多少来自用户的流量。

说人话就是,我要是顾客,我去哪家店不是看我心情吗?我想去哪家店就去哪家店。当然实际情况没有这么夸张,客户端会有自己的策略。

而且同时维护如此多的服务端地址也是很麻烦的一件事,如果服务端此时又增加了实例,客户端则需要同步的更新。但是如果用户体量大的话,因为这种问题频繁的发包让用户更新,会对用户造成不好的体验。

4.2 顾客中心

这个比喻有些夸张,现实中有人这么干可能早破产了。“顾客中心”就是我们说的“网关”。有了网关,客户端就不用关心服务有多少个实例,也不用去维护所有的HOST,所有的请求直接从网关走,由网关来决定将当前请求分发到哪个实例。

“客户中心分批次根据情况送顾客”其实对应到的概念是负载均衡,什么意思呢?就是要让客户端产生的流量对所有实例雨露均沾。其实现的方式也有很多,大致分为随机、轮询、一致性哈希、加权等等。

而网关除了负载均衡,还有很多其他的特性。例如,动态的路由、限流、认证、日志、熔断、可编程插件配置等等。

5. 【微服务的关注点】

看完了这个故事,你可能会觉得没有什么,但是实际上你已经了解了一个应用从单体应用架构转为微服务的架构生命周期以及过程。这其中也包括为什么需要转为微服务架构,和转到微服务架构的好处在哪里。如果你都没有意识到自己理解了这个概念,可以再阅读一遍上面的小故事。

其实实际上的微服务要比上面故事所呈现出来的复杂很多,微服务中需要关注的点要比传统的单体应用多的多。在微服务中我们需要关注服务的发现、负载均衡,统一的配置管理,微服务集群的自愈和弹性伸缩,服务的调度和发布,微服务中的调用链监控,包括Metrics监控,日志监控,服务的安全考虑,API的统一管理等等。

首先把强耦合在一起的代码有条理的拆分出来就是一件很复杂的事情,微服务的划分粒度也是一个很大的挑战。例如很复杂的系统,一个用户服务的代码可能有好几千上万行,但是它仍然是一个微服务,没有再拆分用户服务A和用户服务B。而有的服务可能代码量只有几百行,这需要根据实际的业务情况来选择划分的粒度。

除了拆分服务的粒度,微服务本身还有很多组件。大家在故事中只了解了网关。其实还有很多组件。

服务发布就涉及到Jenkins,把我们的应用打包成Docker Image,然后通过自动化工具发布到对应的环境中。我们的应用跑在Docker中,那么我们就需要有一个容器编排工具来管理这么多容器。例如我们现在使用的就是Docker Swarm,跟业界现在流行的Kubernetes一样,有很多人在使用。

有了容器编排工具,就有工具的可视化界面,Docker Swarm对应的Portainer,和Kubernetes对应的Rancher。除此之外我们还要使用Gitlab来做我们的代码版本管理工具,MySQL和MongoDB作为数据存储的解决方案。Redis作为缓存的解决方案。同时需要有一个地方来统一管理所有服务的配置,我们叫微服务的配置中心。

除此之外,服务之间要相互调用就必须要知道对方的地址,就需要一个注册中心,来保管所有服务的地址,并及时的更新服务的状态。

还有很多细节,例如如何去构建一个Jenkins的构建流水线,如果实现一套CI/CD的流程,如果使用ELK去做统一的日志收集,如果在集群内实现SSO啊等等,由于篇幅原因就不在此一一赘述了。

【The End】

如果大家对微服务感兴趣可以下来详细的沟通,也可以去多了解了解Spring Cloud、Dubbo或者Kubernetes,尤其是Kubernetes,我个人认为这一定是未来微服务框架中的中流砥柱。

人人都能看懂的6种限流实现方案(代码片段)

  为了上班方便,去年我把自己在北郊的房子租出去了,搬到了南郊,这样离我上班的地方就近了,它为我节约了很多的时间成本,我可以用它来做很多有意义的事,最起码不会因为堵车而闹心了,幸福感直线上升。  但即... 查看详情

人人都能看懂的spring源码解析,spring如何解决循环依赖

人人都能看懂的Spring源码解析,Spring如何解决循环依赖原理解析什么是循环依赖循环依赖会有什么问题?如何解决循环依赖问题的根本原因如何解决为什么需要三级缓存?Spring的三级缓存源码走读Spring的三级缓存提前... 查看详情

老爷爷都能看懂的微服务架构系列001☀️分布式事务介绍-全面详细

分布式事务一:项目介绍数据库表二:在微服务架构中要面对的难点1:扣减库存时候的超卖问题2:以及归还库存时候的数据错误问题3:订单超时问题4:下单时候的事务三:分布式锁——解决的问题1:超卖问题,就是扣减库... 查看详情

小白也能看懂的laravel核心概念讲解

自动依赖注入什么是依赖注入,用大白话将通过类型提示的方式向函数传递参数。实例1首先,定义一个类:/routes/web.phpclassBar{}假如我们在其他地方要使用到 Bar 提供的功能(服务),怎么办,直接传入参数即可:/routes/web.... 查看详情

人人都能看懂的lstm

点击上方“迈微AI研习社”,选择“星标★”公众号重磅干货,第一时间送达大家好,我是Charmve。熟悉深度学习的朋友知道,LSTM是一种RNN模型,可以方便地处理时间序列数据,在NLP等领域有广泛应用。在... 查看详情

小学生都能看懂的fft!!!

小学生都能看懂的FFT!!!前言在创新实践重心偷偷看了一天FFT资料后,我终于看懂了一点。为了给大家提供一份简单易懂的学习资料,同时也方便自己以后复习,我决定动手写这份学习笔记。食用指南:本篇受众:如标题所示... 查看详情

review:人人都能看懂pod与容器设计模式

Review:人人都能看懂Pod与容器设计模式[]:https://mp.weixin.qq.com/s?__biz=MzA4ODg0NDkzOA==&mid=2247488010&idx=1&sn=37e4a3bff67d5ce466685b646cbab279&chksm=9022adefa75524f9f63ddc98d05210958725b79ba9823 查看详情

小白都能看懂的linux系统下安装配置zabbix

实验环境:操作系统:Centos7.6服务器ip:192.168.10.100运行用户:root网络环境:InternetZabbix是一个基于web界面的提供分布式系统监控及网络功能的企业级的开源监控工具,做为一个企业运维人员来说,zabbix可以给企业和运维人员带来... 查看详情

优秀文章及工具汇总

...:如何在Python中处理不平衡数据2.2模型详解2.2.1序列模型人人都能看懂的GRU强推|人人都能看懂的LSTM介绍及反向传播算法推导(非常详细)2.2.2机器学习Kaggle神器LightGBM最全解读!2.3业务总结2.3.1CTR算法大佬看了流泪,为什么这么好的... 查看详情

小白都能看得懂的教程一本教你如何在前端实现富文本编辑器(代码片段)

小白都能看得懂的教程一本教你如何在前端实现富文本编辑器博主博客文章内容导航(实时更新)更多优质文章推荐:收藏!最详细的Python全栈开发指南看完这篇你还不会Python全栈开发你来打我!!!一本教你如何在... 查看详情

小白都能看懂的分布式事务与2pc

2PC通信原理分布式事务的原子性什么是2PC2PC提交事务的过程2PC的全局提交规则2PC通信架构集中式2PC通信架构分层2PC通信架构线性2PC通信架构故障恢复站点故障报文丢失总结分布式事务的原子性一提到到事务,一般就会想到它... 查看详情

人人都能看懂的python装饰器入门教程

大家好,我是萱萱!之前的文章中提到,很多人认为理解了装饰器的概念和用法后,会觉得自己的Python水平有一个明显的提高。但很多教程在一上来就会给出装饰器的定义以及基本用法,例如你一定会在很多... 查看详情

小白都能看懂的实战教程手把手教你pythonweb全栈开发(day4)(代码片段)

...家好,我叫亓官劼(qíguānjié),这个《小白都能看懂的实战教程手把手教你PythonWeb全栈开发》是一个零基础的实战教程,手把手带你开发一套系统,带你了解Pythonweb全栈开发,目前正在连续更新中,如... 查看详情

小白都能看懂的redis讲解--针对单个键操作集锦

1重命名键renamekeynewname可以对键重命名,下面的例子我们创建了一个key为name,value为luke的键值对。然后将name重命名为user,之后查询name就返回nil,而user是可以查到值的。127.0.0.1:6379>setnamelukeOK127.0.0.1:6379>getname"luke"127.0.0.1:6379&... 查看详情

猴子都能看懂的androidmenu总结(代码片段)

简单谈谈Androidmenu菜单的使用,帮助入门的同学。menu主要分类:选项菜单:最常规的菜单子菜单:多层菜单的实现方案之一上下文菜单:android中长按视图控件后出现的菜单选项菜单(OptionMenu)该菜单默认在右上... 查看详情

小白都能看懂的关于mixins机制的理解(代码片段)

前言​在学习Flutter源码的时候,看到各种复杂的mixin和on,为了便于后续Flutter的学习,这里有必要一起来份详细Dart的Mixin机制。什么是mixins首先看看官方文档的定义:Mixinsareawayofreusingaclass’scodeinmultipleclasshierarchie... 查看详情

小白都能看懂的关于mixins机制的理解(代码片段)

前言​在学习Flutter源码的时候,看到各种复杂的mixin和on,为了便于后续Flutter的学习,这里有必要一起来份详细Dart的Mixin机制。什么是mixins首先看看官方文档的定义:Mixinsareawayofreusingaclass’scodeinmultipleclasshierarchie... 查看详情

零基础都能看懂的stlmap详解(代码片段)

🎈作者:Linux猿🎈简介:CSDN博客专家🏆,C/C++、面试、刷题、算法尽管咨询我,关注我,有问题私聊!🎈关注专栏:C/C++面试通关集锦 (优质好文持续更新中……)... 查看详情