Spring

Spring

IOC:

控制反转,将创建对象的过程交给 Spring 容器进行创建和管理。

AOP:

控制切面,对目标方法进行增强处理,包括做前置、环绕通知等
实现:通过代理实现
使用场景:记录日志操作,缓存处理(添加缓存),Spring 事务,权限控制等。

SpringAOP 和 AspectJ AOP 区别:

Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。 Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)。AspectJ 相比于 Spring AOP 功能更加强大,但是 Spring AOP 相对来说更简单。
AspectJ 定义的通知类型:
前置通知、后置通知、返回通知、异常通知、环绕通知
多个切面的执行顺序可由 @Order 注解定义,值越小优先级越高。或者实现 Ordered 接口,重写方法。

@Component 和 @Bean 区别:

@Component 用于类,@Bean 用于方法。
很多地方我们只能通过 @Bean 注解来注册 bean。比如当我们引用第三方库中的类需要装配到 Spring容器 时,则只能通过 @Bean来实现。

Spring 不建议使用基于字段的依赖注入?

主要是实例化对象的顺序不同,可能会导致 NPE
	类变量和类方法 > 实例变量(代码块)> 构造方法 > @Autowired
Spring 支持哪些注入:
	基于字段、基于构造器、setter()
	使用构造器可能会导致循环依赖?
		@Lazy

@Bean 的作用域:

● singleton : IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。
● prototype : 每次获取都会创建一个新的 bean 实例。也就是说,连续 getBean() 两次,得到的是不同的 Bean 实例。
● request (仅 Web 应用可用): 每一次 HTTP 请求都会产生一个新的 bean(请求 bean),该 bean 仅在当前 HTTP request 内有效。
● session (仅 Web 应用可用) : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean(会话 bean),该 bean 仅在当前 HTTP session 内有效。
● application/global-session (仅 Web 应用可用):每个 Web 应用在启动时创建一个 Bean(应用 Bean),该 bean 仅在当前应用启动时间内有效。
● websocket (仅 Web 应用可用):每一次 WebSocket 会话产生一个新的 bean。
使用方式: @Scope

@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Person personPrototype() {
    return new Person();
}

Spring 的初始化过程?

创建、使用、销毁
	实例化、初始化、使用和销毁
生命周期:

Bean 的生命周期就是一个 Bean 从创建到使用到销毁的过程
通过 BeanDefinition 获取 bean 的定义信息;(进行 bean 的定义)
调用构造函数实例化 bean;
bean 的依赖注入;
处理 Aware 接口;
Bean 的 BeanPostProcessor 的前置方法;
初始化方法(initializingBean、init-method);
Bean 的 BeanPostProcessor 的后置方法;
销毁 bean。

@Autowired 和 @Resource 区别?

都是将 Bean 注入到容器中的
Autowired:先 ByType,再 ByName  Spirng 提供  作用范围:可以在字段、构造器、setter
Resource: 先 ByName,再 ByType	 JDK 官方提供	作用范围:只能在字段和 setter

Spring 中事务

声明式:@Transactional
本质是基于 AOP, 对方法前后进行拦截,在执行方法之前开启事务,在目标方法执行完毕后提交或回滚。
编程式:TransactionTemplate、TransactionManager
事务失效的场景:
	Spring 中事务是基于 AOP 代理实现的,当同一个类中的方法调用事务方法,即 this 调用会导致事务失效
	静态方法调用,这些是代理失效,
	方法不是 public 的,
	final、static 修饰,
	异常被捕获,(解决,手动抛出异常)
	抛出检查异常,(文件读取失败,默认是只会滚非受检异常)
	事务传播行为不支持

Spring 中事务传播机制?

七种
	Required:只能有一个事务
	Requires_new : 创建新的事务
	Support :调用者有事务,则加入,没有就普通执行
	never:有事务抛出异常
	nested:嵌套
	mandatory:强制有
	not_support:有就挂起

