Redis如何实现高可用架构?_第2页回答

2020-12-23 17:39发布

16条回答
魏魏姐
2楼 · 2020-12-24 10:48

1.要看你的业务复杂度来确定如何搭建。简单的可以采用redis的master-slave构架,实现简单的读高可用,写入不是高可用。

2.可以采用对master采用keepalived监控的方式,来实现master当机时的热切换,redis本身也带了一个master的热备机制

3采用redis的cluster方案,实现负载分离与高可用的方式。(这个方案最少需要3台机器,如果集群较小,配置较为方便。网上现在的攻略较多。)


小橘子
3楼 · 2020-12-24 11:00

哨兵(Sentinel)是 redis 的高可用性解决方案,前面我们讲的主从复制它是高可用的基础,需要人工介入才能完成故障转移,哨兵可以解决这个问题,在主从复制情况下,当主节点发生故障时,哨兵可以自动的发现故障并且完成故障转移,实现真正的 redis 高可用。在哨兵集群中,哨兵会监视所有的 redis 服务器和其他 sentinel 节点状态,来保证 redis 的高可用。


梵梵
4楼 · 2020-12-24 19:58

公司的业务在大量的使用redis,访问量大的业务我们有在使用codis集群,redis 3.0集群,说到redis 3.0集群,我们线上已经跑了半年多了,集群本身没有出现过任务问题,但是由于我们这个业务是海外的,集群建在aws的ec2上,由于ec2的网络抖动或者ec2本身的原因,导致主从切换,目前aws的技术正在跟进,这个集群目前的QPS 50w+,集群本身已经做到了高可用和横向扩展,但是,实际情况一些小的业务没必要上集群,单个实例就可以满足业务需求,那么我们就要想办法如何保证单个实例的高可用,最近也在看相关的文档,做一些测试,大家有在使用redis主从+lvs 漂VIP的方案,也有使用redis主从+哨兵 漂VIP的方案,甚至有在代码逻辑做故障切换等等,各种各样的方案都有,下面我介绍一下redis主从+哨兵 漂VIP的方案,后面我们打算线上大规模的使用这个方案。

小蹲蹲
5楼 · 2020-12-25 08:47

不单单是redis,所有的可用都是要集群.这样才能保障某个节点不能工作时。其他节点仍能正常工作.redis的一般最少要3主,3从.6个节点。其中3个主,3个从。正常情况靠3个主节点工作。当超过半数。也就是2个点都无法与第3个节点通信时。这个第3个节点就被认为不能正常干工作.它的从节点开始代替。继续工作。另外3个主节点访问访问任何节点都可以正常工作.

我想吃肉
6楼 · 2020-12-25 09:16

1 题记

Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。

如今,互联网业务的数据正以更快的速度在增长,数据类型越来越丰富,这对数据处理的速度和能力提出了更高要求。Redis 是一种开源的内存非关系型数据库,给开发人员带来的体验是颠覆性的。在自始至终的设计过程中,都充分考虑高性能,这使得 Redis 成为当今速度最快的 NoSQL 数据库。

考虑高性能的同时,高可用也是很重要的考虑因素。互联网 7x24 无间断服务,在故障期间以最快的速度 Failover,能给企业带来最小的损失。

那么,在实际应用中,都有哪些高可用架构呢?架构之间有何优劣?我们应该怎么取舍?有哪些最佳实践?

二、Sentinel (哨兵)原理

在讲解 Redis 高可用方案之前,我们先来看看 Redis Sentinel 原理(redis.io/topics/sentine)是怎么样的。

Sentinel 集群通过给定的配置文件发现 master,启动时会监控 master。通过向 master 发送 info 信息获得该服务器下面的所有从服务器。

Sentinel 集群通过命令连接向被监视的主从服务器发送 hello 信息 (每秒一次),该信息包括 Sentinel 本身的 IP、端口、id 等内容,以此来向其他 Sentinel 宣告自己的存在。

Sentinel 集群通过订阅连接接收其他 Sentinel 发送的 hello 信息,以此来发现监视同一个主服务器的其他 Sentinel;集群之间会互相创建命令连接用于通信,因为已经有主从服务器作为发送和接收 hello 信息的中介,Sentinel 之间不会创建订阅连接。

