爱美容
当前位置: 首页 美容百科

cap的工作原理(神一样的CAP理论被应用在何方)

时间:2023-06-29 作者: 小编 阅读量: 2 栏目名: 美容百科

可用性非故障的节点在合理的时间内返回合理的响应。因此分布式系统理论上不可能选择CA架构,而必须选择CP或AP架构。相对ZK来说剔除了Leader节点选取和事务日志机制,这样更有利于维护和保证Eureka在运行的健壮性。服务注册应该选择AP还是CP对于服务注册来说,针对同一个服务,即使注册中心的不同节点保存的服务注册信息不相同,也并不会造成灾难性的后果。

【51CTO.com原创稿件】对于开发或设计分布式系统的架构师工程师来说,CAP 是必须要掌握的理论。

图片来自 Pexels

But:这个文章的重点并不是讨论 CAP 理论和细节,重点是说说 CAP 在微服务中的开发怎么起到一个指引作用,会通过几个微服务开发的例子说明,尽量的去贴近开发。

CAP 定理又被称为布鲁尔定理,是加州大学计算机科学家埃里克·布鲁尔提出来的猜想,后来被证明成为分布式计算领域公认的定理。

不过布鲁尔在出来 CAP 的时候并没有对 CAP 三者(Consistency,Availability,Partition tolerance)进行详细的定义,所以在网上也出现了不少对 CAP 不同解读的声音。

CAP 定理

CAP 定理在发展中存在过两个版本,我们以第二个版本为准:

在一个分布式系统中(指互相连接并共享数据的节点集合)中,当涉及到读写操作时,只能保证一致性(Consistence)、可用性(Availability)、分区容错性(Partition Tolerance)三者中的两个,另外一个必须被牺牲。

这个版本的 CAP 理论在探讨分布式系统,更加强调两点是互联和共享数据,其实也是理清楚了第一个版本中三选二的一些缺陷。

分布式系统不一定都存在互联和共享数据,例如 Memcached 集群相互间就没有存在连接和共享数据。

所以 Memcached 集群这类的分布式系统并不在 CAP 理论讨论的范围,而像 MySQL 集群就是互联和数据共享复制,因此 MySQL 集群是属于 CAP 理论讨论的对象。

一致性(Consistency)

一致性意思就是写操作之后进行读操作无论在哪个节点都需要返回写操作的值。

可用性(Availability)

非故障的节点在合理的时间内返回合理的响应。

分区容错性(Partition Tolerance)

当网络出现分区后,系统依然能够继续旅行社职责。

在分布式的环境下,网络无法做到 100% 可靠,有可能出现故障,因此分区是一个必须的选项。

如果选择了 CA 而放弃了 P,若发生分区现象,为了保证 C,系统需要禁止写入,此时就与 A 发生冲突;如果是为了保证 A,则会出现正常的分区可以写入数据,有故障的分区不能写入数据,则与 C 就冲突了。

因此分布式系统理论上不可能选择 CA 架构,而必须选择 CP 或 AP 架构。

分布式事务 BASE 理论

BASE 理论是对 CAP 的延伸和补充,是对 CAP 中的 AP 方案的一个补充,即使在选择 AP 方案的情况下,如何更好的最终达到 C。

BASE 是基本可用,柔性状态,最终一致性三个短语的缩写,核心的思想是即使无法做到强一致性,但应用可以采用适合的方式达到最终一致性。

CAP 在服务中实际的应用例子

理解貌似讲多了,项目的 CAP 可以参考下李运华的《从零开始学架构》的书里面的 21,22 章,比较详细的描绘了 CAP 的理论细节和 CAP 的版本演化过程。

这里着重讲解的是神一样的 CAP 在我们的微服务中怎么去指导和应用起来,大概会举几个平时常见的例子。

服务注册中心,是选择 CA 还是选择 CP?

服务注册中心解决的问题

在讨论 CAP 之前先明确下服务注册中心主要是解决什么问题:

  • 服务注册:实例将自身服务信息注册到注册中心,这部分信息包括服务的主机 IP 和服务的 Port,以及暴露服务自身状态和访问协议信息等。
  • 服务发现:实例请求注册中心所依赖的服务信息,服务实例通过注册中心,获取到注册到其中的服务实例的信息,通过这些信息去请求它们提供的服务。

