微服务架构

系统架构

从互联网早起到现在,系统架构大体经历了下面几个过程:

单体应用架构—>集群应用架构—>垂直应用架构—>SOA 架构—>微服务架构

单体应用架构

单体架构的开发和运维都很简单

集群应用架构

网站流量增加,服务器的性能出现瓶颈,通过集群架构进行横向扩容是最好的方式

垂直应用架构

主要是用来解耦业务的复杂度,提高代码的维护性和可扩展性

SOA架构

SOA架构主要解决服务的复用性问题,通过服务的抽象来实现业务的可复用性。

微服务架构

是在SOA架构思想之上的提炼,它是服务化思想的最佳时间方向和服务治理不断完善和交付链路逐步成熟后的自然产物

微服务架构的优势

独立开发 – 所有微服务都可以根据各自的功能轻松开发

独立部署 – 基于其服务,可以在任何应用程序中单独部署它们

故障隔离 – 即使应用程序的一项服务不起作用,系统仍可继续运行

混合技术堆栈 – 可以使用不同的语言和技术来构建同一应用程序的不同服务

粒度缩放 – 单个组件可根据需要进行缩放,无需将所有组件缩放在一起

微服务架构的常见问题

一旦采用微服务系统架构,就势必会遇到这样几个问题:

如何管理他们?

他们之间如何通讯?

客户端怎么访问他们?

一旦出现问题了,应该如何自处理?

一旦出现问题了,应该如何排错?

微服务架构的常见概念

服务治理

服务治理就是进行服务的自动化管理,其核心是服务的自动注册与发现。

服务注册:服务实例将自身服务信息注册到注册中心。

服务发现:服务实例通过注册中心,获取到注册到其中的服务实例的信息, 通过这些信息去请求它们提供的服务。

服务剔除:服务注册中心将出问题的服务自动剔除到可用列表之外,使其不会被调用到。

服务调用

在微服务架构中,通常存在多个服务之间的远程调用的需求。目前主流的远程调用技术有基于 HTTP 的 RESTful 接口以及基于 TCP 的 RPC 协议。

服务网关

随着微服务的不断增多,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信可能出现:

客户端需要调用不同的 url 地址,增加难度

在一定的场景下,存在跨域请求的问题

每个微服务都需要进行单独的身份认证

API 网关直面意思是将所有 API 调用统一接入到 API 网关层,由网关层统一接入和输出。

服务容错

在微服务当中,一个请求经常会涉及到调用几个服务,如果其中某个服务不可用,没有做服务容错的话,极有可能会造成一连串的服务不可用,这就是雪崩效应。 我们没法预防雪崩效应的发生,只能尽可能去做好容错。

链路追踪

随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务。互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。因此,就需要对一次请求涉及的多个服务链路进行日志记录,性能监控即链路追踪.

微服务架构的常见解决方案

ServiceComb

Apache ServiceComb,前身是华为云的微服务引擎 CSE (Cloud Service Engine) 云服务,是全球 首个 Apache 微服务顶级项目。它提供了一站式的微 服务开源解决方案,致力于帮助企业、用户和开发 者将企业应用轻松微服务化 上云,并实现对微服务应用的高效运维管理。

SpringCloud

Spring Cloud 是一系列框架的集合。它利用 Spring Boot 的开发便利性巧 妙地简化了分布式系统基 础设施的开发,如服务发现注册、配置中心、消息总 线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。

SpringCloud Alibaba

Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服 务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。

主要功能

服 务 限 流 降 级 : 默 认 支 持 WebServlet 、 WebFlux , OpenFeign 、RestTemplate、Spring Cloud Gateway,Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修 改限流降级规则,还支持查看限流降级 Metrics 监控。

组件

Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳 定性。

Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理 平台。

RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提 供低延时的、高可靠 的消息发布与订阅服务。

Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。

Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。

微服务环境搭建

以电商项目中的商品、订单、用户为案例,

创建父工程

创建基础模块

创建用户微服务

创建商品微服务

创建订单微服务

微服务调用

Nacos Discovery–服务治理

服务治理: 是微服务架构中最核心最基本的模块。用于实现各个微服务的自动化注册与发现。

服务注册: 在服务治理框架中,都会构建一个注册中心,每个服务单元向注册中心登记自己提供服 务的详细信息。并在注册中心形成一张服务的清单,服务注 册中心需要以心跳的方式去监测清单中 的服务是否可用,如果不可用,需要在服务清单中剔除不可用的服务。

服务发现: 服务调用方向服务注册中心咨询服务,并获取所有服务的实例清单,实现对具体服务实例的访问。

注册中心一般包含如下几个功能:

1、服务发现:

