标签: 微服务

关于 Java 学习微服务或分布式学习路径的问题

目前学习完了 Springboot 一些框架,一些 redis,es 等框架。想进一步学习 Java 微服务或分布式等!看了部分的 Spring Cloud 的相关介绍,技术太多,而且有些已经过时,不知道学习那种比较好,所以希望大佬指导一下后面的学习路径!*好是列出相关的技术栈

学习 Java 分布式 路径9 条回复 • 2021-10-12 09:28:05 +08:00
ming168 1
ming168 14 小时 3 分钟前
+1
pengtdyd 2
pengtdyd 13 小时 56 分钟前
别卷了,不值得
546L5LiK6ZOt 3
546L5LiK6ZOt 13 小时 12 分钟前 ❤️ 3
这里够学的了: http://icyfenix.cn/
Wien 4
Wien 12 小时 47 分钟前
@546L5LiK6ZOt 周志明大佬,著作 Java 虚拟机必读书籍
xuanbg 5
xuanbg 12 小时 34 分钟前 ❤️ 1
具体的应用和工具使用方法有什么可学的。。。
1 、为什么需要微服务
2 、微服务是如何解决他需要解决的问题的
搞清楚这两个点就足够了。
RayDG 6
RayDG 10 小时 20 分钟前 via Android
可以看看黑马*新的微服务视频,会对微服务有个比较全面的认识
RayDG 7
RayDG 10 小时 19 分钟前 via Android
@RayDG 忘了说,是 B 站视频
yogogo 8
yogogo 3 小时 47 分钟前
框架看多了也没啥用,还是得上手才行。看看 Java 基础还有用一点
wangpugod2003 9
wangpugod2003 2 小时 2 分钟前
B 站油管找个 JAVA 语言的基于微服务的系统,跟着做就行了。
一般现在主流的有两个路线,一个是完全的 JAVA 栈,spring cloud 框架; 一个是 k8s,应用 java 写,docker 镜像部署到 K8s 集群。
看看自己想学哪个。

微服务如何拆分,能解决哪些问题?

微服务在*近几年大受欢迎,很多公司的研发人员都在考虑微服务架构,同时,随着 Docker 容器技术和自动化运维等相关技术发展,微服务变得更容易管理,这给了微服务架构良好的发展机会。

在做微服务的路上,拆分服务是个很热的话题。我们应该按照什么原则将现有的业务进行拆分?是否拆分得越细就越好?接下来一起谈谈服务拆分的策略和坚持的原则。

%title插图%num

拆分目的是什么?

在介绍如何拆分之前,我们需要了解下拆分的目的是什么,这样才不会在后续的拆分过程中忘了*初的目的。

拆分的本质是为了将复杂的问题简单化,那么我们在单体架构阶段遇到了哪些复杂性问题呢?首先来回想下当初为什么选用了单体架构,在电商项目刚启动的时候,我们只希望能尽快地将项目搭建起来,方便将产品更早的投放市场进行快速验证。在开发初期,这种架构确实给开发和运维带来了很大的便捷,主要体现在:

  • 开发简单直接,代码和项目集中式管理。
  • 排查问题时只需要排查这个应用就可以了,更有针对性。
  • 只需要维护一个工程,节省维护系统运行的人力成本。

但是随着功能越来越多,开发团队的规模越来越大,单体架构的缺陷慢慢体现出来,主要有以下几个方面:

在技术层面,数据库的连接数成为应用服务器扩容的瓶颈,因为连接 MySQL 的客户端数量是有限制的。

除此之外,单体架构增加了研发的成本抑制了研发效率的提升。比如公司的垂直电商系统团队会被按业务线拆分为不同的组。当如此多的小团队共同维护一套代码和一个系统时,在配合的过程中就会出现问题。不同的团队之间沟通少,假如一个团队需要一个发送短信的功能,那么有的研发同学会认为*快的方式不是询问其他团队是否有现成的,而是自己写一套,但是这种想法是不合适的,会造成功能服务的重复开发。由于代码部署在一起,每个人都向同一个代码库提交代码,代码冲突无法避免;同时功能之间耦合严重,可能你只是更改了很小的逻辑却导致其它功能不可用,从而在测试时需要对整体功能回归,延长了交付时间。模块之间互相依赖,一个小团队中的成员犯了一个错误,就可能会影响到其它团队维护的服务,对于整体系统稳定性影响很大。

*后,单体架构对于系统的运维也会有很大的影响。想象一下,在项目初期你的代码可能只有几千行,构建一次只需要一分钟,那么你可以很敏捷灵活地频繁上线变更修复问题。但是当你的系统扩充到几十万行甚至上百万行代码的时候,一次构建的过程包括编译、单元测试、打包和上传到正式环境,花费的时间可能达到十几分钟,并且任何小的修改,都需要构建整个项目,上线变更的过程非常不灵活。

而这些问题都可以通过微服务化拆分来解决。

为了方便你更好的理解这块,在此附上一份表格(内容来源:《持续演进的 Cloud Native:云原生架构下微服务*佳》一书),可以更直观地帮助你认识拆分的目的。

%title插图%num

%title插图%num

拆分时机应该如何决策?

产品初期,应该以单体架构优先。因为面对一个新的领域,对业务的理解很难在开始阶段就比较清晰,往往是经过一段时间之后,才能逐步稳定,如果拆分过早,导致边界拆分不合理或者拆的过细,反而会影响生产力。很多时候,从一个已有的单体架构中逐步划分服务,要比一开始就构建微服务简单得多。同时公司的产品并没有被市场验证过,有可能会失败,所以这个投入的风险也会比较高。