Sentinel 集群使用 ping 命令来检测实例的状态,如果在指定的时间内(down-after-milliseconds)没有回复或则返回错误的回复,那么该实例被判为下线。

当 failover 主备切换被触发后,failover 并不会马上进行,还需要 Sentinel 中的大多数 Sentinel 授权后才可以进行 failover,即进行 failover 的 Sentinel 会去获得指定 quorum 个的 Sentinel 的授权,成功后进入 ODOWN 状态。如在 5 个 Sentinel 中配置了 2 个 quorum,等到 2 个 Sentinel 认为 master 死了就执行 failover。

Sentinel 向选为 master 的 slave 发送 SLAVEOF NO ONE 命令,选择 slave 的条件是 Sentinel 首先会根据 slaves 的优先级来进行排序,优先级越小排名越靠前。如果优先级相同,则查看复制的下标,哪个从 master 接收的复制数据多,哪个就靠前。如果优先级和下标都相同,就选择进程 ID 较小的。

Sentinel 被授权后,它将会获得宕掉的 master 的一份最新配置版本号 (config-epoch),当 failover 执行结束以后,这个版本号将会被用于最新的配置,通过广播形式通知其它 Sentinel,其它的 Sentinel 则更新对应 master 的配置。

1 到 3 是自动发现机制:

以 10 秒一次的频率,向被监视的 master 发送 info 命令,根据回复获取 master 当前信息。

以 1 秒一次的频率,向所有 redis 服务器、包含 Sentinel 在内发送 PING 命令,通过回复判断服务器是否在线。

以 2 秒一次的频率,通过向所有被监视的 master,slave 服务器发送当前 Sentinel master 信息的消息。

4 是检测机制,5 和 6 是 failover 机制,7 是更新配置机制。[1]

三、Redis 高可用架构

讲解完 Redis Sentinel 原理之后,接下来讲解常用的 Redis高可用架构

Redis Sentinel 集群 + 内网 DNS + 自定义脚本

Redis Sentinel 集群 + VIP + 自定义脚本

封装客户端直连 Redis Sentinel 端口

JedisSentinelPool,适合 Java

PHP 基于 phpredis 自行封装

Redis Sentinel 集群 + Keepalived/Haproxy

Redis M/S + Keepalived

Redis Cluster

Twemproxy

Codis


帅帅马
7楼 · 2020-12-27 20:16

Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。

如今,互联网业务的数据正以更快的速度在增长,数据类型越来越丰富,这对数据处理的速度和能力提出了更高要求。Redis 是一种开源的内存非关系型数据库,给开发人员带来的体验是颠覆性的。在自始至终的设计过程中,都充分考虑高性能,这使得 Redis 成为当今速度最快的 NoSQL 数据库。

考虑高性能的同时,高可用也是很重要的考虑因素。互联网 7x24 无间断服务,在故障期间以最快的速度 Failover,能给企业带来最小的损失。

那么,在实际应用中,都有哪些高可用架构呢?架构之间有何优劣?我们应该怎么取舍?有哪些最佳实践?

二、Sentinel (哨兵)原理

在讲解 Redis 高可用方案之前,我们先来看看 Redis Sentinel 原理(redis.io/topics/sentine)是怎么样的。

Sentinel 集群通过给定的配置文件发现 master,启动时会监控 master。通过向 master 发送 info 信息获得该服务器下面的所有从服务器。

Sentinel 集群通过命令连接向被监视的主从服务器发送 hello 信息 (每秒一次),该信息包括 Sentinel 本身的 IP、端口、id 等内容,以此来向其他 Sentinel 宣告自己的存在。

Sentinel 集群通过订阅连接接收其他 Sentinel 发送的 hello 信息,以此来发现监视同一个主服务器的其他 Sentinel;集群之间会互相创建命令连接用于通信,因为已经有主从服务器作为发送和接收 hello 信息的中介,Sentinel 之间不会创建订阅连接。

Sentinel 集群使用 ping 命令来检测实例的状态,如果在指定的时间内(down-after-milliseconds)没有回复或则返回错误的回复,那么该实例被判为下线。

当 failover 主备切换被触发后,failover 并不会马上进行,还需要 Sentinel 中的大多数 Sentinel 授权后才可以进行 failover,即进行 failover 的 Sentinel 会去获得指定 quorum 个的 Sentinel 的授权,成功后进入 ODOWN 状态。如在 5 个 Sentinel 中配置了 2 个 quorum,等到 2 个 Sentinel 认为 master 死了就执行 failover。

