微服务架构:是以开发一组小型服务的方式来开发一个独立的应用系统。其中每个小型服务都运行在自己的进程中,并经常采用HTTP资源API这样轻量的机制来相互通信。这些服务围绕业务功能进行构建,并能通过全自动的部署机制来进行独立部署。这些微服务可以使用不同的语言来编写,并且可以使用不同的数据存储技术。对于这些微服务,我们仅能做到最低限度的集中管理。
微服务架构的开发框架:
- Spring Cloud:最早最成熟,Java开源微服务框架方案
- Dubbo : 阿里巴巴开源Java服务治理框架
- Spring Cloud Alibaba 阿里开源Java微服务框架方案
- SOFA:蚂蚁金服开源Java金融微服务框架方案
- Go Micro:Go语言开源微服务框架
- Seneca Microservices ,Node.js微服务框架
- KumuluzEE:Java的微服务框架
- Enduro/X: C/C++/Go
Spring-Cloud(微服务架构工具集)
是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
按开发流程总结我们在Spring-Cloud项目中所用到的主流技术
一、服务发现(nacos-discovery)
服务发现就是找到服务实例的地址的过程,实现这个过程的流程如下:
1.生产端启动时上报本机ip和端口给nocos的服务注册表
2.消费端从服务注册表拉取服务列表
3.服务注册表对生产端进行健康检测
4.如果发生变更,服务注册表对消费端变更通知
5.消费端重新拉取服务列表
二、负载均衡(Load Balance)
负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
选用netflix-ribbon作为负载均衡服务,由nacos-discovery引入
1、ribbon 与 eureka 一样都是 netflix 下的子项目,spring cloud 对它们进行了集成。
2、ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,可以轻松地将面向服务的 REST 模版请求自动转换成客户端负载均衡的服务调用。
3、nginx 在服务端实现负载均衡,ribbon 在客户端提供负载均衡。即客户端程序使用 ribbon 后,就会自动对多个节点微服务进行负载均衡。
4、负载均衡有好几种实现策略,常见的有:随机 (Random)、轮询 (RoundRobinRule)、最小并发数(BestAvailableRule)、响应时间加权(WeightedResponseTimeRule)。默认是轮询。
netflix Ribbon 基本使用
Ribbon 是客户端实现的负载均衡,也就是谁发起请求,谁自己实现负载均衡
- 全局配置
/** * 全局替换成随机规则 * @return */ @Bean public IRule loadBalanceRule(){ return new RandomRule(); }
- 指定某个服务
# 为某一个服务指定负载均衡规则 user: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
三、声明式服务调用组件(openfeign)
1.导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
2.加注解
接口类上加@FeignClient("服务名")
启动类上加@EnableFeignClients(basePackages = "com.woniuxy.*.client"),//扫描所有的feign-client,注意项目的包路径需要符合要求
openfeign实现流程
1、通过 @EnableFeignCleints 触发 Spring 应用程序对 classpath 中 @FeignClient 修饰类的扫描
2、解析到 @FeignClient 修饰类后, Feign 框架通过扩展 Spring Bean Deifinition 的注册逻辑, 最终注册一个 FeignClientFacotoryBean 进入 Spring 容器
3、Spring 容器在初始化其他用到 @FeignClient 接口的类时, 获得的是 FeignClientFacotryBean 产生的一个代理对象 Proxy.
4、基于 java 原生的动态代理机制, 针对 Proxy 的调用, 都会被统一转发给 Feign 框架所定义的一个 InvocationHandler , 由该 Handler 完成后续的 HTTP 转换, 发送, 接收, 翻译HTTP响应的工作。
四、分布式事务(seata)
微服务架构下,一个业务操作必须经过多个服务,每个服务有自己独立的数据库,造成一个业务操作必然在多个数据库实例中执行,必须达到多个数据库实例同时成功或者失败的效果,才能实现这个业务操作。
分布式事务基本概念
- 全局事务:分布式事务本身,由参与的所有分支事务组成
- 分支事务:单个服务内部的事务
- 事务协调者:TC Transaction Coodinator 协调各个分支事务,同时提交,同时回滚
- 事务发起者:TM Transaction Manager 事务管理者 发起全局事务
- 事务参与者:RM Resource Manager 资源管理者 参与全局事务,维护分支事务
常见解决方案:XA协议、TCC、SAGAS、AT模式、重试+幂等性校验
选择方案:AT模式
五、服务网关(gateway)
是整个分布式系统的唯一入口,API网关封装了系统内部架构,为每个客户端提供定制的API。 近几年来移动应用与企业间互联需求的兴起。从以前单一的Web应用,扩展到多种使用场景,且每种使用场景对后台服务的要求都不尽相同。 这不仅增加了后台服务的响应量,还增加了后台服务的复杂性。随着微服务架构概念的提出,API网关成为了微服务架构的一个标配组件。
服务网关的功能(GlobalFilter 全局过滤器):ip黑白名单、性能监测、动态路由、权限控制(认证授权)、解决跨越问题、协议转换。。。
搭建网关:基于Reactive技术栈,不是基于Servlet,底层是Netty。不能有starter-web。选择spring-cloud-gateway。添加依赖lombok和nocos。
动态路由:
spring:
cloud:
gateway:
routes:
- id: user-route #路由的id
uri: lb://user #转发的目标服务
predicates:
- Path=/api/user/** #匹配请求路径
filters:
- StripPrefix=2 #处理操作
匹配请求:Path(路径)、Header(请求头)、Query(请求参数)、cookie、host
处理操作(GatewayFilter网关过滤器):StripPrefix 去除前缀、AddRequestHeader、AddResponseHeader、AddRequestParameter
GlobalFilter 全局过滤器:用到某个Route路由
GatewayFilter网关过滤器:应用于所有的路由,有顺序(Ordered),在NettyRoutingFilter(转发请求)前和后两种方式
网关认证(基于JWT实现):
六、服务容错(sentinel)
服务雪崩:单个实例故障时,处理请求缓慢或者没有响应,导致上层调用它的服务实例也变慢,请求堆积,负载拉高。进一步导致更广泛的服务实例故障。最后整个分布式系统大面积出现服务实例故障,形同异常雪崩,突然全线崩溃。这种由单个服务实例引发的级联故障称为服务雪崩。
造成雪崩原因可以归结为以下三个:
1.服务提供者不可用(硬件故障,程序bug,缓存击穿,用户大量请求)
2.重试加大流量(用户重试,代码逻辑重试)
3.服务调用者不可用(同步等待造成的资源耗尽)
常见服务容错模式:
1.超时[调用方], 限制资源的占用,给资源(线程、cpu时间)占用设置上线
2.限流[提供方],控制进入系统的流量,不超过本机最大处理能力
3.仓壁模式[调用方/提供方],利用线程池或者信号量等其他手段进行资源隔离,确保不会产生级联故障
限流:保证核心服务的稳定性。为了保证核心服务的稳定性,随着访问量的不断增加,需要为系统能够处理的服务数量设置一个极限阀值,超过这个阀值的请求则直接拒绝。
熔断:熔断技术是一种“智能化的容错”,当调用满足失败次数,失败比例就会触发熔断器打开,有程序自动切断当前的RPC调用,来防止错误进一步扩大。实现一个熔断器主要是考虑三种模式,关闭,打开,半开。