另外,在资源受限的情况下,采用微服务架构很多优势无法体现,性能上的劣势反而会比较明显。如下图所示。当业务复杂度达到一定程度后,微服务架构消耗的成本才会体现优势,并不是所有的场景都适合采用微服务架构,服务的划分应逐步进行,持续演进。产品初期,业务复杂度不高的时候,应该尽量采用单体架构。

%title插图%num

随着公司的商业模式逐渐得到验证,且产品获得了市场的认可,为了能加快产品的迭代效率快速占领市场,公司开始引进更多的开发同学,这时系统的复杂度会变得越来越高,就出现单体应用和团队规模之间出现矛盾,研发效率不升反降。上图中的交叉点表明,业务已经达到了一定的复杂度,单体应用已经无法满足业务增长的需求,研发效率开始下降,而这时就是需要考虑进行服务拆分的时机点。这个点需要架构师去权衡。笔者所在的公司,是当团队规模达到百人的时候,才考虑进行服务化。

当我们清楚了什么时候进行拆分,就可以直接落地了吗?不是的,微服务拆分的落地还要提前准备好配套的基础设施,如服务描述、注册中心、服务框架、服务监控、服务追踪、服务治理等几大基本组件,以上每个组件缺一不可,每个组件展开又包括很多技术门槛,比如,容器技术、持续部署、DevOps 等相关概念,以及人才的储备和观念的变化。微服务不仅仅是技术的升级,更是开发方式、组织架构、开发观念的转变。

至此,何时进行微服务的拆分,整体总结如下:

  1. 业务规模:业务模式得到市场的验证,需要进一步加快脚步快速占领市场,这时业务的规模变得越来越大,按产品生命周期来划分(导入期、成长期、成熟期、衰退期)这时一般在成长期阶段。如果是导入期,尽量采用单体架构。
  2. 团队规模:一般是团队达到百人的时候。
  1. 技术储备:领域驱动设计、注册中心、配置中心、日志系统、持续交付、监控系统、分布式定时任务、CAP 理论、分布式调用链、API 网关等等。
  2. 人才储备:精通微服务落地经验的架构师及相应开发同学。
  3. 研发效率:研发效率大幅下降,具体问题参加上面拆分目的里提到的。

%title插图%num

拆分时应该坚守哪些指导原则?

1. 单一服务内部功能高内聚低耦合

也就是说每个服务只完成自己职责内的任务,对于不是自己职责的功能交给其它服务来完成。

2. 闭包原则(CCP)

微服务的闭包原则就是当我们需要改变一个微服务的时候,所有依赖都在这个微服务的组件内,不需要修改其他微服务。

3. 服务自治、接口隔离原则

尽量消除对其他服务的强依赖,这样可以降低沟通成本,提升服务稳定性。服务通过标准的接口隔离,隐藏内部实现细节。这使得服务可以独立开发、测试、部署、运行,以服务为单位持续交付。

4. 持续演进原则

在服务拆分的初期,你其实很难确定服务究竟要拆成什么样。从微服务这几个字来看,服务的粒度貌似应该足够小,但是服务多了也会带来问题,服务数量快速增长会带来架构复杂度急剧升高,开发、测试、运维等环节很难快速适应,会导致故障率大幅增加,可用性降低,非必要情况,应逐步划分,持续演进,避免服务数量的爆炸性增长,这等同于灰度发布的效果,先拿出几个不太重要的功能拆分出一个服务做试验,如果出现故障,则可以减少故障的影响范围。

5. 拆分的过程尽量避免影响产品的日常功能迭代

也就是说要一边做产品功能迭代,一边完成服务化拆分。比如优先剥离比较独立的边界服务(如短信服务等),从非核心的服务出发减少拆分对现有业务的影响,也给团队一个练习、试错的机会。同时当两个服务存在依赖关系时优先拆分被依赖的服务。

6. 服务接口的定义要具备可扩展性

服务拆分之后,由于服务是以独立进程的方式部署,所以服务之间通信就不再是进程内部的方法调用而是跨进程的网络通信了。在这种通信模型下服务接口的定义要具备可扩展性,否则在服务变更时会造成意想不到的错误。比如微服务的接口因为升级把之前的三个参数改成了四个,上线后导致调用方大量报错,推荐做法服务接口的参数类型*好是封装类,这样如果增加参数就不必变更接口的签名,而只需要在类中添加字段就可以了

7. 避免环形依赖与双向依赖

尽量不要有服务之间的环形依赖或双向依赖,原因是存在这种情况说明我们的功能边界没有化分清楚或者有通用的功能没有下沉下来。

%title插图%num

8. 阶段性合并

随着你对业务领域理解的逐渐深入或者业务本身逻辑发生了比较大的变化,亦或者之前的拆分没有考虑的很清楚,导致拆分后的服务边界变得越来越混乱,这时就要重新梳理领域边界,不断纠正拆分的合理性。

%title插图%num

拆分的粒度是不是越细越好?

目前很多传统的单体应用再向微服务架构进行升级改造,如果拆分粒度太细会增加运维复杂度,粒度过大又起不到效果,那么改造过程中如何平衡拆分粒度呢?

%title插图%num

1、弓箭原理

平衡拆分粒度可以从两方面进行权衡,一是业务发展的复杂度,二是团队规模的人数。如上图,它就像弓箭一样,只有当业务复杂度和团队人数足够大的时候,射出的服务拆分粒度这把剑才会飞的更远,发挥出*大的威力。