目前作为注册中心的一些组件大致有:

  • Dubbo 的 Zookeeper
  • Spring Cloud 的 Eureka,Consul
  • RocketMQ 的 nameServer
  • HDFS 的 nameNode

目前微服务主流是 Dubbo 和 Spring Cloud,使用最多是 Zookeeper 和 Eureka,我们就来看看应该根据 CAP 理论怎么去选择注册中心。(Spring Cloud 也可以用 ZK,不过不是主流不讨论)

Zookeeper 选择 CP

Zookeeper 保证 CP,即任何时刻对 Zookeeper 的访问请求能得到一致性的数据结果,同时系统对网络分割具备容错性,但是它不能保证每次服务的可用性。

从实际情况来分析,在使用 Zookeeper 获取服务列表时,如果 ZK 正在选举或者 ZK 集群中半数以上的机器不可用,那么将无法获取数据。所以说,ZK 不能保证服务可用性。

Eureka 选择 AP

Eureka 保证 AP,Eureka 在设计时优先保证可用性,每一个节点都是平等的。

一部分节点挂掉不会影响到正常节点的工作,不会出现类似 ZK 的选举 Leader 的过程,客户端发现向某个节点注册或连接失败,会自动切换到其他的节点。

只要有一台 Eureka 存在,就可以保证整个服务处在可用状态,只不过有可能这个服务上的信息并不是最新的信息。

ZK 和 Eureka 的数据一致性问题

先要明确一点,Eureka 的创建初心就是为一个注册中心,但是 ZK 更多是作为分布式协调服务的存在。

只不过因为它的特性被 Dubbo 赋予了注册中心,它的职责更多是保证数据(配置数据,状态数据)在管辖下的所有服务之间保持一致。

所以这个就不难理解为何 ZK 被设计成 CP 而不是 AP,ZK 最核心的算法 ZAB,就是为了解决分布式系统下数据在多个服务之间一致同步的问题。

更深层的原因,ZK 是按照 CP 原则构建,也就是说它必须保持每一个节点的数据都保持一致。

如果 ZK 下节点断开或者集群中出现网络分割(例如交换机的子网间不能互访),那么 ZK 会将它们从自己的管理范围中剔除,外界不能访问这些节点,即使这些节点是健康的可以提供正常的服务,所以导致这些节点请求都会丢失。

而 Eureka 则完全没有这方面的顾虑,它的节点都是相对独立,不需要考虑数据一致性的问题,这个应该是 Eureka 的诞生就是为了注册中心而设计。

相对 ZK 来说剔除了 Leader 节点选取和事务日志机制,这样更有利于维护和保证 Eureka 在运行的健壮性。

再来看看,数据不一致性在注册服务中会给 Eureka 带来什么问题,无非就是某一个节点被注册的服务多,某个节点注册的服务少,在某一个瞬间可能导致某些 IP 节点被调用数多,某些 IP 节点调用数少的问题。

也有可能存在一些本应该被删除而没被删除的脏数据。

服务注册应该选择 AP 还是 CP

对于服务注册来说,针对同一个服务,即使注册中心的不同节点保存的服务注册信息不相同,也并不会造成灾难性的后果。

对于服务消费者来说,能消费才是最重要的,就算拿到的数据不是最新的数据,消费者本身也可以进行尝试失败重试。总比为了追求数据的一致性而获取不到实例信息整个服务不可用要好。

所以,对于服务注册来说,可用性比数据一致性更加的重要,选择 AP。

分布式锁,是选择 CA 还是选择 CP?

这里实现分布式锁的方式选取了三种:

  • 基于数据库实现分布式锁
  • 基于 Redis 实现分布式锁
  • 基于 Zookeeper 实现分布式锁

基于数据库实现分布式锁

构建表结构:

利用表的 UNIQUE KEY idx_lock(method_lock)作为唯一主键,当进行上锁时进行 Insert 动作,数据库成功录入则以为上锁成功,当数据库报出 Duplicate entry 则表示无法获取该锁。

不过这种方式对于单主却无法自动切换主从的 MySQL 来说,基本就无法实现 P 分区容错性(MySQL 自动主从切换在目前并没有十分完美的解决方案)。

可以说这种方式强依赖于数据库的可用性,数据库写操作是一个单点,一旦数据库挂掉,就导致锁的不可用。这种方式基本不在 CAP 的一个讨论范围。

