Redis五-哨兵
哨兵
导读
- Redis Sentinel是Redis的高可用实现方案:故障发现、故障自动转移、配置中心、客户端通知
- Redis Sentinel从Redis2.8版本开始才正式生产可用,之前版本生产不可用
- 尽可能在不同物理机上部署Redis Sentinel所有节点
- Redis Sentinel中的Sentinel节点个数应该为大于等于3且最好为奇数
- Redis Sentinel中的数据节点与普通数据节点没有区别
- 客户端初始化时连接的是Sentinel节点集合,不再是具体的Redis节点,但Sentinel只是配置中心不是代理
- Redis Sentinel通过三个定时任务实现了Sentinel节点对于主节点、从节点、其余Sentinel节点的监控
- Redis Sentinel在对节点做失败判定时分为主观下线和客观下线
- 看懂Redis Sentinel故障转移日志对于Redis Sentnel以及问题排查非常有帮助
- Redis Sentinel实现读写分离高可用可以依赖Sentinel节点的消息通知,获取Redis数据节点的状态变化
基本概念
名词 | 逻辑结构 | 物理结构 |
---|---|---|
主节点(master) | Redis 主服务 / 数据库 | 一个独立的 Redis 进程 |
从节点(slave) | Redis 从服务 / 数据库 | 一个独立的 Redis 进程 |
Redis 数据节点 | 主节点和从节点 | 主节点和从节点的进程 |
Sentinel 节点 | 监控 Redis 数据节点 | 一个独立的 Sentinel 进程 |
Sentinel 节点集合 | 若干 Sentinel 节点的抽象组合 | 若干 Sentinel 节点进程 |
Redis Sentinel | Redis 高可用实现方案 | Sentinel 节点集合和 Redis 数据节点进程 |
应用方 | 泛指一个或多个客户端 | 一个或者多个客户端进程或者线程 |
主从复制问题
优点:
作为主节点的一个备份,一旦主节点出了故障不可达的情况,从节点可以作为后备“顶”上来,并且保证数据尽量不丢失(主从复制是最终一致性)
从节点可以扩展主节点的读能力
缺点:
一旦主节点出现故障,需要手动将一个从节点晋升为主节点,同时需要修改应用方的主节点地址,还需要命令其他从节点去复制新的主节点,整个过程都需要人工干预-->Redis高可用问题
主节点的写能力、存储能力受到单机的限制-->Redis分布式问题
Redis Sentinel的高可用性
高可用:
- 判断节点不可达的机制
- 怎样保证只有一个被晋升为主节点
- 通知客户端新的主节点机制是否足够健壮
当主节点出现故障时,Redis Sentinel能自动完成故障发现和故障转移,并通知应用方,从而实现真正的高可用
Redis Sentinel是一个分布式架构,其中包含若干个Sentinel节点和Redis数据节点,每个Sentinel节点会对数据节点和其余Sentinel节点进行监控,
当它发现节点不可达时,会对节点做下线标识。如果被标识的是主节点,它还会和其他Sentinel节点进行“协商”,
当大多数Sentinel节点都认为主节点不可达时,它们会选举出一个Sentinel节点来完成自动故障转移的工作,同时会将这个变化实时通知给Redis应用方。
1主2从3哨兵
- 主节点出现故障,此时两个从节点与主节点失去连接,主从复制失败。
- 每个Sentinel节点通过定期监控发现主节点出现了故障
- Sentinel节点对主节点的故障达成一致,选举出sentinel-3节点作为领导者负责故障转移
- 对其执行slaveof no one命令使其成为新的主节点
- 原来的从节点(slave-1)成为新的主节点后,更新应用方的主节点信息,重新启动应用方
- 客户端命令另一个从节点(slave-2)去复制新的主节点(new-master)
- 待原来的主节点恢复后,让它去复制新的主节点。
- Sentinel领导者节点执行了故障转移
故障>协商>从节点1--slaveof no one--升主>通知client>从节点2复制新的主节点>原来的主节点恢复后复制新的主节点
Redis Sentinel具有以下几个功能:
- 监控(Monitoring):Sentinel节点会定期检测Redis数据节点的状态
- 通知(Notification):Sentinel节点会将故障转移后的结果通知给应用方
- 故障转移(Failover):实现自动的故障转移
- 配置中心(Configuration):在Redis Sentinel架构中,客户端连接的是Sentinel节点集合而不是直接连接的Redis数据节点
安装和部署
角色 | ip | port | 别名(为了后文中方便) |
---|---|---|---|
master | 127.0.0.1 | 6379 | 主节点或者 6379 节点 |
slave - 1 | 127.0.0.1 | 6380 | slave - 1 节点或者 6380 节点 |
slave - 2 | 127.0.0.1 | 6381 | slave - 2 节点或者 6381 节点 |
sentinel - 1 | 127.0.0.1 | 26379 | sentinel - 1 节点或者 26379 节点 |
sentinel - 2 | 127.0.0.1 | 26380 | sentinel - 2 节点或者 26380 节点 |
sentinel - 3 | 127.0.0.1 | 26381 | sentinel - 3 节点或者 26381 节点 |
部署数据节点
- 主节点
vi redis-6379.conf
port 6379
daemonize yes
logfile "/var/log/redis-6379.log"
dbfilename "dump-6379.rdb"
dir "/var/redis/data/"
- daemonize yes # 后台运行
- logfile "/var/log/redis-6379.log" # 日志文件
- dbfilename "dump-6379.rdb" # 持久化文件名
- dir "/var/redis/data/" # 持久化文件存放目录
redis-server redis-6379.conf
- 从节点
vi redis-6380.conf
port 6380
daemonize yes
logfile "/var/log/redis-6380.log"
dbfilename "dump-6380.rdb"
dir "/var/redis/data/"
slaveof 127.0.0.1 6379
vi redis-6381.conf
port 6381
daemonize yes
logfile "/var/log/redis-6381.log"
dbfilename "dump-6381.rdb"
dir "/var/redis/data/"
slaveof 127.0.0.1 6379
- slaveof 127.0.0.1 6379 # 从节点复制主节点的地址和端口
redis-server redis-6380.conf
redis-server redis-6381.conf
redis-cli -p 6379 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=491,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=491,lag=1
master_repl_offset:491
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:490
此时拓扑如下:
部署Sentinel节点
vi redis-sentinel-26379.conf # 26379、26380、26381的配置文件类似,只是端口不同
port 26379
daemonize yes
logfile "/var/log/26379.log"
dir /var/redis/data/
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
Sentinel节点的默认端口是26379
sentinel monitor mymaster 127.0.0.1 63792
sentinel-1节点需要监控127.0.0.1:6379这个主节点,
2代表判断主节点失败至少需要2个Sentinel节点同意,
mymaster是主节点的别名
超过了down-after-milliseconds配置的时间且没有有效的回复,则判定节点不可达
parallel-syncs就是用来限制在一次故障转移之后,每次向新的主节点发起复制操作的从节点个数
sentinel failover-timeout mymaster 180000 # 故障转移超时时间
sentinel auth-pass mymaster mypassword # 认证密码
sentinel notification-script mymaster /var/redis/notify.sh # 故障通知脚本,当故障转移发生时,会执行这个脚本
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh # 客户端重新配置脚本,当故障转移发生时,会执行这个脚本
启动:
redis-sentinel redis-sentinel-26379.conf
redis-server redis-sentinel-26379.conf --sentinel
redis-cli -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3
此时拓扑如下:
Seninel配置优化
Redis安装目录下有一个sentinel.conf,是默认的Sentinel节点配置文件
port 26381
daemonize yes
logfile "/var/log/26381.log"
dir "/var/redis/data"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
sentinel known-slave mymaster 127.0.0.1 6380
# Generated by CONFIG REWRITE
sentinel known-slave mymaster 127.0.0.1 6381
sentinel known-sentinel mymaster 127.0.0.1 26380 187ef7cee830e5728fdcf913682f8acc69bca9f6
sentinel known-sentinel mymaster 127.0.0.1 26379 131c66c696c7d604728d2102475dfce8b37d15b2
sentinel current-epoch 0
- 部署技巧
- Sentinel节点不应该部署在一台物理“机器”上
- 部署至少三个且奇数个的Sentinel节点
3个以上是通过增加Sentinel节点的个数提高对于故障判定的准确性,因为领导者选举需要至少一半加1个节点,奇数个节点可以在满足该条件的基础上节省一个节点
sentinel API
Sentinel节点是一个特殊的Redis节点,它有自己专属的API
sentinel masters # 查看所有被监控的主节点信息
sentinel master mymaster # 查看指定主节点的详细信息
sentinel slaves mymaster # 查看指定主节点的所有从节点信息
sentinel sentinels mymaster # 查看指定主节点的所有Sentinel节点信息
sentinel get-master-addr-by-name mymaster # 查看指定主节点的地址和端口
sentinel reset mymaster # 清除 Sentinel 内部关于 mymaster 的所有状态信息、重新发现并注册 mymaster 的从节点和哨兵节点(通过向主节点发送 ROLE 命令获取拓扑信息)
sentinel failover mymaster # 手动触发故障转移
sentinel ckquorum mymaster # 检查 Sentinel 集群是否可以就故障转移达成共识
sentinel flushconfig # 将Sentinel节点的配置强制刷到磁盘上,通常用于磁盘损坏导致配置丢失
sentinel remove mymaster # 移除监控的主节点
sentinel monitor mymaster 127.0.0.1 6379 2 # 添加监控的主节点,和配置文件的一致
实现原理
三个定时任务
Redis Sentinel通过三个定时监控任务完成对各个节点发现和监控
- 每隔10秒,每个Sentinel节点会向主节点和从节点发送info replication命令获取最新的拓扑结构-->master、slave
- 每隔1秒,每个Sentinel节点会向主节点、从节点以及其他Sentinel节点发送ping命令做一次心跳检测
- 每隔2秒,每个Sentinel节点会向Redis数据节点的__sentinel__:hello频道上发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息
简单的说,就两个作用
1. 了解其他的Sentinel节点信息
2. 了解其他Sentinel节点对于主节点的状态判断
具体细节:
每个 Sentinel 节点既是消息的发布者,也是订阅者。
Sentinel 会向所有已知的数据节点(master 和 slave)发送发布 / 订阅命令
Sentinel 启动时:
向所有已知的 master 和 slave 节点发送 SUBSCRIBE __sentinel__:hello 命令,订阅该频道。
定时任务触发时:
向所有已知的 master 和 slave 节点发送 PUBLISH __sentinel__:hello "消息内容" 命令,发布自身状态和主节点判断。
消息传递逻辑:
无论消息发布到 master 还是 slave,只要节点在线,订阅该频道的其他 Sentinel 都能收到消息(因为 Redis 的 Pub/Sub 是节点级别的,不依赖数据同步)。
主观下线和客观下线
主观下线
客观下线
当Sentinel主观下线的节点是主节点时,该Sentinel节点会通过sentinel is-master-down-by-addr命令向其他Sentinel节点询问对主节点的判断
当超过个数的Sentinel节点认为主节点确实有问题,这时该Sentinel节点会做出客观下线的决定,这样客观下线的含义是比较明显了,也就是大部分Sentinel节点都对主节点的下线做了同意的判定,那么这个判定就是客观的
例如sentinel-1节点对主节点做主观下线后,会向其余Sentinel节点发送该命令:
sentinel is-master-down-by-addr 127.0.0.1 6379 0 *
日志分析
先kill掉主节点,然后启动原主节点
2793:X 18 Jun 13:39:34.452 # +sdown master mymaster 127.0.0.1 6379 # Sentinel(进程 ID 2793)主观认为 mymaster 主节点(127.0.0.1:6379)下线(不可达)
2793:X 18 Jun 13:39:34.536 # +new-epoch 6 # 开启一个新的选举纪元(Epoch 6)
2793:X 18 Jun 13:39:34.539 # +vote-for-leader 187ef7cee830e5728fdcf913682f8acc69bca9f6 6 # # 当前 Sentinel 投票给节点 187ef7...(另一个 Sentinel)作为领导者
2793:X 18 Jun 13:39:34.539 # +odown master mymaster 127.0.0.1 6379 #quorum 2/2 # Sentinel 集群达成共识,认为 mymaster 客观下线。
2793:X 18 Jun 13:39:34.539 # Next failover delay: I will not start a failover before Wed Jun 18 13:45:34 2025 # 此次故障转移后,6分钟内不会再次发起故障转移
2793:X 18 Jun 13:39:35.616 # +config-update-from sentinel 127.0.0.1:26380 127.0.0.1 26380 @ mymaster 127.0.0.1 6379 # 从 Sentinel 节点 127.0.0.1:26380 接收新的配置信息。
2793:X 18 Jun 13:39:35.616 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6381 # 故障转移成功,新主节点切换为 127.0.0.1:6381。
2793:X 18 Jun 13:39:35.616 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381 # 新主节点(6381)开始管理从节点。
2793:X 18 Jun 13:39:35.616 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381 # 新主节点(6381)开始管理从节点。
2793:X 18 Jun 13:40:05.696 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381 # Sentinel 认为从节点(6379)下线。
2797:X 18 Jun 13:39:34.455 # +sdown master mymaster 127.0.0.1 6379 # +sdown:主观下线
2797:X 18 Jun 13:39:34.532 # +odown master mymaster 127.0.0.1 6379 #quorum 3/2 # +odown:Sentinel 集群达成共识,确认主节点客观下线
2797:X 18 Jun 13:39:34.532 # +new-epoch 6 # +new-epoch 6:开启一个新的选举纪元(Epoch),用于区分不同轮次的故障转移。
2797:X 18 Jun 13:39:34.532 # +try-failover master mymaster 127.0.0.1 6379 # +try-failover:尝试发起故障转移,但不立即执行。需要等待领导者选举完成。
2797:X 18 Jun 13:39:34.533 # +vote-for-leader 187ef7cee830e5728fdcf913682f8acc69bca9f6 6 # +vote-for-leader:投票给领导者
2797:X 18 Jun 13:39:34.538 # 127.0.0.1:26381 voted for 187ef7cee830e5728fdcf913682f8acc69bca9f6 6 # 其他 Sentinel 节点(127.0.0.1:26381 和 26379)也投票给 187ef7...
2797:X 18 Jun 13:39:34.540 # 127.0.0.1:26379 voted for 187ef7cee830e5728fdcf913682f8acc69bca9f6 6 # 其他 Sentinel 节点(127.0.0.1:26381 和 26379)也投票给 187ef7...
2797:X 18 Jun 13:39:34.605 # +elected-leader master mymaster 127.0.0.1 6379 # +elected-leader:获得多数票,当选为故障转移领导者
2797:X 18 Jun 13:39:34.605 # +failover-state-select-slave master mymaster 127.0.0.1 6379 # +failover-state-select-slave:领导者开始选择从节点作为新的主节点候选者。
2797:X 18 Jun 13:39:34.706 # +selected-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379 # +selected-slave:选中从节点 127.0.0.1:6381 作为新主节点。
2797:X 18 Jun 13:39:34.706 * +failover-state-send-slaveof-noone slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379 # +failover-state-send-slaveof-noone:向选中的从节点(6381)发送 SLAVEOF NO ONE 命令,使其成为独立主节点。
2797:X 18 Jun 13:39:34.783 * +failover-state-wait-promotion slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379 # +failover-state-wait-promotion:等待从节点(6381)完成主节点晋升
2797:X 18 Jun 13:39:35.543 # +promoted-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379 # +promoted-slave:从节点(6381)成功晋升为新主节点。
2797:X 18 Jun 13:39:35.543 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6379 # +failover-state-reconf-slaves:开始重新配置其他从节点,使其复制新主节点(6381)。--127.0.0.1 6379:原主节点的 IP 和端口(故障转移后,该节点将作为从节点存在)。
2797:X 18 Jun 13:39:35.614 * +slave-reconf-sent slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379 # +slave-reconf-sent:向从节点(6380)发送 SLAVEOF 命令,使其复制新主节点。
2797:X 18 Jun 13:39:36.622 * +slave-reconf-inprog slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379 # +slave-reconf-inprog:从节点(6380)正在与新主节点(6381)建立复制连接。
2797:X 18 Jun 13:39:36.623 * +slave-reconf-done slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379 # +slave-reconf-done:从节点(6380)完成配置,开始复制新主节点。
2797:X 18 Jun 13:39:36.678 # -odown master mymaster 127.0.0.1 6379 # -odown:取消原主节点(6379)的客观下线状态(但此时它仍是下线的)。
2797:X 18 Jun 13:39:36.678 # +failover-end master mymaster 127.0.0.1 6379 # +failover-end:故障转移流程结束
2797:X 18 Jun 13:39:36.678 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6381 # +switch-master:主节点已从 127.0.0.1:6379 切换为 127.0.0.1:6381。
2797:X 18 Jun 13:39:36.679 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381 # +slave:记录新的从节点列表
2797:X 18 Jun 13:39:36.679 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381 # +slave:记录新的从节点列表
2797:X 18 Jun 13:40:06.697 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381 # +sdown:原主节点(6379)作为从节点暂时不可达。
- 故障检测:Sentinel 先主观判断主节点下线(+sdown),后通过法定人数达成客观下线共识(+odown)。
- 领导者选举:Sentinel 通过投票选出负责故障转移的领导者(+elected-leader)。
- 新主选择与晋升:从从节点中选出最优节点(6381),并将其提升为新主(+promoted-slave)。
- 集群重组:通知其他从节点(6380、6379)复制新主(+slave-reconf-done)。
- 故障转移完成:更新集群拓扑(+switch-master),恢复服务可用性。
- 故障转移
Redis五-哨兵的更多相关文章
- Redis之哨兵机制(五)
什么是哨兵机制 Redis的哨兵(sentinel) 系统用于管理多个 Redis 服务器,该系统执行以下三个任务: · 监控(Monitoring): 哨兵(sentinel) 会不断 ...
- redis架构~哨兵模式
一 哨兵模式稳定版本 redis哨兵模式是redis自带的高可用框架,稳定版本为redis2.8以上二 哨兵模式建立 1 避免单点故障,建立启动多个哨兵进程 2 哨兵模式启动命令 redis-s ...
- redis的哨兵集群,redis-cluster
#主从同步redis主从优先1.保证数据安全,主从机器两份数据一主多从2.读写分离,缓解主库压力主redis,可读可写slave身份,只读 缺点1.手动主从切换假如主库挂了,得手动切换master ...
- redis:哨兵集群配置
最少配置1主2从3哨兵 一.引言 上一篇文章我们详细的讲解了Redis的主从集群模式,其实这个集群模式配置很简单,只需要在Slave的节点上进行配置,Master主节点的配置不需要做任何更改,但是有一 ...
- redis之哨兵集群
一.主从复制背景问题 Redis主从复制可将主节点数据同步给从节点,从节点此时有两个作用: 一旦主节点宕机,从节点作为主节点的备份可以随时顶上来. 扩展主节点的读能力,分担主节点读压力. 但是问题是: ...
- Redis五种数据结构简介
Redis五种结构 1.String 可以是字符串,整数或者浮点数,对整个字符串或者字符串中的一部分执行操作,对整个整数或者浮点执行自增(increment)或者自减(decrement)操作. 字符 ...
- redis五种数据类型的使用(zz)
redis五种数据类型的使用 redis五种数据类型的使用 (摘自:http://tech.it168.com/a2011/0818/1234/000001234478_all.shtml ) 1.S ...
- redis 五种数据结构详解(string,list,set,zset,hash)
redis 五种数据结构详解(string,list,set,zset,hash) Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存 ...
- redis五种数据类型的使用
redis五种数据类型的使用 redis五种数据类型的使用 (摘自:http://tech.it168.com/a2011/0818/1234/000001234478_all.shtml ) 1.S ...
- redis五种数据类型的使用场景
string 1.String 常用命令: 除了get.set.incr.decr mget等操作外,Redis还提供了下面一些操作: 获取字符串长度 往字符串append内容 设置和获取字符串的某一 ...
随机推荐
- Open diary(每天更新)
.col-md-8 img { display: none } .comment img { display: unset } 这是一个open diary,就是公开日记. 为什么标题用英文呢?因为觉 ...
- Cursor预测程序员行业倒计时:CTO应做好50%裁员计划
提供AI咨询+AI项目陪跑服务,有需要回复1 前两天跟几个业内同学做了一次比较深入的探讨,时间从15.00到21.00,足足6个小时! 其中有个问题特别有意思:从ChatGPT诞生到DeepSeek爆 ...
- AndrodStudio构建时报错Could not find com.android.tools.build:gradle:xxx
检查配置的版本号在maven仓库里有没有. maven仓库地址: https://repo1.maven.org/maven2/com/android/tools/build/gradle/ 选择需要 ...
- lua随写
--local util={}--function util.Split(str, sep)-- local sep, fields = sep or ":", {}-- loca ...
- (原创)[开源][.Net Framework 4.5] SimpleMVVM(极简MVVM框架)更新 v1.1,增加NuGet包
一.前言 意料之外,也情理之中的,在主业是传统行业的本人,技术的选型还是落后于时代. 这不,因现实需要,得将大库中的 WPF MVVM 相关部分功能拆分出来独立使用,想着来都来了,就直接开源得了,顺便 ...
- 康谋分享 | ADTF过滤器全面解析:构建、配置与数据处理应用
在ADTF (Automotive Data and Time-Triggered Framework)中,过滤器(Filter)扮演着数据处理的核心角色.过滤器是处理数据流的基本单元,它们接收.处理 ...
- Python 潮流周刊#98:t-string 语法被正式接纳了(摘要)
本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...
- js多线程new worker报错cannot be accessed from origin 问题
---- Web Workers 为 Web 前端网页上的脚本提供了一种能在后台进程中运行的方法.一旦它被创建,Web Workers 就可以通过 postMessage 向任务池发送任务请求,执行完 ...
- infiniswap用到的技术
infiniswap来自 NSDI'17,其代码主要用到以下技术: configfs(主要) configfs-用户空间控制的内核对象配置 https://www.kernel.org/doc/Doc ...
- java串口通信
实体 package com.hwd.campus.common.common.utils.http; import gnu.io.SerialPort; /** * 串口参数封装类 * @autho ...