比如说电商的商品服务,当我们把商品从大的单体里拆分出来的时候,就商品服务本身来讲,逻辑并没有足够复杂到 2~3 个人没法维护的地步,这时我们没有必要继续将商品服务拆的更细,但是随着业务的发展,商品的业务逻辑变的越来越复杂,可能同时服务公司的多个平台,此时你会发现商品服务本身面临的问题跟单体架构阶段面临的问题基本一样,这个阶段就需要我们将商品拆成更细粒度的服务,比如,库存服务、价格服务、类目服务、商品基础信息服务等等。

虽然业务复杂度已经满足了,如果公司此时没有足够的人力(招聘不及时或员工异动比较多),服务*好也不要拆分,拆分会因为人力的不足导致更多的问题,如研发效率大幅下降(一个开发负责与其不匹配数量的服务)。这里引申另外一个问题,一个微服务究竟需要几个开发维护是比较理性的?我引用下李云华老师在”从零开始学架构“ 中的一段经典论述,可以解决此问题。

2、三个火枪手原则

为什么说是三个人分配一个服务是比较理性的?而不是 4 个,也不是 2 个呢?

首先,从系统规模来讲,3 个人负责开发一个系统,系统的复杂度刚好达到每个人都能全面理解整个系统,又能够进行分工的粒度;如果是 2 个人开发一个系统,系统的复杂度不够,开发人员可能觉得无法体现自己的技术实力;如果是 4 个甚至更多人开发一个系统,系统复杂度又会无法让开发人员对系统的细节都了解很深。

其次,从团队管理来说,3 个人可以形成一个稳定的备份,即使 1 个人休假或者调配到其他系统,剩余 2 个人还可以支撑;如果是 2 个人,抽调 1 个后剩余的 1 个人压力很大;如果是 1 个人,这就是单点了,团队没有备份,某些情况下是很危险的,假如这个人休假了,系统出问题了怎么办?

*后,从技术提升的角度来讲,3 个人的技术小组既能够形成有效的讨论,又能够快速达成一致意见;如果是 2 个人,可能会出现互相坚持自己的意见,或者 2 个人经验都不足导致设计缺陷;如果是 1 个人,由于没有人跟他进行技术讨论,很可能陷入思维盲区导致重大问题;如果是 4 个人或者更多,可能有的参与的人员并没有认真参与,只是完成任务而已。

“三个火枪手”的原则主要应用于微服务设计和开发阶段,如果微服务经过一段时间发展后已经比较稳定,处于维护期了,无须太多的开发,那么平均 1 个人维护 1 个微服务甚至几个微服务都可以。当然考虑到人员备份问题,每个微服务*好都安排 2 个人维护,每个人都可以维护多个微服务。

综上所诉,拆分粒度不是越细越好,粒度需要符合弓箭原理及三个火枪手原则。

%title插图%num

拆分策略有哪些?

拆分策略可以按功能和非功能维度进行考虑,功能维度主要是划分清楚业务的边界,非功能维度主要考虑六点包括扩展性、复用性、高性能、高可用、安全性、异构性。接下来详细介绍下。

1、功能维度

功能维度主要是划分清楚业务边界,采用的主要设计方法可以利用 DDD(关于 DDD 的理论知识可以参考网上其它资料),DDD 的战略设计会建立领域模型,可以通过领域模型指导微服务的拆分,主要分四步进行:

  • *步,找出领域实体和值对象等领域对象。
  • 第二步,找出聚合根,根据实体、值对象与聚合根的依赖关系,建立聚合。
  • 第三步,根据业务及语义边界等因素,定义限界上下文。
  • 第四步,每一个限界上下文可以拆分为一个对应的微服务,但也要考虑一些非功能因素。

以电商的场景为例,交易链路划分的限界上下文如下图左半部分,根据一个限界上下文可以设计一个微服务,拆解出来的微服务如下图右侧部分。

%title插图%num

2、非功能维度

当我们按照功能维度进行拆分后,并不是就万事大吉了,大部分场景下,我们还需要加入其它维度进一步拆分,才能*终解决单体架构带来的问题。

  • 扩展性:区分系统中变与不变的部分,不变的部分一般是成熟的、通用的服务功能,变的部分一般是改动比较多、满足业务迭代扩展性需要的功能,我们可以将不变的部分拆分出来,作为共用的服务,将变的部分独立出来满足个性化扩展需要。同时根据二八原则,系统中经常变动的部分大约只占 20%,而剩下的 80% 基本不变或*少变化,这样的拆分也解决了发布频率过多而影响成熟服务稳定性的问题。
  • 复用性:不同的业务里或服务里经常会出现重复的功能,比如每个服务都有鉴权、限流、安全及日志监控等功能,可以将这些通过的功能拆分出来形成独立的服务,也就是微服务里面的 API 网关。在如,对于滴滴业务,有快车和顺风车业务,其中都涉及到了订单支付的功能,那么就可以将订单支付独立出来,作为通用服务服务好上层业务。如下图:

%title插图%num

  • 高性能:将性能要求高或者性能压力大的模块拆分出来,避免性能压力大的服务影响其它服务。常见的拆分方式和具体的性能瓶颈有关,例如电商的抢购,性能压力*大的是入口的排队功能,可以将排队功能独立为一个服务。同时,我们也可以基于读写分离来拆分,比如电商的商品信息,在 App 端主要是商详有大量的读取操作,但是写入端商家中心访问量确很少。因此可以对流量较大或较为核心的服务做读写分离,拆分为两个服务发布,一个负责读,另外一个负责写。还有数据一致性是另一个基于性能维度拆分需要考虑的点,对于强一致的数据,属于强耦合,尽量放在同一个服务中(但是有时会因为各种原因需要进行拆分,那就需要有响应的机制进行保证),弱一致性通常可以拆分为不同的服务。

%title插图%num

  • 高可用:将可靠性要求高的核心服务和可靠性要求低的非核心服务拆分开来,然后重点保证核心服务的高可用。具体拆分的时候,核心服务可以是一个也可以是多个,只要*终的服务数量满足“三个火枪手”的原则就可以。比如针对商家服务,可以拆分一个核心服务一个非核心服务,核心服务供交易服务访问,非核心提供给商家中心访问。
  • 安全性:不同的服务可能对信息安全有不同的要求,因此把需要高度安全的服务拆分出来,进行区别部署,比如设置特定的 DMZ 区域对服务进行分区部署,可以更有针对性地满足信息安全的要求,也可以降低对防火墙等安全设备吞吐量、并发性等方面的要求,降低成本,提高效率。
  • 异构性:对于对开发语言种类有要求的业务场景,可以用不同的语言将其功能独立出来实现一个独立服务。

以上几种拆分方式不是多选一,而是可以根据实际情况自由排列组合。同时拆分不仅仅是架构上的调整,也意味着要在组织结构上做出相应的适应性优化,以确保拆分后的服务由相对独立的团队负责维护。

%title插图%num服务都拆了为什么还要合并?

古希腊哲学家赫拉克利特曾经说过:“人不能两次踏进同一条河流。”随着时间的流逝,任何事物的状态都会发生变化。线上系统同样如此,即使一个系统在不同时刻的状况也*不会一模一样。现在拆分出来的服务粒度也许合适,但谁能保证这个粒度能够一直正确呢。

服务都拆了为什么还要合,就是要不断适应新的业务发展阶段,笔者这里做个类比看大家是否清晰,拆相当于我们开发代码,合相当于重构代码,为什么要重构呢,相信你肯定知道。微服务的合也是一样的道理,随着我们对应用程序领域的了解越来越深,它们可能会随着时间的推移而变化。例如,你可能会发现由于过多的进程间通信而导致特定的分解效率低下,导致你必须把一些服务组合在一起。

同时因为人员和服务数量的不匹配,导致的维护成本增加,也是导致服务合并的一个重要原因。例如,今年疫情的影响导致很多企业开始大量裁员,人员流失但是服务的数量确没有变,造成服务数量和人员的不平衡,一个开发同学同时要维护至少 5 个服务的开发,效率大幅下降。

那么如果微服务数量过多和资源不匹配,则可以考虑合并多个微服务到服务包,部署到一台服务器,这样可以节省服务运行时的基础资源消耗也降低了维护成本。需要注意的是,虽然服务包是运行在一个进程中,但是服务包内的服务依然要满足微服务定义,以便在未来某一天要重新拆开的时候可以很快就分离。服务合并到服务包示意图如下:

%title插图%num

%title插图%num

拆分过程中要注意的风险

1、不打无准备之仗

开发团队是否具备足够的经验,能否驾驭微服务的技术栈,可能是*个需要考虑的点。这里并不是要求团队必须具备完善的经验才能启动服务拆分,如果团队中有这方面的专家固然是*好的。如果没有,那可能就需要事先进行充分的技术论证和预演,至少不打无准备之仗。避免哪个简单就先拆哪个,哪个新业务要上了,先起一个服务再说。否则可能在一些分布式常见的问题上会踩坑,比如服务器资源不够、运维困难、服务之间调用混乱、调用重试、超时机制、分布式事务等等。

2、不断纠正

我们需要承认我们的认知是有限的,只能基于目前的业务状态和有限的对未来的预测来制定出一个相对合适的拆分方案,而不是所谓的*优方案,任何方案都只能保证在当下提供了相对合适的粒度和划分原则,要时刻做好在未来的末一个时刻会变得不和时宜、需要再次调整的准备。因此随着业务的演进,需要我们重新审视服务的划分是否合理,如服务拆的太细,导致人员效率反而下降,故障的概率也大大增加,则需要重新划分好领域边界。

3、要做行动派,而不是理论派

在具体怎么拆分上,也不要太纠结于是否合适,不动手怎么知道合不合适呢?如果拆了之后发现真的不合适,在重新调整就好了。你可能会说,重新调整成本比较高。但实际上这个问题的本质是有没有针对服务化架构搭建起一套完成的能力体系,比如服务治理平台、数据迁移工具、数据双写等等,如果有的话,重新调整的成本是不会太高的。

妥了!微服务治理的困难,用 Serverless 来解决

 

%title插图%num

微服务治理面临的挑战

在业务初期,因人手有限,想要快速开发并上线产品,很多团队使用单体的架构来开发。但是随着公司的发展,会不断往系统里面添加新的业务功能,系统越来越庞大,需求不断增加,越来越多的人也会加入到开发团队,代码库也会增速的膨胀,慢慢的单体应用变得越来越臃肿,可维护性和灵活性逐渐降低,维护成本越来越高。

%title插图%num

