目录
1、Ribbon:
2、Feign:
3、Sentinel --服务容错
4、Feign整合Sentinel
5、Gateway--服务网关
6、Rocketmq--消息驱动
1、什么是Ribbon: Ribbon是Spring Cloud的一个组件, 它可以让我们使用一个注解就能轻松的搞定负载均衡
在RestTemplate 的生成方法上添加@LoadBalanced注解
例如:
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
可以通过修改配置来调整Ribbon的负载均衡策略
service-product: # 调用的提供者的名称
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
2、什么是Feign:
Feign是Spring Cloud提供的一个声明式的伪Http客户端, 它使得调用远程服务就像调用本地服务一样简单, 只需要创建一个接口并添加一个注解即可。
Nacos很好的兼容了Feign, Feign默认集成了 Ribbon, 所以在Nacos下使用Fegin默认就实现了负载均衡的效果。
<!--maven 依赖fegin组件-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在主类上添加Fegin的注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients//开启Fegin
public class OrderApplication {}
创建一个service接口,只创建接口,不需要创建实现类, 并使用Fegin实现微服务调用
//声明调用的提供者的name
@FeignClient(value = "service-product", fallback = ProductServiceFallBack.class)
public interface ProductService {
//指定调用提供者的哪个方法
//@FeignClient+@GetMapping 就是一个完整的请求路径 http://service-
product/product/{pid}
@GetMapping(value = "/product/{pid}")
Product findByPid(@PathVariable("pid") Integer pid);
}
服务雪崩效应
在分布式系统中,由于网络原因或自身的原因,服务一般无法保证 100% 可用。如果一个服务出现了问题,调用这个服务就会出现线程阻塞的情况,此时若有大量的请求涌入,就会出现多条线程阻塞等待,进而导致 服务瘫痪。
常见的容错思路有隔离、超时、限流、熔断、降级这几种,下面分别介绍一下。
隔离:它是指将系统按照一定的原则划分为若干个服务模块,各个模块之间相对独立,无强依赖。当有故障发生时,能将问题和影响隔离在某个模块内部,而不扩散风险,不波及其它模块,不影响整体的系统服务。常见的隔离方式有:线程池隔离和信号量隔离。
超时:在上游服务调用下游服务的时候,设置一个最大响应时间,如果超过这个时间,下游未作出反应,就断开请求,释放掉线程。
限流:就是限制系统的输入和输出流量已达到保护系统的目的。为了保证系统的稳固运行,一旦达到的需要限制的阈值,就需要限制流量并采取少量措施以完成限制流量的目的。
熔断: 在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。这种牺牲局部,保全整体的措施就叫做熔断。
3、Sentinel --服务容错
Sentinel 是阿里巴巴开源的一款断路器实现,本身在阿里内部已经被大规模采用,非常稳定。
什么是Sentinel
Sentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于服务容错的综合性解决方案。它以流量为切入点, 从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。
Sentinel 具有以下特征:
丰富的应用场景
完备的实时监控
广泛的开源生态
完善的 SPI 扩展点
Sentinel 分为两个部分:
核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo /Spring Cloud 等框架也有较好的支持。
控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
在pom.xml中加入下面依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
资源
资源就是Sentinel要保护的东西
规则
规则就是用来定义如何进行保护资源的
Sentinel的主要功能就是容错,主要体现为下面这三个:
流量控制
直接流控模式
关联流控模式
熔断降价
系统负载保护
4、Feign整合Sentinel
在配置文件中开启Feign对Sentinel的支持
feign:
sentinel:
enabled: true
容错类要求必须实现被容错的接口,并为每个方法实现容错方案
容错类其实就是类似于一个service接口的实现类,实现接口里面的方法,方法里面编写自己逻辑,
需要在接口里面指定一个容错类 fallback的属性
@FeignClient(value = "service-product", fallback = ProductServiceFallBack.class)
这是一个容错类需要 实现Fegin所在的接口,并去实现接口中的所有方法
一旦Fegin远程调用出现问题了,就会进入当 前类中同名方法,执行容错逻辑
在接口里面添加fallbackFactory属性
@FeignClient(value = "service-product"
//fallback = ProductServiceFallback.class,
//fallbackFactory = ProductServiceFallbackFactory.class
)
public interface ProductService {
@RequestMapping("/product/{pid}") // 完整路径 http://service-product/product/" + pid,
Product findByPid(@PathVariable Integer pid);
}
这是容错类,他要求我们要是实现一个FallbackFactory<要为哪个接口产生容错类>
@Component
public class ProductServiceFallBackFactory implements FallbackFactory<ProductService> {
@Override
public ProductService create(Throwable throwable) {
return new ProductService() {
@Override
public Product findByPid(Integer pid) {
throwable.printStackTrace();
Product product = new Product();
product.setPid(-1);
return product;
}
};
}
}
5、Gateway--服务网关
优点:
性能强劲:是第一代网关Zuul的1.6倍
功能强大:内置了很多实用的功能,例如转发、监控、限流等
设计优雅,容易扩展
缺点:
其实现依赖Netty与WebFlux,不是传统的Servlet编程模型,学习成本高
不能将其部署在Tomcat、Jetty等Servlet容器里,只能打成jar包执行
需要Spring Boot 2.0及以上的版本,才支持
<dependencies>
<!--gateway网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
添加配置文件
server:
port: 7000
spring:
zipkin:
base-url: http://127.0.0.1:9411/ #zipkin server的请求地址
discoveryClientEnabled: false #让nacos把它当成一个URL,而不要当做服务名
sleuth:
sampler:
probability: 1.0 #采样的百分比
application:
name: api-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #添加nacos的服务地址
gateway:
discovery:
locator:
enabled: true # 让gateway可以发现nacos中的微服务
routes: # 路由数组[路由 就是指定当请求满足什么条件的时候转到哪个微服务]
- id: product_route # 当前路由的标识, 要求唯一
# uri: http://localhost:8081 # 请求要转发到的地址
uri: lb://service-product # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
order: 1 #路由的优先级,数字越小代表路由的优先级越高
predicates: # 断言(就是路由转发要满足的条件)
- Path=/product-serv/** # 当请求路径满足Path指定的规则时,才进行路由转发 测试访问: http://localhost:7000/product-serv/product/1
# - Age=18,60 # 限制年龄只有在18到60岁之间的人能访问
filters: # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
- StripPrefix=1 # 转发之前去掉1层路径
# - Log=false,true # 自定义过滤器 控制日志是否开启
Gateway核心架构
路由(Route) 是 gateway 中最基本的组件之一,表示一个具体的路由信息载体。主要定义了下面的几个信息:
id,路由标识符,区别于其他 Route。
uri,路由指向的目的地 uri,即客户端请求最终被转发到的微服务。
order,用于多个 Route 之间的排序,数值越小排序越靠前,匹配优先级越高。
predicate,断言的作用是进行条件判断,只有断言都返回真,才会真正的执行路由。
filter,过滤器用于修改请求和响应信息。
执行流程大体如下:
1. Gateway Client向Gateway Server发送请求
2. 请求首先会被HttpWebHandlerAdapter进行提取组装成网关上下文
3. 然后网关的上下文会传递到DispatcherHandler,它负责将请求分发给RoutePredicateHandlerMapping
4. RoutePredicateHandlerMapping负责路由查找,并根据路由断言判断路由是否可用
5. 如果过断言成功,由FilteringWebHandler创建过滤器链并调用
6. 请求会一次经过PreFilter--微服务--PostFilter的方法,最终返回响应
6、Rocketmq--消息驱动
什么是MQ
MQ(Message Queue)是一种跨进程的通信机制,用于传递消息。通俗点说,就是一个先进先出的数据结构
MQ的应用场景
流量削峰
异步解耦
<!--rocketmq maven依赖-->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.4.0</version>
</dependency>
rocketmq:
name-server: 127.0.0.1:9876 #rocketMQ服务的地址
producer:
group: shop-order # 生产者组
发送不同类型的消息
1、普通消息
发送方式 发送TPS 发送结果反馈 可靠性
同步发送 快 有 不丢失
异步发送 快 有 不丢失
单向发送 最快 无 可能丢失
2、顺序消息
3、事务消息