隔离级别
● 默认的隔离级别(使用后端数据库默认的隔离级别)
● 读未提交
● 读已提交
● 可重复读
● 串行化
@Transactional(rollbackFor = Exception.class)
@Transactional 注解默认回滚策略是只有在遇到RuntimeException(运行时异常) 或者 Error 时才会回滚事务,而不会回滚 Checked Exception(受检查异常)

Spring 中用到的设计模式?

工厂模式、代理模式、策略、单例模式、模板方法模式、适配器模式、责任链模式(SpringMVC)

● 工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。
● 代理模式实现 AOP,策略模式 JDK 和 Cglib
● 单例:Spring 中的 Bean 默认都是单例的
● 模板:xxxTemplate 等
● spring MVC 中也是用到了适配器模式适配
● 观察者模式:Spring 中的事件机制

Spring 解决循环依赖?

A 类中有 B 属性, B 类中有 A 属性

● 通过构造函数进行依赖注入时产生的循环依赖(TODO:待确认)
● 通过 setter 方法进行依赖注入且是原型模式产生的循环依赖(TODO:待确认)
● 通过 setter 方法依赖注入且是单例模式产生的循环依赖(Spring 解决了)(TODO:待确认)
其余都会报错
通过三级缓存解决
一级缓存存放成品对象;(实例化、属性初始化)
二级缓存存放半成品对象;(实例化、属性未初始化)
三级缓存存放bean的创建工厂;(ObjectFactory)(生成原始Bean 对象或代理对象,只对单例Bean生效)(创建 bean 的原始对象,属性未初始化,创建完成加入到二级缓存中)
● 只有一级缓存是无法解决循环依赖的;
● 在没有 AOP 的情况下,确实可以只使用一级和三级缓存来解决循环依赖问题。
● 有 AOP 时,二级缓存就可以避免同一个 bean 创建多个代理对象;
过程:对于 A 、B 两个相互依赖,在实例化 A 时,会创建ObjectFactory存入三级缓存,在创建 A 对象时,需要初始化 B;因此继续创建 B 的对象,同样会创建 ObjectFactory 存入三级缓存,B 需要注入 A,从三级缓存中获取 ObjectFactory 生成 A 对象完成 B 对象的创建,半成品A放入二级缓存中,再将 B 存入一级缓存,继续完成 A 的创建,存入一级缓存。
无法解决构造方法产生的循环依赖
Spring 中的 单例 Bean 是线程安全的吗?
Bean 是单例? 可以使用 Scope 注解 (@Scope(“singleton”) ) prototype 是多例
不是线程安全。若是其他的 service 之类的,他们都是无状态的,即不能被修改。对于普通变量可修改,则可能有线程安全。
可以使用多例或加锁解决。

在其它 Bean 之前加载?

BeanFactoryPostProcessor   @PostConstruct

如何统计一个 Bean 中的方法调用次数?

AOP (定义注解,统计)

SpringMVC

MVC?
model view controller
模型、视图、控制器;是一种软件设计的典范;对项目进行分层,视图层提供用户页面,模型层存储对象和数据,是业务 bean 和实体 bean,控制器用于处理转发用户请求。
SpringMVC的处理流程?
浏览器发送请求后,会被前端控制器 dispatcherServlet 处理,查询 handler 返回DispatcherServlet,
DispatcherServlet 再调用 adapter 执行 handler,返回视图和模型,DispatcherServlet将ModelAndView传给ViewReslover;ViewReslover解析后返回具体View;
DispatcherServlet根据View进行渲染视图,响应用户(不使用视图,通过 HttpMessageConverter 转为 json 返回)
流程说明:

  1. 客户端(浏览器)发送请求, DispatcherServlet拦截请求。
  2. DispatcherServlet 根据请求信息调用 HandlerMapping 。HandlerMapping 根据 URL 去匹配查找能处理的 Handler(也就是我们平常说的 Controller 控制器) ,并会将请求涉及到的拦截器和 Handler 一起封装。
  3. DispatcherServlet 调用 HandlerAdapter适配器执行 Handler 。
  4. Handler 完成对用户请求的处理后,会返回一个 ModelAndView 对象给DispatcherServlet,ModelAndView 顾名思义,包含了数据模型以及相应的视图的信息。Model 是返回的数据对象,View 是个逻辑上的 View。
  5. ViewResolver 会根据逻辑 View 查找实际的 View。
  6. DispaterServlet 把返回的 Model 传给 View(视图渲染)。
  7. 把 View 返回给请求者(浏览器)
    Spring MVC 的重要组件:
    DispatcherServlet(接收所有请求)
    HandlerMapping(找到对应方法)
    HandlerAdaptor(执行handler,处理参数和返回值)
    ViewResolver(视图解析)
    统一异常的处理:
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
    @ExceptionHandler(BaseException.class)
    public ResponseEntity<?> handleAppException(BaseException ex, HttpServletRequest request) {
      //......
    }

    @ExceptionHandler(value = ResourceNotFoundException.class)
    public ResponseEntity<ErrorReponse> handleResourceNotFoundException(ResourceNotFoundException ex, HttpServletRequest request) {
      //......
    }
}