服务注册:保存服务提供者和服务调用者的信息

服务订阅:服务调用者订阅服务提供者的信息,注册中心向订阅者推送提供者的信息

2、服务配置:

配置订阅:服务提供者和服务调用者订阅微服务相关的配置

配置下发:主动将配置推送给服务提供者和服务调用者

3、服务健康检测:检测服务提供者的健康情况,如果发现异常,执行服务剔除

nacos

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单 易用的特性集,帮助您快速 实现动态服务发现、服务配置、服务元数据及流量 管理。 从上面的介绍就可以看出,nacos 的作用就是一个注册中心,用来管理 注册上来的各个微服务。

搭建nacos环境

第 1 步: 安装 nacos

下载地址:

https://github.com/alibaba/nacos/releases

下载 zip 格式的安装包,然后进行解压缩操作

第 2 步: 启动 nacos

#切换目录

cd nacos/bin

#命令启动

startup.cmd -m standalone

第 3 步: 访问 nacos

打开浏览器输入 http://localhost:8848/nacos,即可访问服务,默认密码是nacos/nacos
在这里插入图片描述

服务调用负载均衡

什么是负载均衡

通俗的讲, 负载均衡就是将负载(工作任务,访问请求)进行分摊到多个操作单元(服务器,组件)上进行执行。

七种负载均衡策略

轮询策略: RoundRobinRule,按照一定的顺序依次调用服务实例。比如一共有 3 个服务,第一次调用服务 1,第二次调用服务 2,第三次调用服务 3,

依次类推。

NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule 

权重策略: WeightedResponseTimeRule,根据每个服务提供者的响应时间分配一个权重,响应时间越长,权重越小,被选中的可能性也就越低。它的实 现原理是,刚开始使用轮询策略并开启一个计时器,每一段时间收集一次所有服 务提供者的平均响应时间,然后再给每个服务提供者附上一个权重,权重越高被 选中的概率也越大。

NFLoadBalancerRuleClassName:com.netflix.loadbalancer.WeightedResponseTimeRule 

随机策略: RandomRule,从服务提供者的列表中随机选择一个服务实例。

NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule 

最小连接数策略: BestAvailableRule,也叫最小并发数策略,它是遍历服务提供者列表,选取连接数最小的⼀个服务实例。如果有相同的最小连接数,那 么会调用轮询策略进行选取。

NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule 

重试策略: RetryRule,按照轮询策略来获取服务,如果获取的服务实例为null 或已经失效,则在指定的时间之内不断地进行重试来获取服务,如果超过 指定时间依然没获取到服务实例则返回 null。

ribbon: 
	ConnectTimeout: 2000 #请求连接的超时时间
	ReadTimeout: 5000 #请求处理的超时时间
service-product: #调用的提供者的名称
	ribbon: 
NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RandomRule 

可用敏感性策略: AvailabilityFilteringRule,先过滤掉非健康的服务实例,然后再选择连接数较小的服务实例。

NFLoadBalancerRuleClassName:com.netflix.loadbalancer.AvailabilityFilteringRule

区域敏感策略: ZoneAvoidanceRule,根据服务所在区域(zone)的性能和服务的可用性来选择服务实例,在没有区域的环境下,该策略和轮询策略类似。

NFLoadBalancerRuleClassName: com.netflix.loadbalancer.ZoneAvoidanceRule 

我们可以通过修改配置来调整 Ribbon 的负载均衡策略,具体代码如下

service-product: # nacos 中的服务 id
 ribbon: 
   NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

基于 Feign 实现服务调用

什么是 Feign

Feign 是 Spring Cloud 提供的一个声明式的伪 Http 客户端, 它使得调用远程服务,就像调用本地服务 一样简单, 只需要创建一个接口并添加一个注解即可。Nacos 很好的兼容了 Feign, Feign 默认集成了 Ribbon, 所以在Nacos 下使用 Fegin 默认就实现了负 载均衡的效果。

Sentinel–服务容错

高并发带来的问题

在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用,但是由于网络 原因或者自身的原因,服务并不能保证服务的 100%可 用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大量的网络涌入,会形成任务堆积,最终导致服务瘫痪。

服务雪崩效应

在分布式系统中,由于网络原因或自身的原因,服务一般无法保证 100% 可 用。如果一个服务出现了问题,调用这个服务就会出现线程阻塞的情况,此时若有大量的请求涌入,就会出现多条线程阻塞等待,进而导致服务瘫痪。 由于服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的 “雪崩效应”

常见容错方案

隔离

它是指将系统按照一定的原则划分为若干个服务模块,各个模块之间相对独立,无强依赖。当有故障发生时,能将问题和影响隔离在某个模块内部,而不扩散风险,不波及其它模块,不影响整体的系统服务。常见的隔离方式有:线程池隔离和信号量隔离.