Sentinel 向选为 master 的 slave 发送 SLAVEOF NO ONE 命令,选择 slave 的条件是 Sentinel 首先会根据 slaves 的优先级来进行排序,优先级越小排名越靠前。如果优先级相同,则查看复制的下标,哪个从 master 接收的复制数据多,哪个就靠前。如果优先级和下标都相同,就选择进程 ID 较小的。

Sentinel 被授权后,它将会获得宕掉的 master 的一份最新配置版本号 (config-epoch),当 failover 执行结束以后,这个版本号将会被用于最新的配置,通过广播形式通知其它 Sentinel,其它的 Sentinel 则更新对应 master 的配置。

1 到 3 是自动发现机制:

以 10 秒一次的频率,向被监视的 master 发送 info 命令,根据回复获取 master 当前信息。

以 1 秒一次的频率,向所有 redis 服务器、包含 Sentinel 在内发送 PING 命令,通过回复判断服务器是否在线。

以 2 秒一次的频率,通过向所有被监视的 master,slave 服务器发送当前 Sentinel master 信息的消息。

4 是检测机制,5 和 6 是 failover 机制,7 是更新配置机制。[1]

三、Redis 高可用架构

讲解完 Redis Sentinel 原理之后,接下来讲解常用的 Redis高可用架构

Redis Sentinel 集群 + 内网 DNS + 自定义脚本

Redis Sentinel 集群 + VIP + 自定义脚本

封装客户端直连 Redis Sentinel 端口

JedisSentinelPool,适合 Java

PHP 基于 phpredis 自行封装

Redis Sentinel 集群 + Keepalived/Haproxy

Redis M/S + Keepalived

Redis Cluster

Twemproxy

Codis


慕容
8楼 · 2020-12-30 00:11

1 、题记  

Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。

如今,互联网业务的数据正以更快的速度在增长,数据类型越来越丰富,这对数据处理的速度和能力提出了更高要求。Redis 是一种开源的内存非关系型数据库,给开发人员带来的体验是颠覆性的。在自始至终的设计过程中,都充分考虑高性能,这使得 Redis 成为当今速度最快的 NoSQL 数据库。

    

考虑高性能的同时,高可用也是很重要的考虑因素。互联网 7x24 无间断服务,在故障期间以最快的速度 Failover,能给企业带来最小的损失。

那么,在实际应用中,都有哪些高可用架构呢?架构之间有何优劣?我们应该怎么取舍?有哪些最佳实践?

二、Sentinel (哨兵)原理