使用 @ControllerAdvice + @ExceptionHandler 两个注解,会给所有或者指定的 Controller 织入异常处理的逻辑(AOP),当 Controller 中的方法抛出异常的时候,由被@ExceptionHandler 注解修饰的方法进行处理。

MyBatis

什么是ORM?

对象关系映射,即编程中对象与数据库中表的关系转换

MyBatis是半自动化的ORM框架
Hibernate 是全自动化,只需要定义好表中字段和对象,会自动处理 CRUD
半自动化:需要自己手动编写SQL

MyBatis是如何实现字段映射的?

MyBatis 通过 ResultSet 对象获取SQL 查询得到的结果,然后映射到Java对象中
字段映射方式:
	默认是使用列名映射Java中对象的属性
	若使用了别名,优先使用别名与对象属性映射
	使用ResultMap
	自定义 TypeHandler

‘#’ 和 ‘$’ 的区别?

MyBatis 获取参数值的两种方式
	$ : 对字符串或日期赋值时,需要手动添加单引号  order by  、 group by 后只能用 $
	# : 占位符的方式,MyBatis 会将其视为字符串
	预防 $ SQL 注入, 可进行参数验证

MyBatis 插件的运行原理?

基于 Interceptor、Invocation 和 Plugin
Interceptor:拦截器接口,定义了 MyBatis 插件的基本功能,初始化,拦截方法以及销毁方法
Invocation: SQL 语句、参数、返回值等信息
Plugin:执行SQL语句时,会将所有的插件封装成 Plugin 对象

运行流程?

	当 MyBatis 启动时,会将所有实现了 Interceptor 接口的插件进行初始化。
	初始化完成后会将所有插件和原生的 Executor 对象封装成一个 InvocationChain 对象
	每次执行 SQL 时,都会通过 InvocationChain 依次调用所有插件的 intercept 方法,实现对SQL语句的拦截和修改
	最后将修改后的SQL交由原始的 Executor 对象执行,并返回结果给调用方。

常见的 MyBatis 插件有哪些?

	PageHelper 分页插件
		当使用 PageHelper.startPage(int pageNum, int pageSize) 设置分页参数后,PageHelper 会将其存入 ThreadLocal 中
		在执行 query 时,从 ThreadLocal 中获取分页参数,通过修改 SQL 语句的方式动态拼接 limit,最后删除 ThreadLocal

MyBatis 仅可以编写针对 ParameterHandler、 ResultSetHandler、 StatementHandler、 Executor 这 4 种接口的插件,MyBatis 使用 JDK 的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是 InvocationHandler 的 invoke() 方法,当然,只会拦截那些你指定需要拦截的方法。
实现 MyBatis 的 Interceptor 接口并复写 intercept() 方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。

MyBatis 的工作原理?

定义配置文件,xml 或注解,解析配置文件
读取配置文件,实现对应功能
生成代理对象(JDKProxy)执行 execute 即执行SQL