基于 Redis 实现分布式锁

Redis 单线程串行处理天然就是解决串行化问题,用来解决分布式锁是再适合不过。

实现方式:

setnx key value Expire_time 获取到锁 返回 1 , 获取失败 返回 0

为了解决数据库锁的无主从切换的问题,可以选择 Redis 集群,或者是 Sentinel 哨兵模式,实现主从故障转移,当 Master 节点出现故障,哨兵会从 Slave 中选取节点,重新变成新的 Master 节点。

哨兵模式故障转移是由 Sentinel 集群进行监控判断,当 Maser 出现异常即复制中止,重新推选新 Slave 成为 Master,Sentinel 在重新进行选举并不在意主从数据是否复制完毕具备一致性。

所以 Redis 的复制模式是属于 AP 的模式。保证可用性,在主从复制中“主”有数据,但是可能“从”还没有数据。

这个时候,一旦主挂掉或者网络抖动等各种原因,可能会切换到“从”节点,这个时候可能会导致两个业务线程同时获取得两把锁。

这个过程如下:

  • 业务线程 -1 向主节点请求锁
  • 业务线程 -1 获取锁
  • 业务线程 -1 获取到锁并开始执行业务
  • 这个时候 Redis 刚生成的锁在主从之间还未进行同步
  • Redis 这时候主节点挂掉了
  • Redis 的从节点升级为主节点
  • 业务线程 -2 想新的主节点请求锁
  • 业务线程 -2 获取到新的主节点返回的锁
  • 业务线程 -2 获取到锁开始执行业务
  • 这个时候业务线程 -1 和业务线程 -2 同时在执行任务

上述的问题其实并不是 Redis 的缺陷,只是 Redis 采用了 AP 模型,它本身无法确保我们对一致性的要求。

Redis 官方推荐 Redlock 算法来保证,问题是 Redlock 至少需要三个 Redis 主从实例来实现,维护成本比较高。

相当于 Redlock 使用三个 Redis 集群实现了自己的另一套一致性算法,比较繁琐,在业界也使用得比较少。

能不能使用 Redis 作为分布式锁?这个本身就不是 Redis 的问题,还是取决于业务场景。

我们先要自己确认我们的场景是适合 AP 还是 CP , 如果在社交发帖等场景下,我们并没有非常强的事务一致性问题,Redis 提供给我们高性能的 AP 模型是非常适合的。

但如果是交易类型,对数据一致性非常敏感的场景,我们可能要寻找一种更加适合的 CP 模型。

基于 Zookeeper 实现分布式锁

刚刚也分析过,Redis 其实无法确保数据的一致性,先来看 Zookeeper 是否适合作为我们需要的分布式锁。

首先 ZK 的模式是 CP 模型,也就是说,当 ZK 锁提供给我们进行访问的时候,在 ZK 集群中能确保这把锁在 ZK 的每一个节点都存在。

这个实际上是 ZK 的 Leader 通过二阶段提交写请求来保证的,这个也是 ZK 的集群规模大了的一个瓶颈点。

①ZK 锁实现的原理

说 ZK 的锁问题之前先看看 Zookeeper 中几个特性,这几个特性构建了 ZK 的一把分布式锁。

ZK 的特性如下:

  • 有序节点:当在一个父目录下如 /lock 下创建 有序节点,节点会按照严格的先后顺序创建出自节点 lock000001,lock000002,lock0000003,以此类推,有序节点能严格保证各个自节点按照排序命名生成。
  • 临时节点:客户端建立了一个临时节点,在客户端的会话结束或会话超时,Zookepper 会自动删除该节点 ID。
  • 事件监听:在读取数据时,我们可以对节点设置监听,当节点的数据发生变化(1 节点创建 2 节点删除 3 节点数据变成 4 自节点变成)时,Zookeeper 会通知客户端。

结合这几个特点,来看下 ZK 是怎么组合分布式锁:

  • 业务线程 -1,业务线程 -2 分别向 ZK 的 /lock 目录下,申请创建有序的临时节点。
  • 业务线程 -1 抢到 /lock0001 的文件,也就是在整个目录下最小序的节点,也就是线程 -1 获取到了锁。
  • 业务线程 -2 只能抢到 /lock0002 的文件,并不是最小序的节点,线程 2 未能获取锁。
  • 业务线程 -1 与 lock0001 建立了连接,并维持了心跳,维持的心跳也就是这把锁的租期。
  • 当业务线程 -1 完成了业务,将释放掉与 ZK 的连接,也就是释放了这把锁。