超时

在上游服务调用下游服务的时候,设置一个最大响应时间,如果超过这个时间,下游未作出反应, 就断开请求,释放掉线程。

限流

限流就是限制系统的输入和输出流量已达到保护系统的目的。为了保证系 统的稳固运行,一旦达到的需要限制的阈值,就需要限制流量并采取少量措施以完 成限制流量的目的。

熔断

在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。这种牺牲局部,保全整体的措施就叫做熔断。

服务熔断一般有三种状态:

熔断关闭状态(Closed)

服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限制

熔断开启状态(Open)

后续对该服务接口的调用不再经过网络,直接执行本地的 fallback 方法

半熔断状态(Half-Open)

尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。如果成功率达到预期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断关闭状态。

降级

降级其实就是为服务提供一个托底方案,一旦服务无法正常调用,就使用托底方案。

Sentinel 使用及概念

Sentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于服务容错的综 合性解决方案。它以流量 为切入点, 从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。

Sentinel 具有以下特征:

丰富的应用场景 完备的实时监控 广泛的开源生态

Sentinel 分为两个部分:

核心库(Java 客户端) 不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

控制台(Dashboard) 基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

Sentinel重要功能

1、流量控制

流量控制在网络传输中是一个常用的概念,它用于调整网络包的数据。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。

Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状。

2、熔断降级

当检测到调用链路中某个资源出现不稳定的表现,例如请求响应时间长或异常比例升高的时候,则对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联故障。

Sentinel 对这个问题采取了两种手段:

通过并发线程数进行限制

Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的 影响。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后, 对该资源的新请求就会被拒绝。堆积的 线程完成任务后才开始继续接收请求。

通过响应时间对资源进行降级除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。

3、系统负载保护

Sentinel 同时提供系统维度的自适应保护能力。当系统负载较高的时候, 如果还持续让请求进入可能会导致系统崩溃,无法响应。在集群环境下,会把本 应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在 一个边缘状态的时候,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。

Gateway–服务网关

Gateway 简介

Spring Cloud Gateway 是 Spring 公司基于 Spring 5.0,Spring Boot 2.0和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。它的目标是替代 Netflix Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控和限流。

优点:

性能强劲,是第一代网关 Zuul 的 1.6 倍

功能强大,内置了很多实用的功能,例如转发、监控、限流等

设计优雅,容易扩展

缺点:

其实现依赖 Netty 与 WebFlux,不是传统的 Servlet 编程模型,学习成本高

不能将其部署在 Tomcat、Jetty 等 Servlet 容器里,只能打成 jar 包执行

需要 Spring Boot 2.0 及以上的版本,才支持.

Gateway 快速入门

通过浏览器访问 api 网关,然后通过网关将请求转发到商品微服务.以下是配置文件
在这里插入图片描述
Gateway 结合 nacos

现在在配置文件中写死了转发路径的地址, 前面我们已经分析过地址写死带来的问题, 接下来我们从注册中心获取此地址。

修改配置文件

server:
	port: 9000