Dao 接口的工作原理是 JDK 动态代理,MyBatis 运行时会使用 JDK 动态代理为 Dao 接口生成代理 proxy 对象,代理对象 proxy 会拦截接口方法,转而执行 MappedStatement 所代表的 sql,然后将 sql 执行结果返回。
Dao 接口里的方法可以重载,但是 Mybatis 的 xml 里面的 ID 不允许重复。

MyBatis 执行流程:

	①读取 MyBatis 配置文件 :mybatis-config.xml 加载运行环境和映射文件
	②创建会话工厂 SqlSessionFactory
	③会话工厂创建 SqlSession(包含执行 SQL 语句的所有方法)
	④操作数据库的接口,Executor 执行器,同时负责查询缓存的维护。
	⑤Executor 接口的执行方法中有一个 MappedStatement 类型参数,封装了映射信息
	⑥MappedStatement 会对输入参数映射封装
	⑦执行完后对输出结果映射封装

MyBatis 的缓存机制?

一级缓存和二级缓存,一级缓存是会话级的,会将查询的结果存储,若再次执行相同的SQL 就从缓存中获取
二级缓存是可以跨多个会话,是基于命名空间的,但不能用于多表查询,否则可能脏读。
MyBatis 不是直接从 JDBC 获取连接的,而是通过数据源来获取的,我们可以引入第三方 如 druid

MyBatis 的数据源?

其内置了三种数据源,分别是 JNDI,Pooled,Unpooled
一般情况下,我们使用 Hikari,若要增强监控功能,使用 Druid
自带的连接池具有三个缺点:
	空闲连接占用资源、连接池大小调优困难、连接泄露

MyBatis 是否支持延迟加载?

支持,MyBatis 会使用 Cglib 创建目标对象的代理对象,代理对象会进行判断是否加载了,若没有,则触发额外的查询,并将结果
填充到代理对象,再次查询可直接从代理对象中获取。

MyBatis 中如何执行批处理?

通过 BatchExecutor 实现

MyBatis 实现动态 SQL

标签

MyBatis 如何实现分页?

物理分页:SQL 中有 limit 
逻辑分页:查询所有,在结果集中分页
实现:1. SQL 中添加 limit 语句 (物理)
	  2. 基于 PageHelper 分页插件	(物理)
	  3. 基于 RowRounds (逻辑)
				用于分页查询的简单的 POJO 类,在内存中进行分页
	  4. 基于 MyBatis-Plus
			支持物理和逻辑分页,默认是物理

(1) MyBatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页;
(2) 可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,
(3) 也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用 MyBatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。

SpringBoot

Spring和SpringBoot 的区别?

Spring 是一个企业级的 Java 开发框架,具有容器管理,依赖注入。面向切面。事务管理等,
SpringBoot 能够简化 Spring 的开发和部署,具备自动配置,内置 Web 服务器等,具备一系列开箱即用的组件,快速开发。

约定大于配置:
● 自动配置:提供了大量的自动配置,无需自己手动配置依赖或环境
● 默认配置
● 约定优先配置:项目结构、命名规范等

SpringBoot 常用注解

@SpringBootApplication

(复合注解:@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan)
Spring 常见注解:
@Component、@Service、@Controller、@Repository
@Autowired、@Qualifier、@Scope、@Configuration、@ComponentScan、@Import
@Aspect、@Before、@After、@Around、@Pointcut
SpringMVC 常见注解:
@RequestMapping、@RequestBody、@RequestParam、@PathVariable、@RequestHeader、 @RestController

SpringBootStarter?

相当于开箱即用的组件,引入 starter 依赖,就能直接使用其中的功能
自定义实现:创建 Configuration 类,使用 @Configuration,定义需要的配置。
在 resources 包下创建META-INF/spring.factories文件,将配置类的路径添加到文件中。打包即可。
常见 SpringBoot starter:
● spring-boot-starter-web
● mybatis-spring-boot-starter
● dubbo-spring-boot-starter
● rocketmq-spring-boot-starter

SpringBoot 如何实现自动配置的?