②ZK 分布式锁的代码实现

ZK 官方提供的客户端并不支持分布式锁的直接实现,我们需要自己写代码去利用 ZK 的这几个特性去进行实现。

究竟该用 CP 还是 AP 的分布式锁

首先得了解清楚我们使用分布式锁的场景,为何使用分布式锁,用它来帮我们解决什么问题,先聊场景后聊分布式锁的技术选型。

无论是 Redis,ZK,例如 Redis 的 AP 模型会限制很多使用场景,但它却拥有了几者中最高的性能。

Zookeeper 的分布式锁要比 Redis 可靠很多,但他繁琐的实现机制导致了它的性能不如 Redis,而且 ZK 会随着集群的扩大而性能更加下降。

简单来说,先了解业务场景,后进行技术选型。

分布式事务,是怎么从 ACID 解脱,投身 CAP/BASE

如果说到事务,ACID 是传统数据库常用的设计理念,追求强一致性模型,关系数据库的 ACID 模型拥有高一致性 可用性,所以很难进行分区。

在微服务中 ACID 已经是无法支持,我们还是回到 CAP 去寻求解决方案,不过根据上面的讨论,CAP 定理中,要么只能 CP,要么只能 AP。

如果我们追求数据的一致性而忽略可用性这个在微服务中肯定是行不通的,如果我们追求可用性而忽略一致性,那么在一些重要的数据(例如支付,金额)肯定出现漏洞百出,这个也是无法接受。所以我们既要一致性,也要可用性。

都要是无法实现的,但我们能不能在一致性上作出一些妥协,不追求强一致性,转而追求最终一致性,所以引入 BASE 理论。

在分布式事务中,BASE 最重要是为 CAP 提出了最终一致性的解决方案,BASE 强调牺牲高一致性,从而获取可用性,数据允许在一段时间内不一致,只要保证最终一致性就可以了。

实现最终一致性

弱一致性:系统不能保证后续访问返回更新的值。需要在一些条件满足之后,更新的值才能返回。

从更新操作开始,到系统保证任何观察者总是看到更新的值的这期间被称为不一致窗口。

最终一致性:这是弱一致性的特殊形式;存储系统保证如果没有对某个对象的新更新操作,最终所有的访问将返回这个对象的最后更新的值。

BASE 模型

BASE 模型是传统 ACID 模型的反面,不同于 ACID,BASE 强调牺牲高一致性,从而获得可用性,数据允许在一段时间内的不一致,只要保证最终一致就可以了。

BASE 模型反 ACID 模型,完全不同 ACID 模型,牺牲高一致性,获得可用性或可靠性:Basically Available 基本可用。

支持分区失败(e.g. sharding碎片划分数据库)Soft state 软状态,状态可以有一段时间不同步,异步。

Eventually consistent 最终一致,最终数据是一致的就可以了,而不是时时一致。

分布式事务

在分布式系统中,要实现分布式事务,无外乎几种解决方案。方案各有不同,不过其实都是遵循 BASE 理论,是最终一致性模型:

  • 两阶段提交(2PC)
  • 补偿事务(TCC)
  • 本地消息表
  • MQ 事务消息

①两阶段提交(2PC)

还有一个数据库的 XA 事务,不过目前在真正的互联网中实际的应用基本很少,两阶段提交就是使用 XA 原理。

在 XA 协议中分为两阶段:

  • 事务管理器要求每个涉及到事务的数据库预提交(Precommit)此操作,并反映是否可以提交。
  • 事务协调器要求每个数据库提交数据,或者回滚数据。

说一下,为何在互联网的系统中没被改造过的两阶段提交基本很少被业界应用,最大的缺点就是同步阻塞问题。

在资源准备就绪之后,资源管理器中的资源就一直处于阻塞,直到提交完成之后,才进行资源释放。

这个在互联网高并发大数据的今天,两阶段的提交是不能满足现在互联网的发展。

还有就是两阶段提交协议虽然为分布式数据强一致性所设计,但仍然存在数据不一致性的可能。

