1微服务发展微服务架构的发展伴随着互联网行业的飞速增长和技术的日新月异。起初,企业为了提升应用的灵活性和可维护性,开始尝试将单体应用拆分为多个服务,这便是面向服务的架构(SOA)的兴起。然而,此时的拆分粒度仍然相对较大,并没有完全实现服务的细粒度划分。随着Docker和容器技术的兴起,微服务架构真正得到了发展的助力。容器技术为微服务提供了轻量级的隔离环境,使得微服务更容易部署和管理。每个微服务都可以独立运行、扩展和更新,大大提高了系统的灵活性和可维护性。进入云原生时代,伴随着Kubernetes等技术的兴起,微服务架构得到了更为完善的支撑。云原生技术为微服务提供了自动化部署、管理和监控的能力,
1介绍互联网行业内在进行微服务高可用建设的时候,不可避免的要考虑一个事情,如何部署才能提高系统的可用性和稳定性。所以一般情况下,不会只部署一个机房,这样无法完全避免一个机房内网络故障、机房断电,遭受区域网络攻击的风险。所以有了多机房建设的,但是多机房建设同样也有问题,他们无法近距离的部署,如果部署区域太近(如在同一个城市),依然无法避免区域断电、洪灾、水灾、火灾、地震等灾难情况的发生。所以业内的大型互联网企业,会耗费大量的人力物理在基础设施建设方面。通过资源的冗余来保证服务的可持续性,这种其实就是资源博弈的过程。2高可用架构模型2.1两地安中心两地三中心是一种容灾解决方案,指的是一个生产中心、
1介绍大家都知道,一个主机(或称为节点)可以部署多个Pod,Pod作为Kubernetes中的最小部署单元。是一组一个或多个紧密关联的容器的集合,它们共享相同的网络命名空间和存储卷。一般来说,服务上云之后,我们的服务会配置anti-affinity(反亲和调度),他有哪些利弊权衡呢:affinity可以实现就近部署,增强网络能力实现通信上的就近路由,减少网络的损耗。如同一个BCC聚类多个实例Pod。anti-affinity反亲和性主要是出于高可靠性考虑,尽量分散实例Pod,某个节点故障的时候,对应用的影响只是N分之一或者单实例。所以,最终的部署结构可能是:同一个服务(如ServiceA)的实
1介绍在互联网电商场景中,我们经常会遇到有计划的流量洪峰,比如双11、618购物节,积分竞拍和定时抢购的疯狂场景。这种是在预期内的,知道会发生并有一定的准备。而那些预期之外的突发流量异常,才是真正给我们带来挑战的部分,比如:硬件故障:如服务器宕机,机房断电,光纤被挖断等。缓存击穿:一般发生在应用重启导致的缓存失效,以及短时间内大量缓存过期失效时。大量的无法命中,使请求直击后端服务,造成服务提供者超负荷运行,引起服务不可用。程序BUG:如程序逻辑导致内存泄漏;JVM长时间FullGC等。新功能上线:未经过评估,导致非预期流量上涨(某次功能上线,未进行有效的容量评估,导致ws长连接翻数倍)。单个服
1介绍在复杂的互联网场景中,不可避免的会因为一些内在或者外在的因素,导致出现请求超时的情况。而典型的业务超时场景主要有如下:网络延迟或者抖动或者丢包,从而导致响应时间变长。容器甚至云主机资源瓶颈情况:如CPU使用率过高、内存使用是否正常、磁盘IO压力情况、网络时延情况等资源使用情况异常,也可能导致响应时间变长。负载均衡性问题:多实例下分配的流量不均衡,目前看云基础场景,这个情况不多见。突发洪峰请求:大部分对内的业务基本不存在非预期的流量,突发洪峰请求主要还是程序的调用不合理或者程序bug(内存泄露、循环调用、缓存击穿等)。单个Pod实例,长耗时容易造成队列堆积,对资源损耗很大,快速的释放或者调
1背景在复杂的互联网场景中,不可避免的会出现请求失败的情况。从程序的的响应结果来看,一般是Response返回5xx状态的错误;从用户的角度去看,一般是请求结果不符合预期,即操作失败(如转账失败、下单失败、信息获取不到等)。偶发的不可避免的5xx请求错误,产生的原因有很多种,比如:网络延迟或者抖动服务器资源不足(CPU、内存走高、连接池满)服务器故障符合某些特定条件下的服务程序bug(大都非必现)2系统稳定性等级划分大部分服务容忍低频、偶发的5xx错误,并使用可用性级别来衡量系统的健壮性,级别系数越高,健壮性越好,如下:等级描述故障时长(年)可用行等级基本可用性87.6h99%较高可用8.8h
1微服务的基本流量策略微服务提供了一些技术来实现对微服务的流量的管理,其中最典型的就是对流量进行拆分和转发。具体体现在金丝雀发布(灰度发布)、ABTesting以及流量染色等策略方案上。2流量策略实现流控的本质云原生基础场景下,如果想要实现流控和调度,需要具备以下几个条件:请求的流量中,需要附带某些特征,如流量的请求的Header、Cookies、queryParams等中带有某些信息。部署在kubernetes上的服务(svc)的实例(pod),打上版本标签,如label:default、label:version1、label:version2等。在云原生基础组件(如Service-Mes
1微服务的基本流量策略微服务提供了一些技术来实现对微服务的流量的管理,其中最典型的就是对流量进行拆分和转发。具体体现在金丝雀发布(灰度发布)、ABTesting以及流量染色等策略方案上,下面会进行详细的介绍。2价值和必要性★价值驱动:支持蓝绿发布、金丝雀发布,无需停服也能保证发布的无缝衔接,提高了服务整体的SLA。全链路的ABTesting,保证不同特征类型的用户可以在独立的链路通道上测试、使用、实验、生产。大幅降低早期为实现灰度而做多服务的资源(时间、服务器资源)损耗。★业务视角:实现所有业务分级发布、扩散发布的能力,保证发布的渐序性。比如上线一个新功能,首先在小范围发布,观察一段时间之后在
1前言在《微服务系列》中,我们讲过很多限流,熔断相关的知识。老生长谈的一个话题,服务的能力终归是有限的,无论是内存、CPU、线程数都是,如果遇到突如其来的峰量请求,我们怎么友好的使用限流来进行落地,避免整个服务集群的雪崩。峰量请求主要有两种场景:1.1突发高峰照成的服务雪崩如果你的服务突然遇到持续性的、高频率的、不符合预期的突发流量。你需要检查一下服务是否有被错误调用、恶意攻击,或者下游程序逻辑问题。这种超出预期的调用经常会造成你的服务响应延迟,请求堆积,甚至服务雪崩。而雪崩会随着调用链向上传递,导致整个服务链的崩溃,对我们的系统造成很大的隐患。1.2超出预期值的流量洪峰如果你的商城或者平台搞
1介绍前面的章节,我们学习了微服务中对熔断降级的原理,参考这篇《服务治理:熔断、降级、限流》。了解了固定窗口算法、滑动窗口算法、漏桶原理和令牌桶原理,本文对Hystrix做进一步的分析。Hystrix是Netflix开源的一款具备熔断、限流、降级能力的容错系统,设计目的是将应用中的系统访问、多链路服务调用、第三方依赖服务的调用,通过流量资源控制的方式隔离开。避免了在分布式系中的某个服务故障沿着调用链向上传递,出现整体的服务雪崩,并以此提升系统的稳定性和健壮性。1.1Hystrix是用来解决哪些问题的?对所依赖的服务的延迟和故障进行容错(防护+控制)对服务的故障进行妥善的处理对延迟过久的请求进行
1为什么熔断限流分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务。如下图,对于同步调用,当库存服务不可用时,商品服务请求线程被阻塞,当有大批量请求调用库存服务时,最终可能导致整个商品服务资源耗尽,无法继续对外提供服务。并且这种不可用可能沿请求调用链向上传递,这种现象被称为雪崩效应。1.2雪崩效应常见场景硬件故障:如服务器宕机,机房断电,光纤甚至专线被破坏等。流量激增:如异常流量,线上活动导致的流量激增,重试导致流量放大等。缓存穿透:缓存服务重启,导致大量缓存同时失效时。重建缓存或者大量的请求无法命中缓存,会直接投向数据库,导致服务和数据层压力骤增甚至雪崩。程序漏洞:如
1微服务带来的挑战在第2篇《微服务2:微服务全景架构》中,我们曾经分析过微服务化后所面临的挑战,有过如下的结论:1.1分布式固有复杂性微服务架构是基于分布式的系统,而构建分布式系统必然会带来额外的开销。性能:分布式系统是跨进程、跨网络的调用,受网络延迟和带宽的影响。可靠性:由于高度依赖于网络状况,任何一次的远程调用都有可能失败,随着服务的增多还会出现更多的潜在故障点。因此,如何提高系统的可靠性、降低因网络引起的故障率,是系统构建的一大挑战。分布式通信:分布式通信大大增加了功能实现的复杂度,并且伴随着定位难、调试难等问题。数据一致性:需要保证分布式系统的数据强一致性,即在C(一致性)A(可用性)
1说明上一节我们我们详细学习了RPC的概念和原理,以及它能够提供的能力。也对目前业内主流的RPC的框架有了一定的了解。接下来以Dobbo为例子,来学习下怎么使用RPC框架来进行服务之间的通信。2Dubbo框架功能介绍ApacheDubbo是一款分布式微服务开发框架,它提供了RPC通信与微服务治理两大关键能力。这意味着,使用Dubbo开发的微服务,将具备相互之间的远程发现与通信能力,同时利用Dubbo提供的丰富服务治理能力,可以实现诸如服务发现、负载均衡、流量调度等服务治理诉求。同时Dubbo是高度可扩展的,用户几乎可以在任意功能点去定制自己的实现,以改变框架的默认行为来满足自己的业务需求。2.
1什么是RPC通信RPC:RemoteProcedureCallProtocol,指的是远程过程调用协议,一般使用在分布式业务或者微服务架构风格中。即一个节点通过网络调用的方式来请求另一个节点提供的服务的过程,也可以简单的理解为client访问server上提供的函数(像调用本地函数一样,去调用一个远端服务)。2RPC通信详解2.1RCP角色和职能在RPC框架中主要有三个角色:Provider、Consumer和Registry。如下图所示:节点角色说明,这边看起来,跟其他的服务注册与发现框架原理差不多(如Eureka、Consul):Service(provider):暴露服务的服务提供方。
1概述回顾下前面几篇关于微服务的介绍,我们可以了解到从当单体系统到微服务,再到服务网格的演进过程。那单体系统和微服务相比,有哪些区别呢,下面是对功能性的对比? 单体系统 微服务系统 单体系统 微服务系统 程序、数据、配置集中管理按照功能拆分、微服务化、松耦合开发效率低下分模块快速迭代发布全量,启动慢平滑发布,快速启动可靠性差熔断、限流、降级,超时重试,异常离群服务内直接调用轻量级通信技术单一跨语言微服务有诸多的有利条件,但是如果微服务的粒度比较细(按照业务功能拆分),则他们之间服务调用就会比较复杂,链路会比较长。比如上图中,我们按照职能将服务进行了拆分,这时候从不同的客户端(如Web、A
1服务注册中心前面我们对业内几种比较常见的注册中心做了介绍:Eureka、Zookeeper、Consul、Etcd。并且在各个指标上做了对比:注册方式(watch\polling)、健康检查、雪崩保护、安全与权限,以及在SpringCloud、Dubbo、Kubernets上的支持程度。方便我们在不同的场景下做正确的技术选型。 指标 Eureka Zookeeper Consul Etcd 指标 Eureka Zookeeper Consul Etcd 一致性协议APCP(Paxos算法)CP(Raft算法)CP(Raft算法)健康检查TTL(TimeToLive)TCPK
1微服务的注册与发现我们前面在全景架构中对服务注册与发现做了大致的说明,本章我们着重详细说明微服务下注册与发现的这个能力。微服务注册与发现类似于生活中的"电话通讯录"的概念,它记录了通讯录服务和电话的映射关系。在分布式架构中,服务会注册进去,当服务需要调用其它服务时,就这里找到服务的地址,进行调用。步骤如下:1、你先要把"好友某某"记录在通讯录中。2、拨打电话的时候通过通讯录中找到"好友某某",并拨通回电话。3、当好友某某电话号码更新的时候,需要通知到你,并修改通讯录服务中的号码。从这个过程中我们看到了一些特点:1、把"好友
前面我们学习了微服务的全景架构,了解到相对于传统单体架构,微服务的优势,以及系统服务化的发展趋势。对于新启动的项目,我们在权衡之后可以大方的使用微服务架构。但其实大部分情况下,我们还要去维护一些以前研发的单体系统,这些系统可能因为访问流量的膨胀、功能的扩张而显得非常臃肿不堪,急需要向微服务架构迁移。1微服务迁移准备1、需对业务充分了解,这是服务拆分,通信设计,资源整合的必要前提。2、适应微服务架构设计原则:小版本,高速迭代。3、快速的环境提供能力:依赖于云计算、容器技术,快速交付环境。4、服务合理拆分:需符合团队结构或能逆向影响,能对组织架构进行微调并划分职责。(康威定律和逆康威定律)5、基本
1微服务优势与挑战1.1微服务的优势1.1.1单一职责微服务架构中的每个节点高度服务化,都是具有业务逻辑的,符合高内聚、低耦合原则以及单一职责原则的单元,包括数据库和数据模型;不同的服务通过“管道”的方式灵活组合,从而构建出庞大的系统。1.1.2轻量级通信通过RESTAPI模式或者RPC框架,事件流和消息代理的组合相互通信,实现服务间互相协作的轻量级通信机制。1.1.3独立性在微服务架构中,每个服务都是独立的业务单元,与其他服务高度解耦,只需要改变当前服务本身,就可以完成独立的开发、测试、部署、运维。1.1.4进程隔离在微服务架构中,应用程序由多个服务组成,每个服务都是高度自治的独立业务实体,
1传统单体系统介绍在很多项目的业务初期阶段,高速迭代上线是首要考虑的事情,对后期的容量预估、可扩展性和系统健壮性、高可用一般没有那么重视。但随着业务的发展,用户量、请求量的暴增,发现原来的单体系统已经远远不满足需求了,特别是随着互联网整体的高速发展,对系统的要求越来越高。但是物理服务器的CPU、内存、存储器、连接数等资源有限,单体系统能够承受的的QPS也是有限的,某个时段大量连接同时执行操作,会导致web服务和数据库服务在处理上遇到性能瓶颈。为了解决这个问题,伟大的前辈们发扬了分而治之的思想,对大数据库、大表进行分割,可以参考我的《分库分表》,以便实施更好的控制和管理。同时创建多个服务实例,使
在SpringCloud架构体系中,微服务间的通信是基于Feign调用。而在实际使用Feign的过程中我们大概率会面临下面几个问题:Feign客户端放在消费端还是独立一个api层?Feign调用的接口如何要不要进行包装?Feign如何抓取业务生产端的业务异常?这篇文章我们就来一起探讨一下这几个问题,希望看完能对你有所帮助。首先我们先看看Feign的调用方式如何抉择?Feign的调用方式如何选择?总体来说,Feign的调用方式分为两大类:在生产端API中声明Feign客户端如上,消费端服务直接依赖生产端提供的API包,然后通过@Autowired注解注入,就可以直接调用生产者提供的接口。这样做的
前几天有一个看我SpringCloudalibaba系列文章的粉丝私下问我:如何处理jwt失效的问题?修改密码或退出登录后需要将之前的jwttoken失效掉,不允许使用旧token登录系统。我说:很简单呀,咱们直接无为而治,用户退出或修改密码的时候前端直接删除这个token不就完了吗?后端啥都不用管,啥也不用做。他说:别闹,你的每篇文章我都给你一键三连。我当时就被感动了,既然是这样的好读者,我果断答应专门给他写篇文章来分享一下我这个不太成熟的做法,改造一下这个SpringCloudalibaba项目。在正式开始之前,我们先来回顾一下oauth2中token的相关知识。知识回顾众所周知,在OAu
在SpringCloud实战系列文章中曾经介绍过在SpringCloud体系下如何防止前端请求绕过网关直接到达后端微服务,今天我们要反其道而行之,介绍在SpringCloud体系中如何防止内部隐私接口被网关调用。看到这里可能有的同学会有点晕,怎么还有这种业务场景呢,别急,咱们先回顾一下我们的业务场景。“友情提示,这是系列文章,欢迎持续关注!”业务场景客户端通过网关调用OrderService服务获取数据,OrderService通过Feign调用AccountService服务,而当AccountService提供对应的Feign接口后,客户端是可以通过网关直接调用AccountService
前言这篇文章来源于粉丝提出的一个问题:如何解决多环境统一注册中心服务实例乱窜?怎么理解呢?假设现在开发环境的AccountService已经在Nacos中注册了,现在小张需要对它进行修改升级,本地启动AccountService后也注册到了Nacos,但是在调试的时候请求通过网关经常直接跳转到开发环境,这样的话小张就没办法安心debug了。其实这个问题归根结底是如何基于SpringCloudGateway实现灰度发布,通过指定的规则让请求流量到达特定的实例。在SpringCloud2020版本中官方推荐使用SpringCloudLoadBalancer来替换原Ribbon的负载均衡器。所以本篇
前言分布式事务是在微服务开发中经常会遇到的一个问题,之前的文章中我们已经实现了利用Seata来实现强一致性事务,其实还有一种广为人知的方案就是利用消息队列来实现分布式事务,保证数据的最终一致性,也就是我们常说的柔性事务。消息队列实现分布式事务原理首先让我们来看一下基于消息队列实现分布式事务的原理方案。发送消息的服务有个OUTBOX数据表,在进行INSERT、UPDATE、DELETE业务操作时也会给OUTBOX数据表INSERT一条消息记录,这样可以保证原子性,因为这是基于本地的ACID事务。OUTBOX表充当临时消息队列,然后我们在引入一个消息中继(MessageRelay)的服务,由他从O
概述在单体项目中如果我们需要记录操作日志一般会通过如下手段实现:建立一个自定义注解,标注业务操作类型通过AOP组装日志实体,完成日志的收集工作具体实现可以参考如下的文章链接:http://javadaily.cn/articles/2020/05/13/1589330750429.html但是在微服务架构中我们不可能每个服务都写一个自定义注解,再写一个AOP,这很明显违反了Don’trepeatyourself精神。所以这时候我们一般都会建立一个公共的组件,在公共组件中完成日志的收集,后端服务只需要引入这个公共的组件即可。这就是今天文章的内容,独立的业务日志收集组件。SpringBootSta
前面文章咱们对比过网关授权与微服务授权的区别,文章也提到了,如果要实现微服务授权,一般会构建一个独立的资源服务器配置模块,否则每个后端业务都需要进行资源服务器的配置,那本节内容我们就来完成此功能。由于间隔时间较久,建议先阅读下面两篇相关文章回顾一下。SpringCloudAlibaba微服务实战十九-集成RBAC授权SpringCloudAlibaba微服务实战二十八-网关授权VS微服务授权话不多说,我们直接开始代码改造。认证服务器改造首先我们需要改造认证服务器,需要认证服务器在构建用户权限的时候使用的是权限标识字段。对于代码而言只需要UserDetailServiceImpl#loadUse
请求响应日志是日常开发调试定位问题的重要手段,在微服务中引入SpringCloudGateway后我们希望在网关层统一进行日志的收集。本节内容将实现以下两个功能:获取请求的输入输出参数,封装成自定义日志将日志发送到MongoDB进行存储获取输入输出参数首先我们先定义一个日志体@Datapublic class GatewayLog { /**访问实例*/ private String targetServer; /**请求路径*/ private String requestPath; /**请求方法*/ private String requestMeth
在SpringCloud架构中,实现授权功能有两种实现方式:在网关层进行授权由后端微服务自己授权两种方式在此系列文章中都有实现方案,那么问题来了:哪种才是最优方案,哪种方案更合理呢?很抱歉,看完这篇文章你也不一定能得到你想要的答案,因为结论是并没有最优方案,两种方案各有千秋,只有根据自身业务选择对应的方案。本文我们将两种方案做一个简单对比,以便大伙在做方案决策有个选择参考。解决方案对比首先我们看看两种方案实现的原理:如果对具体实现方式有疑问的同学可以参考这篇文章:SpringCloudAlibaba微服务实战十九-集成RBAC授权网关授权基于网关授权我们又叫基于路径匹配器授权,请求在经过网关的
前言使用SpringCloud架构后我们希望所有的请求都需要经过网关才能访问,在不作任何处理的情况下我们是可以绕过网关直接访问后端服务的。如下,我们绕过网关直接访问后端服务也是可以获取到数据的。那我们今天的议题就是如何防止请求绕过网关直接访问后端服务?解决方案我觉得防止绕过网关直接请求后端服务的解决方案主要有三种:使用Kubernetes部署在使用Kubernetes部署SpringCloud架构时我们给网关的Service配置NodePort,其他后端服务的Service使用ClusterIp,这样在集群外就只能访问到网关了。网络隔离后端普通服务都部署在内网,通过防火墙策略限制只允许网关应用