由启动类上的 @SpringBootApplication 中的 @EnableAutoConfiguration 实现,它会通过 @Import 注解导入对应的配置选择器,会读取该项目和该项目引用的 jar 包的 classpath 路径下 META-INF/spring.factories 文件中所有配置的类的全类名,在这些配置类中所定义的 Bean 会根据注解所指定的条件按需加入 Spring 容器中。
例如 @ConditionalOnClass ,表明若有对应 class 则由 Spring 容器管理。

SringBoot 启动流程:

从 main 方法开始:
● 初始化配置:加载读取 classpath下所有的spring.factories配置文件,初始化配置对象; 通知监听者应用程序启动开始,创建环境对象environment,用于读取环境配置 如 application.yml
● 创建应用程序上下文 createApplicationContext ,创建 bean 工厂
● 刷新上下文
○ 配置 Spring 相关
○ 启动 tomcat
● 通知监听者-启动程序完成

补充
SpringBoot 执行流程:
主要分为两步:
● 初始化 SpringApplication 实例 ( new SpringApplication )
● 初始化 SpringBoot 项目启动 (run () )
public static ConfigurableApplicationContext run(Class<?>[] primarySources,String[] args){
return new SpringApplication(primarySources).run(args);
}
// ① new SpringApplication(primarySources)
// ② new SpringApplication(primarySources).run(args)
SpringBoot 的启动流程包括 SpringApplication 的初始化以及项目的初始化启动,其中SpringApplication 的初始化主要是SpringBoot 的自动配置,包括加载 META/INF 类路径下的配置文件,用于加载 Bean,加载 Listener,确定项目启动类;SpringApplication 的启动主要是启动监听器,加载环境(配置文件),创建上下文,刷新上下文,实例化 Bean 以及启动 tomcat,通知监听器启动完成。
初始化 SpringApplication 实例

● 判断当前项目类型:查看 Classpath 类路径下是否存在特征类, 判断是 MVC 应用还是 WebFlux 交互式应用
● ApplicationContextInitializer :设置应用的初始化器,会使用 Spring 类加载器加载 META-INF/spring.factories 类路径下的配置文件
● 同上,加载所有监听器
● 设置项目启动类
初始化 SpringBoot 项目启动

● 获取 SpringApplication 初始化过程中的监听器并运行
● (prepareEnvironment)设置项目环境,加载 application.properties 等配置文件
● 创建上下文,用于加载 Bean
● 准备上下文
● 刷新上下文:实例化 Bean,启动 tomcat
● 通知监听器,启动完成

SpringCloud

SpringCloud 是构建分布式系统中的微服务架构的框架,它提供了服务注册、服务发现、负载均衡、网关、断路器等。

组件

SpringCloud 5大组件? SpringCloudAlibaba?
注册中心:Eureka Nacos
负载均衡:Ribbon Ribbon
Fegin:远程调用 OpenFegin
服务熔断:Hystrix sentinel
网关:zuul/gateway gateway

注册中心:服务注册和发现

即: 服务注册:服务提供者将自己的信息注册到 eureka ,由 eureka 保存这些信息,如服务名称、ip、端口等。
	 服务发现:消费者向 eureka 拉取服务列表信息,若有集群,根据负载均衡选一个发起调用。
	 服务监控:服务提供者会每隔30s 向 eureka 发送心跳,报告健康状态,若 eureka 90s 内未收到心跳,则将其剔除。
nacos 与 eureka 区别?
	都支持服务注册、服务拉取、心跳检测;
	nacos 支持服务端主动检测提供者状态,主动推送消息,及时更新服务列表;其支持配置中心

负载均衡:

Fegin 远程调用会使用 Ribbon 负载均衡
	负载均衡策略:轮询、随机、根据权重、区域敏感策略...
	自定义方式实现:实现 IRule 接口、配置文件设置

● 简单轮询
● 加权轮询
● 简单随机
● 加权随机
● 一致性哈希
● 最小活跃数
如何实现一直均衡给一个用户
采用一致性哈希,根据用户的 ip、或用户信息等进行哈希算法

服务熔断

服务出现响应时间过慢或者长时间不可用,导致调用其服务的其他服务也崩溃,导致服务雪崩
解决:快速响应失败
在 SpringCloud 中可以采用 Hystrix,当失败到达一定阈值,启动熔断机制