例如:在第二阶段中,假设协调者发出了事务 Commit 的通知,但是因为网络问题该通知仅被一部分参与者所收到并执行了 Commit 操作,其余的参与者则因为没有收到通知一直处于阻塞状态,这时候就产生了数据的不一致性。

②补偿事务(TCC)

TCC 是服务化的两阶段编程模型,每个业务服务都必须实现 Try,Confirm,Cancel 三个方法,这三个方式可以对应到 SQL 事务中 Lock,Commit,Rollback。

相比两阶段提交,TCC 解决了几个问题:同步阻塞,引入了超时机制,超时后进行补偿,并不会像两阶段提交锁定了整个资源,将资源转换为业务逻辑形式,粒度变小。

因为有了补偿机制,可以由业务活动管理器进行控制,保证数据一致性。

Try 阶段:Try 只是一个初步的操作,进行初步的确认,它的主要职责是完成所有业务的检查,预留业务资源。

Confirm 阶段:Confirm 是在 Try 阶段检查执行完毕后,继续执行的确认操作,必须满足幂等性操作,如果 Confirm 中执行失败,会有事务协调器触发不断的执行,直到满足为止。

Cancel 是取消执行:在 Try 没通过并释放掉 Try 阶段预留的资源,也必须满足幂等性,跟 Confirm 一样有可能被不断执行。

一个下订单,生成订单扣库存的例子:

接下来看看,我们的下单扣减库存的流程怎么加入 TCC:

在 Try 的时候,会让库存服务预留 N 个库存给这个订单使用,让订单服务产生一个“未确认”订单,同时产生这两个预留的资源。

在 Confirm 的时候,会使用在 Try 预留的资源,在 TCC 事务机制中认为,如果在 Try 阶段能正常预留的资源,那么在 Confirm 一定能完整的提交。

在 Try 的时候,有任务一方为执行失败,则会执行 Cancel 的接口操作,将在 Try 阶段预留的资源进行释放。

这个并不是重点要论 TCC 事务是怎么实现,重点还是讨论分布式事务在 CAP BASE 理论的应用。

实现可以参考:

https://github.com/changmingxie/tcc-transaction

③本地消息表

本地消息表这个方案最初是 eBay 提出的,eBay 的完整方案:

https://queue.acm.org/detail.cfm?id=1394128

本地消息表这种实现方式应该是业界使用最多的,其核心思想是将分布式事务拆分成本地事务进行处理。

对于本地消息队列来说,核心就是将大事务转变为小事务,还是用上面下订单扣库存的例子说明:

  • 当我们去创建订单的时候,我们新增一个本地消息表,把创建订单和扣减库存写入到本地消息表,放在同一个事务(依靠数据库本地事务保证一致性)。
  • 配置一个定时任务去轮询这个本地事务表,扫描这个本地事务表,把没有发送出去的消息,发送给库存服务,当库存服务收到消息后,会进行减库存,并写入服务器的事务表,更新事务表的状态。
  • 库存服务器通过定时任务或直接通知订单服务,订单服务在本地消息表更新状态。

这里须注意的是,对于一些扫描发送未成功的任务,会进行重新发送,所以必须保证接口的幂等性。

本地消息队列是 BASE 理论,是最终一致性模型,适用对一致性要求不高的情况。

④MQ 事务

RocketMQ 在 4.3 版本已经正式宣布支持分布式事务,在选择 RokcetMQ 做分布式事务请务必选择 4.3 以上的版本。

RocketMQ 中实现了分布式事务,实际上是对本地消息表的一个封装,将本地消息表移动到了 MQ 内部。

事务消息作为一种异步确保型事务, 将两个事务分支通过 MQ 进行异步解耦,RocketMQ 事务消息的设计流程同样借鉴了两阶段提交理论。

整体交互流程如下图所示:

MQ 事务是对本地消息表的一层封装,将本地消息表移动到了 MQ 内部,所以也是基于 BASE 理论,是最终一致性模式,对强一致性要求不那么高的事务适用,同时 MQ 事务将整个流程异步化了,也非常适合在高并发情况下使用。

RocketMQ 选择同步/异步刷盘,同步/异步复制,背后的 CP 和 AP 思考

虽然同步刷盘/异步刷盘,同步/异步复制,并没有对 CAP 直接的应用,但在配置的过程中也一样涉及到可用性和一致性的考虑。