这个时候很多团队会把单体应用架构改为微服务的架构,解决单体应用的问题。但随着微服务越来越多,运维投入会越来越大,需要保证几十甚至几百个服务正常运行与协作,这给运维带来了很大的挑战,下面从软件生命周期的角度来分析这些挑战:

  • 开发测试态
    • 如何实现开发、测试、线上环境隔离?
    • 如何快速调试本地变更?
    • 如何快速部署本地变更?
  • 发布态
    • 如何设计服务发布策略?
    • 如何无损下线旧版本服务?
    • 如何实现对新版本服务灰 度测试?
  • 运行态
    • 线上问题如何排查?有什么工具可以利用呢?
    • 对于服务质量差的节点如何处理?
    • 对于完全不工作的实例我们如何恢复?

面对以上问题,Serverless 应用引擎在这方面都做了哪些工作?

%title插图%num

Serverless 应用引擎

%title插图%num

如上图所示,Serverless 应用引擎(SAE)基于神龙 + ECI + VPC + SLB + NAS 等 IaaS 资源,构建了一个 Kubernetes 集群,在此之上提供了应用管理和微服务治理的一些能力。它可以针对不同应用类型进行托管,比如 Spring Cloud 应用、Dubbo 应用、HSF 应用、Web 应用和多语言应用。并且支持 Cloudtoolkit 插件、云效 RDC / Jenkins 等开发者工具。在 Serverless 应用引擎上,零代码改造就可以把 Java 微服务的应用迁移到 Serverless。

总的来说,Serverless 应用引擎能够提供成本更优、效率更高的一站式应用托管方案,零门槛、零改造、零容器基础,即可享受 Serverless + K8s + 微服务带来的技术红利。

%title插图%num

微服务治理实践

1. 开发态实践

1)多环境管理

%title插图%num

  • 多租户共有一个注册中心,通过不同的租户对流量进行隔离;更进一步可以通过网络 VPC 进行环境隔离;
  • 提供环境级别的运维操作,比如一键停止和拉起整个环境的功能;
  • 提供环境级别的配置管理;
  • 提供环境级别的网关路由流量管理。

2)云端联调

Serverless 应用引擎(SAE)基于 Alibaba CloudToolkit 插件+ 跳板机可以实现:

  • 本地服务订阅并注册到云端 SAE 内置的注册中心;
  • 本地服务可以和云端 SAE 服务互相调用。

%title插图%num

如上图所示,在实现的时候用户需要有一个 ECS 代理服务器,实际注册的是 ECS 代理服务器到 SAE 的注册中心,IDEA 在安装 Cloudtoolkit 插件以后,在启动进程时,会在本地拉起一个通道服务,这个通道服务会连上 ECS 代理服务器,本地所有的请求都会转到 ECS 代理服务器上,云端对服务的调用也会通过 ECS 代理转到本地,这样就可以以*新的代码在本地断点调试,这就是云端联调的实现。

3)构建快速开发体系

%title插图%num

代码在本地完成联调以后,要能快速地通过 Maven 插件和 IDEA-plugin,可以很快地一键部署到云端的开发环境。

2. 发布态实践

1)应用发布三板斧

%title插图%num

%title插图%num

  • 可灰度:应用在发布的过程中,运维平台一定要有发布策略,包括单批、分批、金丝雀等发布策略;同时还要支持流量的灰度;批次间也要允许自动/手动任选。
  • 可观测:发布过程可监控,白屏化实时查看发布的日志和结果,及时定位问题。
  • 可回滚:允许人工介入控制发布流程:异常中止、一键回滚。

通过这三点可以让应用发布做到可灰度、可观测、可回滚。

2)微服务无损下线

在版本更换的过程中,SAE 是如何保证旧版本的微服务流量可以无损地下线掉?

%title插图%num

上图是微服务注册和发行的整个流程,图中有服务消费者和服务提供者,服务提供者分别有 B1、B2 两台实例,服务消费者分别有 A1、A2 两台实例。

B1、B2 把自己注册到注册中心,消费者从注册中心刷新服务列表,发现服务提供者 B1、B2,正常情况下,消费者开始调用 B1 或者 B2,服务提供者 B 需要发布新版本,先对其中一个节点进行操作,如 B1,首先停止 Java 进程,服务停止过程又分为主动销毁和被动销毁,主动销毁是准实时的,被动销毁的时间由不同的注册中心决定,*差的情况可能需要一分钟。

如果应用是正常停止,Spring Cloud 和 Dubbo 框架的 ShutdownHook 能正常被执行,这一步的耗时基本上是可以忽略不计的。如果应用是非正常停止,比如说直接 Kill-9 的一个停止,或者是 Docker 镜像构建的时候,Java 进程不是一号进程,且没有把 Kill 信号传递给应用的话,那么服务提供者不会主动去注销节点,它会等待注册中心去发现、被动地去感知服务下线的过程。

当微服务注册中心感知到服务下线以后,会通知服务消费者其中一个服务节点已下线,这里有两种方式:注册中心的推送和消费者的轮巡。注册中心刷新服务列表,感知到提供者已经下线一个节点,这一步对于 Dubbo 框架来说不存在,但对于 Spring Cloud 来说,它*差的刷新时间是 30 秒。等消费者的服务列表更新以后,就不再调用下线节点 B。从第 2 步到第 6 步的过程中,注册中心如果是 Eureka,*差的情况需要消耗两分钟;如果是 Nacos,*差的情况需要消耗 50 秒。

在这个时间内请求都有可能出现问题,所以发布的时候会出现各种报错。

%title插图%num