降级

降低服务器压力,减少请求,或快速响应失败

限流

并发大、防止用户恶意刷接口。
限流实现方式:
	tomcat 设置最大连接数
	nginx 漏桶算法  √  
		(桶里存储大量请求,控制速率以固定速率漏出请求)
	网关 令牌桶算法  √  
		(与漏桶算法不同的是,会先申请令牌才能被处理,每次令牌生成个数有限制,可能每次最多处理固定个数)
			(存储在 Redis 中)
	自定义拦截器 √

CAP:

分布式系统有三个指标:
	Consistency:用户访问任意节点,数据必须一致
	Availability:用户访问任意健康节点,都能得到响应,而非超时或拒绝。
	Partition tolerance:因网络故障或其他原因导致该节点与其他节点失去连接,形成独立分区。

Base理论:

Base 理论是对 CAP 的一种解决思路,包含三个思想:
	Basically Available (基本可用):分布式系统出现故障时,允许损失部分可用性,即保证核心可用
	Soft State(软状态):在一定时间内,允许出现中间状态,即临时的不一致状态
	Eventually Consistent(最终一致性):在软状态结束后,最终达到数据一致性

解决分布式事务的思想和模型:
最终一致性:各分支事务分别执行提交,如果有不一致的情况,再恢复数据(AP)
强一致性: 各分支事务执行完不提交,等待彼此结果,最后统一提交或回滚(CP)

分布式事务解决方案:

Seata 框架(XA、AT、TCC)
	Seata 事务管理中三个重要角色:
		TC - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。
		TM - 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。
		RM - 资源管理器:管理分支事务处理的资源,注册到 TC 上报告分支事务的状态,驱动分支事务提交或回滚。
	XA:(CP)
		由 TM 开启全局事务,然后调用各分支,各分支注册到 TC,各分支执行SQL后(不提交),向 TC 报告事务状态;
		TM 进行提交或回滚全局事务,TC 检测各分支状态,通知各 RM 提交或回滚。
	AT:(AP)(弥补了XA 模型中资源锁定周期过长的缺陷)
		由 TM 开启全局事务,然后调用各分支,各分支注册到 TC,各分支执行SQL并提交,
		记录更新前后的快照到 undolog,再向 TC 报告事务状态;TM 进行提交或回滚全局事务,
		TC 检测各分支状态,通知各 RM 提交或回滚。(提交:删除 log; 回滚:读取log 进行恢复)
	TCC:(AP)
		Try:资源检测和预留
		Confirm:完成资源操作业务,Try成功,Confirm 也成功
		Cancel:预留资源的释放
		由 TM 开启全局事务,然后调用各分支,各分支注册到 TC,各分支进行资源预留,再向 TC 报告事务状态;
		TM 进行提交或回滚全局事务,TC 检测各分支状态,通知各RM 提交或回滚
			提交(Confirm);回滚(Cancel)
		三步需要手动编码实现。

分布式接口的幂等性如何设计?

幂等:重复调用方法和单次调用结果一致;例如:下单时准备提交订单重复点了多次(网络波动)
解决:
	若依据数据库唯一索引,可解决新增操作,即不能重复插入相同数据。
	token + redis:解决新增和修改
		如 创建商品、提交订单、转账、支付等操作
		第一次请求时服务端生成一个 token 存储到 redis 中并返回给客户端,当客户端第二次请求时携带 token 时;
		服务端验证 token ,若存在则删除 redis 中的 token 进入下一步 ;不存在直接返回
	分布式锁(获取锁失败直接返回)

分布式任务调度

xxl-job
 路由策略:(页面中直接设置)轮询、随机、一致性 hash、故障转移、分片广播(对集群中所有机器都执行任务)
 任务失败解决:路由策略 故障转移 + 失败重试;  查看日志 --- 报警邮件  (均在 xxl-job 页面设置)
 有大量任务需要同时执行:路由策略使用 分片广播(任务取模由分片执行)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值