spring:
	application:
		name: api-gateway
	cloud:
	   nacos:
		 discovery:
		   server-addr: 127.0.0.1:8848 #nacos 服务地址
	   gateway:
		 discovery:
		   locator:
			 enabled: true
		 routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
		    - id: product_route # 当前路由的标识, 要求唯一
			  uri: lb://service-order  #lb指的是从 nacos 中按照名称获取微服务, 并遵循负载均衡策略
		      order: 1 # 路由的优先级,数字越小级别越高
			  predicates: # 断言(就是路由转发要满足的条件)
				 - Path=/order-serv/**  # 当请求路径满足 Path 指定的规则时,才进行路由转发
			  filters: #过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
				- StripPrefix=1 # 转发之前去掉1层路径

网关限流

网关是所有请求的公共入口,所以可以在网关进行限流,而且限流的方式也很多,我们本次采用前 面学过的 Sentinel组件来实现网关的限流。Sentinel支持对SpringCloud Gateway、Zuul 等主流网关进行限流。

消息队列-MQ

MQ 全称(Message Queue)又名消息队列,是一种提供消息队列服务的中间件,也称为消息中间件,是一套提供了消息生产、存储、消费全过程 API的软件系统(消息即数据)。通俗点说,就是一个先进先出的数据结构。

MQ 的应用场景

异步解耦

最常见的一个场景是用户注册后,需要发送注册邮件和短信通知,以告知用户注册成功。传统的做法如下:
在这里插入图片描述此架构下注册、邮件、短信三个任务全部完成后,才返回注册结果到客户端,用户才能使用账号登录。 但是对于用户来说,注册功能实际只需要注册系统存 储用户的账户信息后,该用户便可以登录,而后续 的注册短信和邮件不是即时 需要关注的步骤。 所以实际当数据写入注册系统后,注册系统就可以把其他的操作放入对应的消息队列 MQ 中然后马上返 回用户结果,由消息队列 MQ 异步地进行这些操作。

异步解耦是消息队列 MQ 的主要特点,主要目的是减少请求响应时间和解耦。主要的使用场景就是将比较耗时而且不需要即时(同步)返回结果的操 作作为消息放入消息队列。同时,由于使用了消息队列 MQ,只要保证消息格 式不变,消息的发送方和接收方并不需要彼此联系,也不需要受对方的影响,即解耦合。

常见的 MQ 产品

ZeroMQ: 号称最快的消息队列系统,尤其针对大吞吐量的需求场景。扩展性好,开发比较灵活,采用C语言实现,实际上只是一个 socket 库的重新封装,如果做为消息队列使用,需要开发大量的代码。 ZeroMQ 仅提供非持久性的队列,也就是说如果 down 机,数据将会丢失。

RabbitMQ: 使用 erlang 语言开发,性能较好,适合于企业级的开发。但是不利于做二次开发和维护。

ActiveMQ: 历史悠久的 Apache 开源项目。已经在很多产品中得到应用,实现了 JMS1.1 规范,可以和 springjms 轻松融合,实现了多种协议,支持持久化到 数据库,对队列数较多的情况支持不好。

RocketMQ: 阿里巴巴的 MQ 中间件,由 java 语言开发,性能非常好,能够撑住双十一的大流量,而且使用起来很简单。

Kafka: Kafka 是 Apache 下的一个子项目,是一个高性能跨语言分布式Publish/Subscribe 消息队列系统, 相对于 ActiveMQ 是一个非常轻量级的消息系统,除了性能非常好之外,还是一个工作良好的分布式系统。

RocketMQ 入门

下载

https://rocketmq.apache.org/download/

RocketMQ 的架构及概念

整体可以分成 4 个角色,分别是:

NameServer,Broker,Producer,Consumer。

Broker(邮递员) Broker是RocketMQ 的核心,负责消息的接收,存储,投递等功能.

NameServer(邮局) 消息队列的协调者,Broker 向它注册路由信息,同时 Producer 和 Consumer 向其获取路由信息

Producer(寄件人) 消息的生产者,需要从 NameServer 获取 Broker 信息,然后与 Broker 建立连接,向 Broker 发送消息

Consumer(收件人) 消息的消费者,需要从 NameServer 获取 Broker 信息,然后与 Broker 建立连接,从 Broker 获取消息

Topic(地区) 用来区分不同类型的消息,发送和接收消息前都需要先创建Topic,针对 Topic 来发送和接收消息

Message Queue(邮件) 为了提高性能和吞吐量,引入了 Message Queue, 一个 Topic 可以设置一个或多个 Message Queue,这样消息就可以并行往各个Message Queue 发送消息,消费者也可以并行的从多个 Message Queue 读取消息 Message Message 是消息的载体。

Producer Group 生产者组,简单来说就是多个发送同一类消息的生产者称之 为一个生产者组。

Consumer Group 消费者组,消费同一类消息的多个 consumer 实例组成一 个消费者组。

RocketMQ 提供三种方式来发送普通消息:可靠同步发送、可靠异步发送、单向发送

可靠同步发送: 同步发送是指消息发送方发出数据后,会在收到接收方发回响应之后才发下一个数据包的通讯方式。 此种方式应用场景非常广泛,例如重要通知邮件、报名短信通知、营销短信系统等。

可靠异步发送: 异步发送是指发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。发送 方通过回调接口接收服务器响应,并对响应结 果进行处理。 异步发送一般用于链路耗时较长,对 RT 响应时间较为敏感的业 务场景,例如用户视频上传后通知 启动转码服务,转码完成后通知推送转码结果等。

单向发送: 单向发送是指发送方只负责发送消息,不等待服务器回应且没有回调函数触发,即只发送请求不 等待应答。 适用于某些耗时非常短,但对可靠性要求并不高的场景,例如日志收集。

Redis 实现分布式锁

分布式锁,即分布式系统中的锁。在单体应用中我们通过 java 中的锁解决多线程访问共享资源的问题,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题。与单体应用不同的是,分布式系统中竞争共享资源的最小粒度从线程升级成了进程.

在分布式项目中,一个商品服务,可以开多个实例,这样在不同的服务实例进行加synchronized锁是不能锁定共享资源的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JIANG++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值