经过上面的分析,在传统的发布流程中,客户端有一个服务端调用报错期,这是由于客户端没有及时感知到服务端下线的实例造成的,这种情况主要是因为服务提供者借助微服务,通知消费者来更新服务提供的列表造成的。

%title插图%num

那能否绕过注册中心,服务提供者直接通知服务消费者?答案是肯定的。SAE 做了两件事情,*,服务提供者在应用发布前,会主动向服务注册中心注销应用,并将应用标记为已下线状态,将原来停止进程阶段的注销变成了 preStop 阶段注销进程。

在接收到服务消费者的请求时,首先会正常处理本次请求,并且通知服务消费者此节点已经下线,在此之后消费者收到通知后,会立即刷新自己的服务列表,在此之后服务消费者就不会再把请求发到服务提供者 B1 的实例上。

通过上面这个方案,就使得下线感知时间大大缩短,从原来的分钟级别做到准实时的,确保你的应用在下线时能够做到业务无损。

3)基于标签的灰度发布

%title插图%num

发布策略分为分批发布和灰度发布,如何实现流量的灰度?从上面的架构图中可以看到,在应用发布之前,要配置一个灰度规则,比如按 uid 的取模余值 =20 来作为灰度流量的规则,当应用发布的时候,会对已发布的节点标识为一个灰度的版本,在这样的情况下,当有流量进来时,微服务网关和消费者都会通过配置中心拿到在治理中心配置的灰度规则。

消费者的 Agent 也会从注册中心拉取它所依赖的服务的一些信息,当一个流量进到消费者时,会按照灰度规则来做匹配,如果是灰度的流量,它会转化到灰度的机器上;如果是正常流量,它会转到正常的机器上,这是基于标签实现的灰度发布的具体逻辑。

3. 运行态实践

1)强大的应用监控 & 诊断能力

%title插图%num

运行态的实例,服务的运行过程中会出现这样或者那样的问题,怎么去排查和解决它?

排查和解决的前提是必须具有强大的应用监控能力和诊断能力,SAE 集成了云产品 ARMS,能够让跑在上面的 Java 微服务看到应用的调用关系拓扑图,可以定位到你的 MySQL 慢服务方法的调用堆栈,进而定位到代码级别的问题。

比如一个请求响应慢,业务出现问题,它可以定位到是哪个请求、哪个服务、服务的哪行代码出现了问题,这样就能为解决问题带来很多便利。总的来说,就是我们要先有监控报警的能力,才能帮助我们更好地诊断服务运营过程中的问题。

2)故障隔离和服务恢复

上面说到我们通过监控、报警来排查、解决遇到的问题,那我们的系统能否主动去做一些事情呢?SAE 作为一个 Serverless 平台,具备很多自运维的能力,下图中有两个场景:

%title插图%num

  • 场景1:某应用运营过程中,某几台机器由于磁盘满或者宿主机资源争抢,导致 load 很高或网络状态差,客户端出现调用超时或者报错。

面对这种情况,SAE 提供了服务治理能力,即离群摘除,它可以配置,当网络超时严重或者后端服务 5xx 报错达到一定比例时,可以选择把该节点从消费端服务列表中摘除,从而使得有问题的机器不再响应业务的请求,很好地保证业务的 SLA。

  • 场景2:某应用运行过程中,因突发流量导致内存耗尽,触发 OOM。

这种情况下,通过 SAE 这种 Serverless 应用引擎,节点在配置健康检查以后,节点里的容器是可以重新拉起的,可以做到快速对进程进行恢复。

3)精准容量+限流降级+*致弹性

%title插图%num

基于 Serverless Paas 平台 SAE 和其他产品的互动,来达到整个运维态的闭环。

用户在使用的时候,可以运用 PTS 压测工具构造场景,然后得出来一些阈值。比如可以对流量高峰所需要消耗的资源进行预估,这时就可以根据这些阈值设计弹性策略。当业务系统达到请求比例时,就可以按照所设置的弹性策略来扩缩容自己的机器。

扩缩容在时间上,有可能还跟不上处理大批量的请求,这时可以通过和 AHAS 的互动,配置限流降级的能力。当有突发大流量时,首先可以用 AHAS 的能力把一些流量挡在门外,然后同时触发 SAE 上应用的扩容策略去扩容实例,当这些实例扩容完成之后,整个机器的平均负载会下降,流量又重新放进来。从突发大流量到限流降级再到扩容,*后到流量达到正常状态,这就是“精准容量+限流降级+*致弹性”的*佳实践模型。

%title插图%num

总结

本文首先按照提出问题、解决问题的思路,阐述微服务在开发、发布和运行态是如何解决问题的;再介绍如何通过 Serverless 产品和其他产品的互动,从而实现精准流量、限流降级和*致弹性。

  • 开发测试态
    • 通过注册中心多租户和网络环境的隔离,并提供环境级别的能力;
    • 通过云端联调技术来快速调式本地变更;
    • 如果 IDE 插件快速部署本地变更。
  • 发布态
    • 运维平台针对应用发布需要具备可灰度、可观测、 可回滚;
    • 通过 MSE agent 能力实现服务无损下线;
    • 通过标签路由提供了线上流量灰度测试的能力。
  • 运行态
    • 建立强大应用监控和诊断能力;
    • 对服务质量差的节点具备离群摘除能力;
    • 对已经不工作的实例通过配置健康检查能够做到实例重启恢复业务;
    • 提供了精准容量+限流降级+*致弹性模型。

 

鸟瞰微服务、云原生、容器和无服务器(一)

