-
引入redis单体
-
引入mysql读写分离
-
引入服务器集群
-
分布式架构
-
- 为什么要使用分布式架构
-
分布式基础组件
-
- Eureka
-
Spring Cloud Config
-
Netflix Zuul(网关)
-
Spring Cloud Bus
-
Feign
-
Netflix Hystrix(熔断)
-
MQ(消息中间件)
-
分布式事务
-
- Mq确保一致性
-
seata(分布式事务)
-
完整的分布式架构
-
总结
-
- 单体服务与分布式服务对比
-
什么时候使用分布式/集群
-
使用分布式注意事项
-
关于组件停更消息
由于疫情的原因,我这里被分配的任务也不是很多,所以就会空闲出一点时间,一般这个时候我都会做自己的事情,比如看看源码、翻翻csdn的博客、然后就是写写博客,正当我沉迷在源码中不能自拔的时候,总监突然来到我旁边,应该是知道了我最近不怎么忙,他轻声的对我说道:最近这段时间大家的任务也不是特别多,空闲时间比较足,你这边能不能做点技术分享什么的,一来可以联络一下同事之间的感情,二来也可以增加同事之间的学习氛围,你觉得怎么样?
听到这个我就知道,我可能干不了自己的事情了,毕竟技术分享也能增加与同事之间的感情,所以我就答应了,但是我愁啊,我该分享一个什么东西呢?如果讲的是java方向,除了java的同事,其他同事听起来就会很吃力,但是讲其他方面,我也不知道能讲什么。。。。。。。。
宝宝心里难受啊,一直在想我要将一个什么样的话题才能让大部分的人都能听得懂并且感兴趣呢?这里面肯定不时出现太多的代码,既然这样,那我就讲一讲分布式的架构演进吧,这个话题既高端,也能让大部分的人听懂,我就是个天才。
好了,不废话了,开始这次的主题,分布式架构的演变。
===================================================================
我记得在我实习的时候用的就是单体的服务,那个时候的架构很简单,前后端分离都还没有,直接jsp+java实现一套项目,整个流程相当简单,就连nginx都没有用到,我们一起来看看当时的架构是什么样的。
没错,就是这么简单,浏览器通过接口访问服务器,服务器通过用户的请求操作数据库,然后再相应给浏览器,这就是一个最简单的单体服务的流程,后来领导觉得直接将端口暴露出去相当危险,我们需要做一层代理,让用户直接通过域名访问。然后流程就被设计成了这样:
这是引入nginx之后的架构图,在这样运行了一段时间之后,突然有一天,领导找到我并说到:你写的代码是不是有问题,为什么一个普通的查询需要很长的时间?基本操作都卡的要死,给你一周时间,赶紧给我解决!
经过我的排查之后发现导致程序变卡的原因是数据库受到了瓶颈,压力太大,承受不住那么大的请求,既然问题找到了,那解决就很简单了,我在程序和数据库之间增加一个中间件:redis,使用它来降低数据库的访问,这样性能自然会得到提升。
舒服,引入redis,并且对代码做了一些优化之后,发现速度上来了,我有可以快乐的写bug了,就这样过去了大概一个月左右,这天我正在和同事讨论一些八卦,突然感觉背后一阵阴风 ,我知道,出事了,没想到是领导又来找我麻烦了,他说由于我们的产品太火了,下载注册人数都几十万了,日活跃人数也是上万,我们现在的这套架构撑不住了,你有没有什么好的建议?我惊讶了一下,我们的产品这么受欢迎吗?于是我和领导说,我们可以将数据做一下读写分离,这样也可以提升一下程序的性能,但是对于现在的情况,就算加了读写分离,作用应该也不大,我们应该将单体多部署几台,提升程序的吞吐量。
这就是将数据库改造成读写分离之后的架构,读操作和写操作分别在不同的库中,这样,查询和写入就不会那么长的时间了,因为再读库中没有写操作,写库中没有读操作,由于我们一般是读的操作比较多,所以这个时候我们我们可以将读库的配置设置的好一点,写库的设置的差一点,均衡分配,但仅仅这样是也是不能支撑那么大流量的,所以这个时候我们还需要将服务器做集群。
这就是我们单体的最终架构,改造完成之后性能确实得到了很大的提升,因为服务做了集群之后,分散了很多的请求,比如一个tomcat能支持的最高并发是200,那现在三个服务就能支持600的并发,性能提升了3倍,最终扩充了多少台服务器我也不清楚,因为这个是运维做的,集群算是做完了,总算可以满足领导的要求了,为了搞定这一套一套的升级,不知道熬了多少夜,看到电脑旁边掉落的那几根头发,我满意的点了点头。
在后面的两个月的时间里,我们再不停的做迭代更新,几乎每周都会有版本上线,两个月过后版本终于稳定下来了,不怎么有更新了,所以又来到了程序猿的空闲时间,同事们每天上班都做着自己的事情,有学习的,有逛淘宝的,有玩游戏的,更夸张的是居然有个同事闲着没事居然去撩产品小姐姐,握草,这是想要自掘坟墓吗?
我们大概空闲了一周的时间左右,我们的技术总监说话了,今天下午3点,所有后端开发人员会议室开会,听到这个消息,我就知道,有活干了,难道是接了新的项目?
到了下午3点,我们来到会议室,只见技术总监已经提前到了,并且屏幕上写着五个大字,看到这5个字,我心里想,该来的还是会来,躲不过去的,那就是:分布式架构。
====================================================================
因为我知道,我们产品注册人数已经高达几十万,以我们现在的架构肯定会有撑不住的一天,这个产品肯定会被重构,并且是以分布式的架构进行重构,果然,今天技术总监就召开了这个会议。
技术总监:我们的产品现在比较火热,不管是注册人数还是日活跃人数都是比较高的,为了让程序能有更好的健壮性,我希望我们可以对这个项目进行重构,以分布式的架构,今天开会就是我们一起来做个技术选型,你们对分布式熟悉吗?
同事A:分布式系统(distributed system)是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。因此,网络和分布式系统之间的区别更多的在于高层软件(特别是操作系统),而不是硬件。
技术总监:嗯,不错,不过这个解释比较官方,还有没有比较通俗易懂的解释?
同事B:分布式将一个大的系统拆分成无数个细微的子系统,让每一个系统都负责一定的职责,他们相互独立,但是又相互联系。
技术总监:哟,不错哦,这个同事可以,晚上加鸡腿,那有人可以举个例子吗?
me:从前有一个有一个饭店,里面只有老板和一个员工,这个员工负责饭店所有的事情,包括但不限于:厨师、服务员、收银员、清洁工等,在炒菜的时候就不能去收钱,在打扫卫生的时候就不能炒菜,这个员工干了一个月之后,突然有一天,他病倒了,餐厅的生意就停滞了,这个时候老板就想到了一个人不行,那我多招几个人,一个人负责一个职位,这样即使某个人请假或者离职了,对我的生意影响不是很大,比如:清洁工离职了,虽然没有人打扫卫生,但是这并不影响我开门做生意,分布式就是这个道理。
技术总监:这个例子讲的不错,你晚上不用加班了,如果你要是能画一个分布式的基础图出来,我今晚请大家撸串。
me:我专治各种不服,于是我就给技术总监“上了一课”,请看图:
技术总监: 不错,画的很好,但是你们知道我们为什么要将单体的服务重构为分布式吗?答对有鸡腿。
同事C:
-
Spring Cloud专注于提供良好的开箱即用经验的典型用例和可扩展性机制覆盖。
-
分布式/版本化配置
-
服务注册和发现
-
路由
-
service - to - service调用
-
负载均衡
-
断路器
-
分布式消息传递
这是分布式的优点,这样看起来可能比较抽象,举个例子来说,对于单体服务来说,如果我想更新订单中的某个功能,我是不是需要重启整个服务,这个时候就会导致整个项目都处于不可用状态,或者在处理订单的时候由于程序代码写的有问题,导致死锁了,这个时候也会导致整个服务处于宕机专改,容错率很差,但是分布式不同,如上图所示,订单服务、售后服务、用户服务都是独立的服务,如果需要更新订单服务或者订单服务发生死锁,受影响的只会是订单服务,售后服务与用户服务还是可以正常工作的,这就是分布式相对单体来说最大的优势之一。
技术总监:想不到我们这个团队人才辈出啊,不错不错,看来我都没有讲下去的必要了啊,大家对分布式都相当熟悉了啊,那分布式架构存在缺点或者不足吗?
同事D:
这是我平时刷博客的时候看到的,觉得总结的不错,这张图出自:什么是分布式系统!以及分布式系统架构的优缺点!
技术总监:既然大家对分布式都这么熟悉了,那我也就不在多说了,我们接下来直接来说说关于分布式组件的选型吧,大家有什么意见都可以提出来,首先谁来说一下分布式组件都有哪些?请开始你们的表演。
同事E:那我就不客气了,由于我们都是对springcloud比较熟悉,现在他也是比较主流,那我介绍一下cloud的基础组件吧。
-
Spring Cloud Config:配置管理工具包,让你可以把配置放到远程服务器,集中化管理集群配置,目前支持本地存储、Git以及Subversion。
-
Spring Cloud Bus:事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与Spring Cloud Config联合实现热部署。
-
Eureka:云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。
-
Hystrix:熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。
-
Zuul:Zuul 是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门。
-
Archaius:配置管理API,包含一系列配置管理API,提供动态类型化属性、线程安全配置操作、轮询框架、回调机制等功能。
-
Consul:封装了Consul操作,consul是一个服务发现与配置工具,与Docker容器可以无缝集成。
-
Spring Cloud for Cloud Foundry:通过Oauth2协议绑定服务到CloudFoundry,CloudFoundry是VMware推出的开源PaaS云平台。
-
Spring Cloud Sleuth:日志收集工具包,封装了Dapper和log-based追踪以及Zipkin和HTrace操作,为SpringCloud应用实现了一种分布式追踪解决方案。
-
Spring Cloud Data Flow:大数据操作工具,作为Spring XD的替代产品,它是一个混合计算模型,结合了流数据与批量数据的处理方式。
-
Spring Cloud Security:基于spring security的安全工具包,为你的应用程序添加安全控制。
-
Spring Cloud Zookeeper:操作Zookeeper的工具包,用于使用zookeeper方式的服务发现和配置管理。
-
Spring Cloud Stream:数据流操作开发包,封装了与Redis,Rabbit、Kafka等发送接收消息。
-
Spring Cloud CLI:基于 Spring Boot CLI,可以让你以命令行方式快速建立云组件。
-
Ribbon:提供云端负载均衡,有多种负载均衡策略可供选择,可配合服务发现和断路器使用。
-
Turbine:Turbine是聚合服务器发送事件流数据的一个工具,用来监控集群下hystrix的metrics情况。
-
Feign:Feign是一种声明式、模板化的HTTP客户端。
-
Spring Cloud Task:提供云端计划任务管理、任务调度。
-
Spring Cloud Connectors:便于云端应用程序在各种PaaS平台连接到后端,如:数据库和消息代理服务。
-
Spring Cloud Cluster:提供Leadership选举,如:Zookeeper, Redis, Hazelcast, Consul等常见状态模式的抽象和实现。
-
Spring Cloud Starters:Spring Boot式的启动项目,为Spring Cloud提供开箱即用的依赖管理。
我们常用的组件:Spring Cloud Config、Spring Cloud Bus、Hystrix、Zuul、Ribbon、Feign。
技术总监:
不错,组件分析的不错,但是你的讲解比较官方,下面我们来一个一个的讲解一下我们经常使用的这些组件。
Eureka
Eureka属于Spring Cloud Netflix下的组件之一,主要负责服务的注册与发现,何为注册与发现?在刚刚我们分析的分布式中存在这一个问题,那就是订单服务与用户服务被独立了,那么他们怎么进行通信呢?比如在订单服务中获取用户的基础信息,这个时候我们需要怎么办?如果按照上面的架构图,直接去数据库获取就可以了,因为服务虽然独立了,但是数据库还是共享的,所以直接查询数据库就能得到结果,如果我们将数据库也拆分了呢?这个时候我们该怎么办呢?有人想到了,服务调用,服务调用是不是需要ip和端口才可以,那问题来了,对于订单服务来说,我怎么知道用户服务的IP和端口呢?在订单服务中写死吗?如果用户服务的端口发生改变了呢?这个时候Eureka就出来了,他就是为了解决服务的通信问题,每个服务都可以将自己的信息注册到Eureka中,比如ip、端口、服务名等信息,这个时候如果订单服务想要获取用户服务的信息,只需要去Eureka中获取即可,请看下图:
这就是Eureka的主要功能,也是我们使用中的最值得注意的,他让服务之间的通信变得更加的简单灵活。
Spring Cloud Config
Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持。使用Config Server,您可以在所有环境中管理应用程序的外部属性。客户端和服务器上的概念映射与Spring Environment和PropertySource抽象相同,因此它们与Spring应用程序非常契合,但可以与任何以任何语言运行的应用程序一起使用。随着应用程序通过从开发人员到测试和生产的部署流程,您可以管理这些环境之间的配置,并确定应用程序具有迁移时需要运行的一切。服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具。可以轻松添加替代实现,并使用Spring配置将其插入。
简单点来说集中来管理每个服务的配置文件,将配置文件与服务分离,这么多的目的是什么?举个简单的栗子,我们配置文件中肯定会存在数据库的连接信息,redis的连接信息,我们的环境是多样的,有开发环境、测试环境、预发布环境、生产环境,每个环境对应的连接信息肯定是不相同的,难道每次发布的时候都要去修改一下服务中的配置文件?我能不能将这些变动较大的配置集中管理,不同环境的管理者分别对他们进行修改,就不需要再服务中做改动了,Config他就做到了。
这就是config的大致架构,所有的配置文件都集中交给config管理,拿config怎么管理这些配置文件呢?你可以将每个环境的配置文件存放再一个位置,比如Lgitlab、svn、本地等等,config会根据根据你设置的位置读取配置文件进行管理,然后其他服务启动的时候直接到config配置中心获取对应的配置文件即可,这样开发人员只需要关注-dev的配置文件,测试人员只需要关注-test的配置文件,完全和服务解耦,你值得拥有。
Netflix Zuul(网关)
这个时候技术总监突然提了一个问题,他说:既然我们将一个服务拆分成了很多微服务,那岂不是要暴漏很多接口给浏览器?这样会不会造成安全隐患呢?有谁可以来说说这个问题。
同事A:我们可以通过nginx反向代理,开放二级域名,然后将域名映射到微服务中。
技术总监:这个方案也可以,也是不需要使用的,但不是最完善的,还有没有更好的方案?nginx虽然把端口隐藏了,如果我们的服务都是需要一些权限的校验,nginx是无法替我们完成的,这个时候我们难道要在每个服务中都添加一套权限校验的逻辑吗?
同事B:我觉得我们可以使用网关,它既可以做分流转发,也可以做权限控制,使用nginx+网关,我觉得是比较好的一种方案,以下是网关zuul的介绍。
路由在微服务体系结构的一个组成部分。例如,/可以映射到您的Web应用程序,/api/users映射到用户服务,并将/api/shop映射到商店服务。Zuul是Netflix的基于JVM的路由器和服务器端负载均衡器。
Netflix使用Zuul进行以下操作:
- 认证
-洞察
-
压力测试
-
金丝雀测试
-
动态路由
-
服务迁移
-
负载脱落
-
安全
-
静态响应处理
-
主动/主动流量管理
其实我们在日常开发过程中并不会使用那么多,基本上就是认证、动态路由、安全等等,我画了一张关于网关的架构图,请看:
技术总监:你们真的太优秀了,没错,nginx只能为我们做反向代理,不能做到权限认证,网关不但可以做到代理,也能做到权限认证、甚至还能做限流,所以我们要做分布式项目,少了他可不行。
代码实现:springcloud(三)网关zuul
Spring Cloud Bus
application.yml
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/test
driver-class-name: com.mysql.cj.jdbc.Driver
技术总监:比如上面这行配置大家都应该很熟悉,这是数据库的连接信息,如果它发生改变了怎么办呢?我们都知道,服务启动的时候会去config配置中心拉取配置信息,但是启动完成之后修改了配置文件我们应该怎么办呢,重启服务器吗?
同事C:我们可以通过spring cloud bus来解决这个问题,Spring Cloud Bus将轻量级消息代理链接到分布式系统的节点。然后可以将其用于广播状态更改(例如,配置更改)或其他管理指令。该项目包括AMQP和Kafka经纪人实施。另外,在类路径上找到的任何Spring Cloud Stream绑定程序都可以作为传输工具使用。
这个需要我们有一点的mq基础,不管是rabbitmq还是kafka,都可以,bus的基本原理就是:配置文件发生改变时,config会发出一个mq,告诉服务,配置文件发生改变了,并且还发出了改变的哪些信息,这个时候服务只需要根据mq的信息做实时修改即可,这是一个很简单的原理,理解起来可能也不会怎么难,画个图来理解一下
大致流程就是这样,核心就是通过mq机制实现不重启服务也能做到配置文件的改动,这方便了运维工程师,不用每次修改配置文件的时候都要去重启一遍服务的烦恼。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
文末
我将这三次阿里面试的题目全部分专题整理出来,并附带上详细的答案解析,生成了一份PDF文档
- 第一个要分享给大家的就是算法和数据结构
- 第二个就是数据库的高频知识点与性能优化
- 第三个则是并发编程(72个知识点学习)
- 最后一个是各大JAVA架构专题的面试点+解析+我的一些学习的书籍资料
还有更多的Redis、MySQL、JVM、Kafka、微服务、Spring全家桶等学习笔记这里就不一一列举出来
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
全部分专题整理出来,并附带上详细的答案解析,生成了一份PDF文档
- 第一个要分享给大家的就是算法和数据结构
[外链图片转存中…(img-O8VJzPce-1713555322242)]
- 第二个就是数据库的高频知识点与性能优化
[外链图片转存中…(img-xZdvnG1b-1713555322242)]
- 第三个则是并发编程(72个知识点学习)
[外链图片转存中…(img-lW5SAata-1713555322242)]
- 最后一个是各大JAVA架构专题的面试点+解析+我的一些学习的书籍资料
[外链图片转存中…(img-nPe5PAYi-1713555322243)]
还有更多的Redis、MySQL、JVM、Kafka、微服务、Spring全家桶等学习笔记这里就不一一列举出来
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!