同步刷盘/异步刷盘

RocketMQ 的消息是可以做到持久化的,数据会持久化到磁盘,RocketMQ 为了提高性能,尽可能保证磁盘的顺序写入。

消息在 Producer 写入 RocketMQ 的时候,有两种写入磁盘方式:

  • 异步刷盘:消息快速写入到内存的 Pagecache,就立马返回写成功状态,当内存的消息累计到一定程度的时候,会触发统一的写磁盘操作。这种方式可以保证大吞吐量,但也存在着消息可能未存入磁盘丢失的风险。
  • 同步刷盘:消息快速写入内存的 Pagecahe,立刻通知刷盘线程进行刷盘,等待刷盘完成之后,唤醒等待的线程,返回消息写成功的状态。

同步复制/异步复制

一个 Broker 组有 Master 和 Slave,消息需要从 Master 复制到 Slave 上,所以有同步和异步两种复制方式:

  • 同步复制:是等 Master 和 Slave 均写成功后才反馈给客户端写成功状态。
  • 异步复制:是只要 Master 写成功即可反馈给客户端写成功状态。

异步复制的优点是可以提高响应速度,但牺牲了一致性 ,一般实现该类协议的算法需要增加额外的补偿机制。

同步复制的优点是可以保证一致性(一般通过两阶段提交协议),但是开销较大,可用性不好(参见 CAP 定理),带来了更多的冲突和死锁等问题。

值得一提的是 Lazy Primary/Copy 的复制协议在实际生产环境中是非常实用的。

RocketMQ 的设置要结合业务场景,合理设置刷盘方式和主从复制方式,尤其是 SYNC_FLUSH 方式,由于频繁的触发写磁盘动作,会明显降低性能。

通常情况下,应该把 Master 和 Slave 设置成 ASYNC_FLUSH 的刷盘方式,主从之间配置成 SYNC_MASTER 的复制方式,这样即使有一台机器出故障,仍然可以保证数据不丢。

总结

在微服务的构建中,永远都逃离不了 CAP 理论,因为网络永远不稳定,硬件总会老化,软件可能出现 Bug,所以分区容错性在微服务中是躲不过的命题。

可以这么说,只要是分布式,只要是集群都面临着 AP 或者 CP 的选择,但你很贪心的时候,既要一致性又要可用性,那只能对一致性作出一点妥协,也就是引入了 BASE 理论,在业务允许的情况下实现最终一致性。

究竟是选 CA 还是选 CP,真的在于对业务的了解,例如金钱,库存相关会优先考虑 CP 模型,例如社区发帖相关可以优先选择 AP 模型,这个说白了基于对业务的了解是一个选择和妥协的过程。

作者:陈于喆

简介:十余年的开发和架构经验,国内较早一批微服务开发实施者。曾任职国内互联网公司网易和唯品会高级研发工程师,后在创业公司担任技术总监/架构师,目前在洋葱集团任职技术研发副总监。