本系列文章希望对现代软件行业的一些关键主题,即微服务、云原生应用程序、容器和无服务器应用程序提供实践性支持,并涵盖这些技术的实际优点和缺点。

这一系列文章由《Golang Cloud Native编程》一书的作者Mina Andrawos撰写——该书为云原生微服务提供了实用技术和架构模式。他还是《 掌握Go编程》和《现代Golang编程》视频课程的作者。

本系列文章希望对现代软件行业的一些关键主题,即微服务、云原生应用程序、容器和无服务器应用程序提供实践性支持,并涵盖这些技术的实际优点和缺点。

微服务

微服务架构作为构建现代软件应用程序的强大方法赢得了业内认同。什么是微服务?微服务将软件应用所需的功能分成多个独立的小软件服务。这些微服务中的每一个都负责一个专门的任务。为了使这些微服务一起工作以形成一个大型可扩展应用程序,它们必须在多个服务器之间进行通信和交换数据,这被称为水平扩展。

每个服务都可以部署在具有专用资源的不同服务器上,也可以部署在不同的容器中。这些服务可以用不同的编程语言编写,实现更大的灵活性,并允许每个团队专注于单个服务,*终得到质量更高的应用程序

使用微服务的另一个显著优势是易于持续交付,或经常和随时部署软件的能力。微服务使得持续交付更容易,因为部署到一个微服务的新功能不太可能影响其他微服务。

云原生应用

 


微服务架构非常适合云原生应用程序——从云计算基础开始构建的应用程序。如果设计为可在分布式和可伸缩的基础设施上进行部署,那么应用程序就是云原生的。

例如,构建具有冗余微服务架构的应用程序使应用程序成为云原生的,因为此架构允许应用程序以分布式的方式进行部署,从而使其可扩展且几乎总是可用。云原生应用程序不需要总是部署到公有云(如AWS),也可以部署到分布式云类基础设施。

实际上,使应用程序完全云原生的原因不仅仅在于使用微服务。你的应用程序应该采用持续交付,能够在不中断的情况下持续向生产应用程序提供更新。你的应用程序还应该使用消息队列和容器等技术。

云原生应用程序假定可以访问众多的服务器节点,可以访问预先部署的软件服务,如消息队列或负载均衡器,易于与持续交付服务集成等。

如果你将云原生应用程序部署到AWS或Azure等商业云,你的应用程序可以选择使用只有在云中才有的软件服务。例如,DynamoDB是一个功能强大的数据库引擎,只能在AWS上用于生产应用程序。另一个例子是Azure中的DocumentDB数据库。还有像Amazon Simple Queue Service(SQS)这样的云消息队列,可用于允许AWS云中微服务之间的通信。

如前所述,云原生微服务应该被设计为允许服务之间的冗余。如果我们以事件预订应用程序为例,应用程序将如下所示:

%title插图%num

每个微服务将分配多个服务器节点,从而部署冗余的微服务架构。如果主节点或服务因任何原因失败,则辅助节点可以接管,以确保云原生应用的持久可靠性和可用性。这种可用性对于电子商务平台等容错应用程序至关重要,因为电子商务平台的停机时间会导致收入损失。

在微服务和云计算领域一个值得一提的工具是Prometheus。Prometheus是一个开源的系统监控和警报工具,可用于监控复杂的微服务架构,并在需要采取行动时发送警报。Prometheus*初由SoundCloud创建来监控其的系统,现在逐渐发展为一个独立的项目,并成为CNCF的一部分。

容器

一个容器就是将一些软件封装在一个孤立的用户空间或“容器”中的想法。例如,一个MySQL数据库可以在一个容器内隔离,其中有所需要的环境变量和配置。默认情况下,容器外部的软件将不会看到容器内包含的环境变量或配置。同一个本地虚拟机、云虚拟机或硬件服务器上可以存在多个容器。

容器提供了在同一台计算机上运行众多独立软件服务及其所有配置、软件依赖关系、运行时、工具和附带文件的功能。在云环境中,这种能力转化为成本和功夫的节省,因为为每个微服务供应和购买服务器节点的需求会减少( 不同的微服务可以部署在同一主机上而不会相互干扰)。容器与微服务架构相结合,成为构建现代、便携、可扩展且经济高效软件的强大工具。在生产环境中,需要多个服务器节点和众多容器来实现可扩展性和冗余。

容器为云原生应用程序增加了更多优势。使用容器,你可以将微服务及其所需的所有配置、依赖关系和环境变量移动到全新的服务器节点上,而无需重新配置环境,这样就实现了强大的可移植性。

由于软件容器技术的强大和普及,一些新的操作系统,如CoreOS或Photon OS,从一开始就为容器的主机而构建。

Docker是软件行业*受欢迎的软件容器项目之一。思科、谷歌和IBM等公司在其基础设施和产品中使用Docker容器。

Kubernetes是软件容器领域的另一个值得关注的项目。Kubernetes是一个允许自动化部署、管理和伸缩容器的工具。为了便于管理其容器,谷歌建立了Kubernetes。它提供了一些强大的功能,例如容器之间的负载均衡,重启失败的容器以及编排容器使用的存储。

云原生计算的缺点

指出这些技术的缺点非常重要。严重依赖微服务的一个显著缺点是,随着数量和范围的扩大,*终它们可能变得太复杂而无法管理。有一些方法可以缓解,如利用诸如Prometheus的监视工具来检测问题和诸如Docker之类的容器技术避免污染主机环境并避免过度设计服务。但是,这些方法需要付出努力和时间。