在讲解 Redis 高可用方案之前,我们先来看看 Redis Sentinel 原理(https://redis.io/topics/senti...。

  1. Sentinel 集群通过给定的配置文件发现 master,启动时会监控 master。通过向 master 发送 info 信息获得该服务器下面的所有从服务器。

  2. Sentinel 集群通过命令连接向被监视的主从服务器发送 hello 信息 (每秒一次),该信息包括 Sentinel 本身的 IP、端口、id 等内容,以此来向其他 Sentinel 宣告自己的存在。

  3. Sentinel 集群通过订阅连接接收其他 Sentinel 发送的 hello 信息,以此来发现监视同一个主服务器的其他 Sentinel;集群之间会互相创建命令连接用于通信,因为已经有主从服务器作为发送和接收 hello 信息的中介,Sentinel 之间不会创建订阅连接。

  4. Sentinel 集群使用 ping 命令来检测实例的状态,如果在指定的时间内(down-after-milliseconds)没有回复或则返回错误的回复,那么该实例被判为下线。

  5. 当 failover 主备切换被触发后,failover 并不会马上进行,还需要 Sentinel 中的大多数 Sentinel 授权后才可以进行 failover,即进行 failover 的 Sentinel 会去获得指定 quorum 个的 Sentinel 的授权,成功后进入 ODOWN 状态。如在 5 个 Sentinel 中配置了 2 个 quorum,等到 2 个 Sentinel 认为 master 死了就执行 failover。

  6. Sentinel 向选为 master 的 slave 发送 SLAVEOF NO ONE 命令,选择 slave 的条件是 Sentinel 首先会根据 slaves 的优先级来进行排序,优先级越小排名越靠前。如果优先级相同,则查看复制的下标,哪个从 master 接收的复制数据多,哪个就靠前。如果优先级和下标都相同,就选择进程 ID 较小的。

  7. Sentinel 被授权后,它将会获得宕掉的 master 的一份最新配置版本号 (config-epoch),当 failover 执行结束以后,这个版本号将会被用于最新的配置,通过广播形式通知其它 Sentinel,其它的 Sentinel 则更新对应 master 的配置。

1 到 3 是自动发现机制:

  • 以 10 秒一次的频率,向被监视的 master 发送 info 命令,根据回复获取 master 当前信息。

  • 以 1 秒一次的频率,向所有 redis 服务器、包含 Sentinel 在内发送 PING 命令,通过回复判断服务器是否在线。

  • 以 2 秒一次的频率,通过向所有被监视的 master,slave 服务器发送当前 Sentinel master 信息的消息。

4 是检测机制,5 和 6 是 failover 机制,7 是更新配置机制。[1]

三、Redis 高可用架构

讲解完 Redis Sentinel 原理之后,接下来讲解常用的 Redis 高可用架构

  • Redis Sentinel 集群 + 内网 DNS + 自定义脚本

  • Redis Sentinel 集群 + VIP + 自定义脚本

  • 封装客户端直连 Redis Sentinel 端口

  • JedisSentinelPool,适合 Java

  • PHP 基于 phpredis 自行封装

  • Redis Sentinel 集群 + Keepalived/Haproxy

  • Redis M/S + Keepalived

  • Redis Cluster

  • Twemproxy

  • Codis

接下来配合图文逐个讲解。

1、Redis Sentinel 集群 + 内网 DNS + 自定义脚本

Redis Sentinel 集群 + 内网 DNS + 自定义脚本

上图是已经在线上环境应用的方案。底层是 Redis Sentinel 集群,代理着 Redis 主从,Web 端连接内网 DNS 提供服务。内网 DNS 按照一定的规则分配,比如 xxxx.redis.cache/queue.port.xxx.xxx,第一个段表示业务简写,第二个段表示这是 Redis 内网域名,第三个段表示 Redis 类型,cache 表示缓存,queue 表示队列,第四个段表示 Redis 端口,第五、第六个段表示内网主域名。

当主节点发生故障,比如机器故障、Redis 节点故障或者网络不可达,Sentinel 集群会调用 client-reconfig-script 配置的脚本,修改对应端口的内网域名。对应端口的内网域名指向新的 Redis 主节点。

优点

秒级切换,在 10s 内完成整个切换操作

脚本自定义,架构可控

对应用透明,前端不用担心后端发生什么变化

缺点:

维护成本略高,Redis Sentinel 集群建议投入 3 台机器以上

依赖 DNS,存在解析延时

Sentinel 模式存在短时间的服务不可用

服务通过外网访问不可采用此方案

2、Redis Sentinel 集群 + VIP + 自定义脚本

Redis Sentinel 集群 + VIP + 自定义脚本

此方案和上一个方案相比,略有不同。第一个方案使用了内网 DNS,第二个方案把内网 DNS 换成了虚拟 IP。底层是 Redis Sentinel 集群,代理着 Redis 主从,Web 端通过 VIP 提供服务。在部署 Redis 主从的时候,需要将虚拟 IP 绑定到当前的 Redis 主节点。当主节点发生故障,比如机器故障、Redis 节点故障或者网络不可达,Sentinel 集群会调用 client-reconfig-script 配置的脚本,将 VIP 漂移到新的主节点上。

优点:

  • 秒级切换,在 5s 内完成整个切换操作

  • 脚本自定义,架构可控

  • 对应用透明,前端不用担心后端发生什么变化

缺点:

  • 维护成本略高,Redis Sentinel 集群建议投入 3 台机器以上

  • 使用 VIP 增加维护成本,存在 IP 混乱风险

  • Sentinel 模式存在短时间的服务不可用

  • 3.3 封装客户端直连 Redis Sentinel 端口

3、封装客户端直连 Redis Sentinel 端口

部分业务只能通过外网访问 Redis,上述两种方案均不可用,于是衍生出了这种方案。Web 使用客户端连接其中一台 Redis Sentinel 集群中的一台机器的某个端口,然后通过这个端口获取到当前的主节点,然后再连接到真实的 Redis 主节点进行相应的业务员操作。需要注意的是,Redis Sentinel 端口和 Redis 主节点均需要开放访问权限。如果前端业务使用 Java,有 JedisSentinelPool 可以复用;如果前端业务使用 PHP,可以在 phpredis 的基础上做二次封装。

优点:

  • 服务探测故障及时

  • DBA 维护成本低

缺点:

  • 依赖客户端支持 Sentinel

  • Sentinel 服务器和 Redis 节点需要开放访问权限

  • 对应用有侵入性

4、Redis Sentinel 集群 + Keepalived/Haproxy

Redis Sentinel 集群 + Keepalived/Haproxy

底层是 Redis Sentinel 集群,代理着 Redis 主从,Web 端通过 VIP 提供服务。当主节点发生故障,比如机器故障、Redis 节点故障或者网络不可达,Redis 之间的切换通过 Redis Sentinel 内部机制保障,VIP 切换通过 Keepalived 保障。

优点:

  • 秒级切换

  • 对应用透明

缺点:

  • 维护成本高

  • 存在脑裂

  • Sentinel 模式存在短时间的服务不可用

5、Redis M/S + Keepalived

Redis M/S + Keepalived

此方案没有使用到 Redis Sentinel。此方案使用了原生的主从和 Keepalived,VIP 切换通过 Keepalived 保障,Redis 主从之间的切换需要自定义脚本实现。

优点:

  • 秒级切换

  • 对应用透明

  • 部署简单,维护成本低

缺点:

  • 需要脚本实现切换功能

  • 存在脑裂

6、Redis Cluster

Redis Cluster

From: http://intro2libsys.com/focus...

Redis 3.0.0 在 2015 年 4 月 2 日正式发布,距今已有两年多的时间。Redis 集群采用 P2P 模式,无中心化。把 key 分成 16384 个 slot,每个实例负责一部分 slot。客户端请求对应的数据,若该实例 slot 没有对应的数据,该实例会转发给对应的实例。另外,Redis 集群通过 Gossip 协议同步节点信息。

优点:

  • 组件 all-in-box,部署简单,节约机器资源

  • 性能比 proxy 模式好

  • 自动故障转移、Slot 迁移中数据可用

  • 官方原生集群方案,更新与支持有保障

缺点:

  • 架构比较新,最佳实践较少

  • 多键操作支持有限(驱动可以曲线救国)

  • 为了性能提升,客户端需要缓存路由表信息

  • 节点发现、reshard 操作不够自动化

7、Twemproxy

Twemproxy

From: http://engineering.bloomreach...

多个同构 Twemproxy(配置相同)同时工作,接受客户端的请求,根据 hash 算法,转发给对应的 Redis。

Twemproxy 方案比较成熟了,之前我们团队长期使用此方案,但是效果并不是很理想。一方面是定位问题比较困难,另一方面是它对自动剔除节点的支持不是很友好。

优点:

  • 开发简单,对应用几乎透明

  • 历史悠久,方案成熟

缺点:

  • 代理影响性能

  • LVS 和 Twemproxy 会有节点性能瓶颈

  • Redis 扩容非常麻烦

  • Twitter 内部已放弃使用该方案,新使用的架构未开源

8、Codis

Codis

From: https://github.com/CodisLabs/...

Codis 是由豌豆荚开源的产品,涉及组件众多,其中 ZooKeeper 存放路由表和代理节点元数据、分发 Codis-Config 的命令;Codis-Config 是集成管理工具,有 Web 界面供使用;Codis-Proxy 是一个兼容 Redis 协议的无状态代理;Codis-Redis 基于 Redis 2.8 版本二次开发,加入 slot 支持,方便迁移数据。

优点:

  • 开发简单,对应用几乎透明

  • 性能比 Twemproxy 好

  • 有图形化界面,扩容容易,运维方便

缺点:

  • 代理依旧影响性能

  • 组件过多,需要很多机器资源

  • 修改了 Redis 代码,导致和官方无法同步,新特性跟进缓慢

  • 开发团队准备主推基于 Redis 改造的 reborndb

四、最佳实践

所谓的最佳实践,都是最适合具体场景的实践。

主推以下方案:

  • Redis Sentinel 集群 + 内网 DNS + 自定义脚本

  • Redis Sentinel 集群 + VIP + 自定义脚本

以下是实战过程中总结出的最佳实践:

  • Redis Sentinel 集群建议使用 >= 5 台机器

  • 不同的大业务可以使用一套 Redis Sentinel 集群,代理该业务下的所有端口

  • 根据不同的业务划分好 Redis 端口范围

  • 自定义脚本建议采用 Python 实现,扩展便利

  • 自定义脚本需要注意判断当前的 Sentinel 角色

  • 自定义脚本传入参数:

  • 自定义脚本需要远程 ssh 操作机器,建议使用 paramiko 库,避免重复建立 SSH 连接,消耗时间

  • 加速 SSH 连接,建议关闭以下两个参数

  • UseDNS no

  • GSSAPIAuthentication no

  • 微信或者邮件告警,建议 fork 一个进程,避免主进程阻塞

  • 自动切换和故障切换,所有操作建议在 15s 以内完成


相关问题推荐

  • 回答 36

    看军事新闻的同学应该都知道,一艘航空母舰作战能力虽然很强,但是弱点太明显,就是防御能力太差,单艘的航空母舰很少单独行动,通常航空母舰战斗群才是主要军事力量,你可以把单艘航母理解为的单体应用(防御差,机动性不好),把航母战斗群(调度复杂,维护...

  • 回答 31

    初始化过程细节:首先进行的就是将服务装载到容器中,然后准备注册服务。和Spring中启动过程类似,Spring启动时,将bean装载进容器中的时候,首先要解析bean。所以dubbo也是先读配置文件解析服务。解析服务:基于dubbo.jar内的META-INF/spring.handlers配置,...

  • 回答 27

    分布式事务 指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上 。换成比较容易理解的话,就是多个事务之间再保持事务的特性,也就是多个事务之间保证结果的一致性。分布式事务解决方案1、基于XA协议的两阶...

  • 什么是接口幂等性?2021-02-24 18:21
    回答 25

    1. 接口调用存在的问题        现如今我们的系统大多拆分为分布式SOA,或者微服务,一套系统中包含了多个子系统服务,而一个子系统服务往往会去调用另一个服务,而服务调用服务无非就是使用RPC通信或者restful,既然是通信,那么就有可能在服务器处理...

  • 回答 21

    前提是另外一个bean在bean容器中能找到

  • 回答 22

    1.View——表示层1.1准备数据实现方式:struts,servlet等1.2显示数据实现方式:extjs,jsp,jquery,html等2.Service——业务层实现方式:drools等3.Dao——数据访问层实现方式:hibernate、mybatis等...

  • SpringCloud Netflix和Sprin2020-11-12 09:41
    回答 8
    已采纳

    SpringCloud Netflix和SpringCloud Alibaba的区别如下图:

  • 回答 8

    redis为什么会有高并发问题redis的出身决定Redis是一种单线程机制的nosql数据库,基于key-value,数据可持久化落盘。由于单线程所以redis本身并没有锁的概念,多个客户端连接并不存在竞争关系,但是利用jedis等客户端对redis进行并发访问时会出现问题。发生连...

  • 回答 8

    用dubbo是想利用分布式集群的形式来提高服务的并发量,适用与大型项目.如果不用它还想提高并发另一个解决方案是springCloud+微服务.适合大中小型项目.当前对并发要求的项目还是很多的,所以dubbo用的也相对较多.建议如果是初学者可以跳过dubbo直接学习第二个方...

  • 回答 4

    不需要。一般是service分出去。然后其它放在web层即一个jar为service业务处理,一个为web层war包

  • 回答 7

    在回答这个问题之前,我们先回答一下什么是锁。普通的锁,即在单机多线程环境下,当多个线程需要访问同一个变量或代码片段时,被访问的变量或代码片段叫做临界区域,我们需要控制线程一个一个的顺序执行,否则会出现并发问题。如何控制呢?就是设置一个各个线...

  • 回答 6

     springmvc位于表现层,主要与浏览器进行交互(接收和响应浏览器请求)。springmvc采用MVC设计模型,模型由model、view和controller组成。         model(模型):对应JavaBean         view(视图):对应JSP         controller(控制器)...

没有解决我的问题,去提问