SpringCloud之热门组件
微服务架构图
SpringCloud常用组件
SpringCloud包含的组件很多,有很多功能是重复的。其中最常用组件包括:
- 注册中心组件:Eureka、Nacos等
- 负载均衡组件:Ribbon
- 远程调用组件:OpenFeign
- 网关组件:Zuul、Gateway
- 服务保护组件:Hystrix、Sentinel
- 服务配置管理组件:SpringCloudConfig、Nacos
常用组件图
SpringCloud升级之后的组件
注册中心和配置中心Nacos
Nacos Nacos致力于帮助您发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos帮助您更敏捷和容易地构建、交付和管理微服务平台。
Nacos是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。使用:在接下里的教程中,将使用Nacos作为微服务架构中的注册中心(替代:eurekba、consul等传统方案)以及配置中心(spring cloud config)来使用。
Nacos注册中心结构
Nacos采用了数据的分级存储模型,最外层是Namespace,用来隔离环境。然后是Group,用来对服务分组。接下来就是服务(Service)了,一个服务包含多个实例,但是可能处于不同机房,因此Service下有多个集群(Cluster),Cluster下是不同的实例(Instance)。对应到Java代码中,Nacos采用了一个多层的Map来表示。
结构为Map<String, Map<String,Service>>
- 其中最外层Map的key就是namespaceId,值是一个Map。
- 内层Map的key是group拼接serviceName,值是Service对象。
- Service对象内部又是一个Map,key是集群名称,值是Cluster对象。而Cluster对象内部维护了Instance的集合。
如图:
Nacos注册中心和服务提供中心流程
Nacos在更新实例列表时,会采用CopyOnWrite技术,首先将旧的实例列表拷贝一份,然后更新拷贝的实例列表,再用更新后的实例列表来覆盖旧的实例列表。这样在更新的过程中,就不会对读实例列表的请求产生影响,也不会出现脏读问题了。
远程调用OpenFeign
核心原理:OpenFeign和Feign底层都内置了Ribbon负载均衡组件,在导入OpenFeign依赖后无需专门导入Ribbon依赖,用做客户端负载均衡,去调用注册中心服务。
- 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响应的工作。
核心API注解:
@EnableFeignClient
@FeignClient(value = "${service-url.nacos-order-service}",fallback = OrderServiceFallBackImpl.class)
类似代码如下
UserClient.java
@FeignClient(value = "user-server", fallbackFactory = UserClientFallBack.class)
//@FeignClient(contextId = "user", name = "user-server", fallbackFactory = UserClientFallBack.class)
public interface UserClient {
@GetMapping("/user/getUserById/{id}")
User getUserById(@PathVariable("id") Long id);
@GetMapping("/user/getListUser")
List<User> getListUser(@RequestParam Map<String, Object> params);
}
UserClientFallBack.java
@Component
public class UserClientFallBack implements FallbackFactory<UserClient> {
private static final Logger logger = LoggerFactory.getLogger(UserClientFallBack.class);
@Override
public UserClient create(Throwable cause) {
return new UserClient() {
@Override
public User getUserById(Long id) {
logger.error("获取用户详情ID[{}] 数量失败:{}", id, cause.getMessage());
return new User(-1L,"熔断","---熔断---");
}
@Override
public List<User> getListUser(Map<String, Object> params) {
logger.error("获取用户列表ID[{}] 数量失败:{}", params.toString(), cause.getMessage());
List<User> userList = new ArrayList<>();
User User = new User(-1L,"熔断","---熔断---");
userList.add(User);
return userList;
}
};
}
}
UUserBlockHandler.java
public class UserBlockHandler {
// 参数必须加上BlockException 不然报错
public static User getByIdBlockHandler(@PathVariable("id") Long id, BlockException e) {
e.printStackTrace();
return new User(-1L,"限流","---限流限流---");
}
// 参数必须加上BlockException 不然报错
public static User getUserInfoBlockHandler(@RequestParam Map<String, Object> params, BlockException e) {
e.printStackTrace();
return new User(-1L,"限流","---限流限流---");
}
// 参数必须加上BlockException 不然报错
public static List<User> getListUserBlockHandler(BlockException e) {
e.printStackTrace();
List<User> userList = new ArrayList<>();
User user =new User(-1L,"限流","---限流限流---");
userList.add(user);
return userList;
}
}
Gateway网关介绍
- 1、介绍作用:统一入口,鉴权校验,动态路由,减少客户端与服务端的耦合,[自定义日志过滤器,自定义token过滤器]
- 2、相关概念:Route(唯一id),url(目标nacos的服务地址) Predicate(路由条件),Filter(过滤规则)
- 3、核心api:RouteLocatorBuilder
Sentinel 服务限流
大概介绍:
介绍:流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。控制台:实时监控,机器发现,规则配置、管理推送规则、监控、集群限流分配管理
- 1、核心注解:@SentinelResource,滑动窗口[MetricBucket[LongAdder数组实现]]
- 2、规则定义:流控规则、 熔断降级规则、系统规则、权限规则、热点参数规则
- 3、降级策略:平均响应时间,异常比例,异常数, 流控规则:QPS(每秒请求数,当前调用该api的QPS到达阈值的时候进行限流),线程数(当调用该api的线程数到达阈值的时候,进行限流)
- 4、滑动窗口算法[一个大数组里面定义了一个固定长度的数组在数组上进行滑动,左边出右进,在一定的时间跨度内计算统计,最后根据窗口记录运算进行统计,数组字符统计子串,|sentinel时间线驱动计算,统计根据配置进行计算,
常用限流算法
限流算法常见的有三种实现:滑动时间窗口、令牌桶算法、漏桶算法。Gateway则采用了基于Redis实现的令牌桶算法。
Sentinel内部的限流算法
- 1、 默认限流模式是基于滑动时间窗口算法
- 2、排队等待的限流模式则基于漏桶算法
- 3、而热点参数限流则是基于令牌桶算法