对于云原生应用程序,如果需要迁移部分或全部应用程序,则会面临一些挑战。这有多种原因,具体取决于应用程序的部署位置。

一个原因是如果你的云原生应用程序部署在像AWS这样的公有云上,云原生API不是跨云平台的。例如,应用程序中使用的DynamoDB数据库API仅适用于AWS,而不适用于Azure,因为DynamoDB仅属于AWS。这一API也不会在本地环境中工作,因为DynamoDB只能在生产环境中使用AWS。

另一个原因是,构建一些云原生应用程序时会做出一些假设,例如在需要时实际上可以使用无限数量的服务器节点,并且可以快速提供新的服务器节点。但是在需要购买服务器、网络硬件和布线的本地数据中心环境中,这些假设有时难以保证。

就容器而言,由于与管理不断扩大微服务数量相同的原因,管理容器有时会变得相当复杂。随着容器或微服务的规模不断扩大,需要有一种机制来确定每个容器或微服务的部署位置、目的是什么以及它们需要什么资源才能继续运行。

无服务器应用

无服务器架构是一种新的软件架构范式,已通过AWS Lambda服务推广。为了完全理解无服务器应用,我们首先定义功能即服务(FaaS)。这是一个云提供商(如亚马逊或甚至本地软件,如Fission.io或funktion)提供服务的想法,用户可以请求一个远程运行的功能以执行非常特定的任务,然后在功能结束后,功能结果会返回给用户。不需要维护服务或有状态数据,功能代码由用户提供给运行该功能的服务。

利用无服务器架构设计合理的生产应用程序的想法是,不是构建多个持续运行的微服务来执行单个任务,而是构建一个有更少的与FAAS结合的微服务的应用来完成不需要服务持续运行的任务

FAAS的构造比微服务更小。例如,对于之前介绍的事件预订应用程序,有多个微服务覆盖不同的任务。如果我们使用无服务器应用模型,那么这些微服务中的一些将被替换为许多服务于其目的的功能。例如,下面的图表展示了使用无服务器架构的应用程序:

%title插图%num

个现有的微服务。

这种单体的应用程序将适用于小到中等负载。它可以在单个服务器上运行,连接到单个数据库,并且可能会用相同的编程语言编写。

那么,如果业务繁多以及数十万或数百万用户需要处理,会发生什么?*初,短期解决方案是确保运行应用程序的服务器具有强大的硬件规格,以承受更高的垂直伸缩负载(增加硬件规格的方法包括用RAM和硬盘驱动器运行繁重应用程序)。通常情况下,随着应用程序的负载持续增长,这种方法不可持续。

单体应用的另一个挑战是由于仅限于一种或两种编程语言而导致的不灵活性。这种不灵活性会影响应用程序的整体质量和效率。例如,node.js是用于构建Web应用程序的流行JavaScript框架,而R在数据科学应用程序中很受欢迎。一个单体的应用程序很难同时使用这两种技术,而在微服务应用程序中,你可以简单地构建用R编写的数据科学服务和用Node.js编写的Web服务。

单体应用的第三个大挑战是协作。例如,在事件预订应用程序中,修改在单个前端用户接口层中的bug可能会影响其他应用程序,如搜索、事件和预订处理程序。

如果你要创建事件应用程序的微服务版本,它将采用以下形式:

%title插图%num

此应用程序将能够在多个服务器之间进行水平缩放。每个服务都可以部署在具有专用资源的不同服务器上,或者部署在不同的容器中。

微服务如何与云原生应用程序一起工作?


微服务架构非常适合云原生应用程序。云原生应用程序简单地定义为从底层构建并运行在云平台上的应用程序。云平台具有许多优点,例如在免去IT硬件基础设施规划痛苦的情况下,就可以立即获得多个服务器节点。在微服务架构中构建应用程序是开发可扩展的云原生应用程序的重要一步。

云原生应用程序的另一个功能是利用只有在云上才有的软件服务。例如,DynamoDB是一种功能强大的数据库引擎,只能在AWS上用于生产应用程序。另一个例子是Azure中的DocumentDB数据库。还有云原生消息队列,如Amazon Simple Queue Service(SQS),可用于允许AWS云中微服务之间的通信。

云原生微服务也可以设计为允许服务之间的冗余。如果以事件预订应用程序为例,该应用程序将如下所示:

%title插图%num

由于获得新的服务器节点不是硬件基础设施的挑战,因此可以为每个微服务分配多个服务器节点。如果主节点或服务出于任何原因失败,辅助节点可以接管,从而确保云本机应用的持久可靠性和可用性。这里的关键是可用于容错应用程序,如电子商务平台,其中停机时间会导致收入损失。

微服务云原生应用程序将微服务的优势与云计算的优势相结合,为开发人员、企业和创业公司提供巨大的价值。

另一个显著优势(除了可用性和可靠性)是持续交付。微服务使持续交付更容易的原因是因为部署到一个微服务的新功能不太可能影响其他微服务。

结论

云计算为开发高效、可扩展和可靠的软件开辟了道路。在这里,我们介绍了云计算领域的一些重要概念,如微服务、云原生应用和无服务器应用。

在设计应用程序时,架构师必须选择是构建单体应用程序、微服务云原生应用程序或是无服务器应用程序。

在本系列的第二篇文章中,我们将深入介绍云原生应用程序和容器,以及它们的缺点。本系列的第三部分将详细介绍无服务器应用程序,并展示如何将以上三者结合在一起。

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速