【51CTO原创稿件,合作站点转载请注明原文作者和出处为51CTO.com】

    推荐阅读
  • 怎么样让眼睛变大的最有效的方法(5种方法让你的眼睛变大)

    使用时先轻刷一层睫毛膏,趁睫毛膏尚未干掉时,将增长纤维的刷头转出,并将刷头上的白色细致纤维轻轻以滚动方式附着每根睫毛的尖端部位。再重复刷上黑头睫毛膏,电眼效果max。

  • 双减带给老师的挑战和机遇(双减之后教师面临的)

    7月24日,中共中央办公厅、国务院办公厅印发了《关于进一步减轻义务教育阶段学生作业负担和校外培训负担的意见》。面对教师陡然增加的负担,教育部相关负责人回应,将继续督促指导各地将教师减负工作同优化教师资源配置、深化教育教学改革等有机结合起来,健全教师减负长效机制,推动教师减负工作取得实效。“双减”政策明确提出,要构建教育良好生态,有效缓解家长焦虑情绪,促进学生全面发展、健康成长。

  • 我的世界橡胶甘蔗怎么杂交 我的世界粘性甘蔗种子

    杂交前需要合成作物架,用4个木棍合成,摆放成左右两列,合成2个作物架,由于杂交的几率比较低,所以需要准备多点作物架。拿着作物架在,每两个种了甘蔗的耕地的中间,放上两个作物架,作物架成十字交叉,代表此时在进行杂交。进行一段长时间的等待,等待甘蔗长大,等待杂交成功,注意杂交的地方很容易长杂草,如果长了杂草请尽快打掉,否则整个耕地都会蔓延杂草,需要重新杂交。

  • 娃哈哈新媒体营销策划(第13届娃哈哈营销策划大赛重磅来袭)

    为了丰富大学生的课余生活,引导和培养大学生创新精神和实践能力,4月23日18时30分,第十三届娃哈哈全国大学生营销策划大赛启动仪式于南宁职业技术学院大礼堂顺利举行。娃哈哈营销大赛为大学生提供了一个广阔的实践平台,推动教育与实践相结合,使同学们的创新意识得到激发。在此预祝娃哈哈营销策划大赛取得圆满成功,也祝本次参赛的团队都能够在比赛中取得佳绩!

  • 狮鹫怎么驯服(方舟生存进化手游狮鹫驯服技巧攻略)

    接下来我们就一起去研究一下吧!狮鹫怎么驯服方舟生存进化中狮鹫是高傲的守护兽,想要驯服狮鹫并不容易,必须获得狮鹫的尊重,这并不算容易的事,下面就来介绍一下怎么驯服狮鹫的方法吧。第一种方法:人物等级85级以上,并且不是可以获得全部尊重的!比如85级的,可能只能获取低等级狮鹫的尊重!

  • tabata间歇性训练的方法(什么是Tabata锻炼)

    各种研究得出结论,Tabata锻炼对健康有很多好处。有时您可能会达到最大强度,这可能会因肌肉松懈而导致受伤每周最多进行3-4次Tabata训练。Tabata锻炼以多种方式改善健康。此外,心脏病患者在开始Tabata锻炼之前还应听取医生的建议。在没有科学证据的情况下,对原始Tabata版本的修改可能弊大于利。人们可能会选择Tabata只是为了减肥,这不是它的实际用途。与传统HIIT相比,Tabata的强度水平更高,恢复时间更短。

  • s10和s9有什么区别(s10和s9有什么区别瑞思迈)

    vivoS9电池容量4000mAh,配置33W闪充。vivo官方宣布vivoS10系列于2021年7月15日正式发布,该手机代言人有Lisa、蔡徐坤、刘昊然。2021年7月15日,vivo召开了S10系列发布会,会上发布了新一代自拍旗舰vivoS10系列,其vivoS10系列依然采用了前置4400万像素AF双摄设计,仍然支持105度超广角,还有前置微缝式双柔光灯。

  • 专业版微博怎么设置(其实很简单)

    接下来我们就一起去了解一下吧!专业版微博怎么设置需要认证过才能成为专业版。专业版微博是为企业和机构定制的微博。新浪微博企业版是我们为企业、机构用户量身打造的服务平台。它具有更丰富的个性化页面展示功能设置,更精准的数据分析服务,以及更高效的沟通管理后台。我们期待新浪微博企业版能够帮助企业更便捷地与目标用户进行互动沟通,提升营销效果转化,挖掘更多商业机会。

  • 变速箱油到底多久换一次呢(变速箱油多久更换一次)

    如果需要更换变速箱油,查看用户的保养手册上如果有明确的更换周期,按照规定换油。如果变速箱油是终身免维护的,也一样要引起重视,终身免维护并不意味着变速箱油一直不用换。其实变速箱油不像机油那么黑,相比于机油甚至更为干净一点。所以车主千万不要忽略变速箱油,如果过长时间不更换,也会对变速箱造成一定的损伤,而且一些汽车的变速箱比发动机还要昂贵,修一次可能得要好几万元。

  • 恐惧症会遗传吗 幽闭恐惧症会遗传吗

    恐惧症是发病率非常高的一种心理疾病,而有许多患者并没有得到有效的治疗。导致恐惧症的因素恐惧症是各种因素的共同作用。恐惧症的典型症状是恐怖发作,并伴有强烈的生理反应。尽管患者知道这种恐惧是不合理的,但是没法控制。研究表明,在100名患者中40名患者可以彻底治疗,基本上没有什么后遗症。所以一定要及早治疗,效果好,造成的危害也小。