keepalived搭建高可用

news/2025/12/9 22:12:45/文章来源:https://www.cnblogs.com/qylogs/p/19328554

一、HA集群

1.1 ha集群是什么

高可用集群,是有多台服务器节点组成的集群,通过冗余设计和故障自动切换,保证了核心服务,持续可用,减少了停机时间

  • 就是当一个提供网站的服务故障后,另外一台机器充当这个提供网站的角色

1.2 HA集群实现的几种方式

  • keepalived

二、keepalived详解

1、概述

1.1 简介

  • keepalived是一款基于VRRP协议的轻量级HA软件,核心功能是vip漂移和服务的健康检查,切换的速度快

  • LVS进行健康检查,这个keepalvied本身不具备负载均衡的功能,因此需要依赖在linux内核的LVS

  • VRRPv2协议来处理负载均衡集群的故障切换,这个完成集群节点之间的心跳检查,在集群节点故障时,将浮动ip漂移到正常的节点上,保证业务的高可用,能够继续提供服务

1.2 keepalived核心组件

  • vrrp_stack: 核心模块实现VRRP协议,负责vip漂移和主备的选举

  • checkers 健康检查模块,监控后端服务,nginx,mysql等,服务故障后,将请求不转发到这个故障的服务器上

  • libipvs: 负载均衡模块,集成LVS功能,实现了HA+负载均衡一体化

1.3 VRRP协议(核心原理)

  • 就是靠这个来实现高可用的,当一个服务器故障后,备用服务器充当主服务器提供服务

  • 是一个二层的协议

1.3.1 VRRP状态机制

  • initalize 不可用状态(初始状态):在Keepalive刚刚启动时还没有进行主从的选举时处于该状态或者是Keepalive的节点故障,在这个状态下是无法处理VRRP的心跳,也就是节点不可用

  • master主节点(活跃状态):在该状态下 Keepalive正常工作,并承载集群的流量访问出入口,也就是该状态下所在的节点是浮动IP所在的节点,并且向网络中正常发送VRRP的报文,优先级为255自动式master状态

  • backup 备用状态 :在该状态下Keepalive处于备用模式,不会承载集群的流量访问,仅接受和处理VRRP的心跳,并判断Master节点的状态,一旦master节点发送故障,则抢占浮动IP,将业务流量切换到当前节点,且自身变成master状态

1.3.2 VRRP选举机制

  • 就是谁来获取这个浮动ip,

  • 通过比较各个节点的优先级来进行比较,优先级大的成为master

  • 当优先级相同的时候,比较接口的ip地址,比较值大的成为master节点

1.3.3 防脑裂机制

  • 当出现了突然的情况,比如2个节点的心跳检查都检查不到,都在抢夺这个vip地址,就是一个很大的问题呢

  • 解决措施

    • 通过第三方软件仲裁

    • 通过加强心跳网络,比如专门有一个接口来进行心跳检查

    • 通过自定义检查脚本,这个是非常有用的

1.4 keepalived原理

  • VRRP2协议,和对业务的健康检查

  • 2个节点首先进行选举,主节点接收请求,并且和备用节点进行心跳检查,当主节点故障的时候,备用节点顶替为主节点,接收请求

  • 为什么能够自动切换呢?就是靠的VRRP2协议

  • 还有一个功能就是对LVS的后端服务器进行健康检查,后面的综合实验会涉及到的

2、keepalvied配置详解

2.1 安装keepalived和配置文件

yum -y install keepalived# 配置文件路径
[root@server ~]# rpm -qc keepalived
/etc/keepalived/keepalived.conf
/etc/sysconfig/keepalived# 安装产生的文件
[root@server ~]# rpm -ql keepalived

2.2 主配置文件详解

# 全局配置
global_defs {notification_email {admin@example.com     # 通知邮箱1ops@example.com       # 通知邮箱2}notification_email_from keepalived@hostname    # 发件人地址smtp_server 127.0.0.1                          # SMTP服务器smtp_connect_timeout 30                         # SMTP连接超时router_id LVS_DEVEL                             # 路由器标识,必须唯一,字符串vrrp_skip_check_adv_addr                        # 跳过检查广告地址vrrp_strict                                     # 严格遵守VRRP协议vrrp_garp_interval 0                            # 免费ARP间隔vrrp_gna_interval 0                             # 邻居通告间隔script_user nobody                              # 脚本运行用户enable_script_security                          # 启用脚本安全
}# 脚本检查配置,后面实例配置需要引用vrrp_script chk_nginx {script "/usr/bin/killall -0 nginx"              # 检测脚本路径interval 2                                      # 检测间隔(秒)weight 2                                        # 权重变化值fall 2                                          # 失败次数判定rise 2                                          # 成功次数判定user nobody                                     # 执行用户
}# VRRP实例配置,核心部分,决定谁是主节点和备用节点vrrp_instance VI_1 {                               # 实例名称,可自定义state MASTER                                   # 初始状态:MASTER/BACKUPinterface eth0                                 # 绑定的网络接口,也就是浮动ip地址virtual_router_id 51                           # 虚拟路由器ID(0-255),集群内必须一致priority 100                                   # 优先级(1-254),值越大优先级越高,255自动默认是主节点advert_int 1                                   # 宣告间隔(秒),心跳检查# 认证配置authentication {auth_type PASS                             # 认证类型:PASS/AHauth_pass 1111                             # 密码(最多8位)}# VIP配置(可以有多个)virtual_ipaddress {192.168.1.100/24 dev eth0                  # VIP地址1,可以就是ip地址192.168.1.200/24 dev eth0 label eth0:1     # VIP地址2(带标签)}# 跟踪脚本(健康检查)track_script {chk_nginx                                  # 引用上面定义的脚本}}# 虚拟服务配置,lvs相关的virtual_server 192.168.1.100 80 {                  # VIP和端口delay_loop 6                                   # 健康检查间隔lb_algo rr                                     # 调度算法:rr|wrr|lc|wlc|lblc|sh|dhlb_kind NAT                                    # LVS模式:NAT|DR|TUNpersistence_timeout 50                         # 持久化超时,就是一个连接要持续多久,在轮询中,一个连接保持50秒,那么在这个期间内都是访问这个服务器,而不是访问另外一个服务器,后面keepalived+lvs 会注释这一行的protocol TCP                                   # 协议类型# 真实服务器池real_server 192.168.1.10 80 {                  # 真实服务器1weight 1                                   # 权重# TCP健康检查TCP_CHECK {connect_timeout 10 # 超时时间retry 3  # 重试的次数delay_before_retry 3  # 延迟多长时间后,再次重试connect_port 80  # 连接的端口,默认是RS提供业务端口}# 或HTTP健康检查HTTP_GET {url {path /healthz   # 检查的路径是healthzstatus_code 200  # 返回值为200就是正确的}connect_timeout 3nb_get_retry 3  # get重试的次数delay_before_retry 3  # 在重试之前延迟多少秒}# 或SSL健康检查,https检查SSL_GET {url {path /digest <digest_string>  # 摘要检查,会生成一个固定的值}connect_timeout 3retry 3delay_before_retry 3}}real_server 192.168.1.11 80 {                  # 真实服务器2weight 2TCP_CHECK {connect_port 80connect_timeout 3}}
}

2.3 脚本检查配置

  • 有2种写法

2.3.1 第一种写法(任何版本都能使用)

2.3.2 第二种写法(在高版本使用)

vrrp_script nginx_check {
script “/etc/keepalived/check.sh”
interval 1  脚本执行间隔时间
weight -5   权重
fail 3  错误的次数
} # 在实例中引用脚本
vrrp_instance Nginx {track_script {nginx_check}
}

keepalived原理:就是一个浮动ip来提供业务,当这个节点出现了故障,备用就自动的切换为主节点,提供业务,这个怎么切换的呢,就是心跳检查,2个节点之间的检查

  • 还有一个就是加上了lvs这个服务

三、keepalvied实现

1、keepalived+nginx

  • 目的,当一个keepalived停掉的时候,业务还在,

  • 另外一个问题,当业务停掉的时候,浮动ip还是故障的节点上,使用脚本检查来实现浮动ip漂移

  • vrrp是检查keepalived状态来是否漂移

1.1 拓补图

1.2 keepalived配置

主节点配置

[root@server keepalived]# cat keepalived.conf
! Configuration File for keepalivedglobal_defs {router_id lvs1
}vrrp_instance lvs1 {state MASTERinterface ens33virtual_router_id 10priority 254advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.50.100/24}
}

备用节点配置

[root@node1 keepalived]# cat keepalived.conf
! Configuration File for keepalivedglobal_defs {router_id lvs2
}vrrp_instance lvs2 {state BACKUPinterface ens33virtual_router_id 10priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.50.100/24}
}

重启服务和查看ip地址

[root@server keepalived]# systemctl restart keepalived# ip 可以看到vip地址,但是ifconfig不会看到
[root@server keepalived]# ip a | grep ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000inet 192.168.50.20/24 brd 192.168.50.255 scope global noprefixroute ens33inet 192.168.50.100/24 scope global secondary ens33
# secondary 就是一个虚拟的ip地址# 在主节点上面可以看到这个vip地址

1.2 配置后端nginx服务器

[root@server html]# echo master > index.html 
[root@server html]# systemctl restart nginx[root@node1 html]# echo backup > index.html 

1.3 测试和模拟故障

直接访问浮动ip

# 发现请求都是主节点回复的,备用节点没有接收请求
[root@node2 ~]# curl 192.168.50.100
master
[root@node2 ~]# curl 192.168.50.100
master

将主节点故障

[root@server ~]# systemctl stop keepalived.service # 发现这个浮动ip地址转移到了备用节点
[root@node1 html]# ip a | grep ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000inet 192.168.50.21/24 brd 192.168.50.255 scope global noprefixroute ens33inet 192.168.50.100/24 scope global secondary ens33# 访问浮动ip,现在就是备用节点接收请求
[root@node2 ~]# curl 192.168.50.100
backup

1.4 将业务停掉呢?

  • 将主节点的keepalived服务启动,浮动ip会漂移到主节点上

  • 现在将主节点上面的业务停掉,发现浮动ip在这个故障的节点
    上,没有进行漂移

[root@server ~]# systemctl stop nginx
[root@server ~]# ip a| grep ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000inet 192.168.50.20/24 brd 192.168.50.255 scope global noprefixroute ens33inet 192.168.50.100/24 scope global secondary ens33# 业务出现故障的节点,浮动ip地址还在上面,当客户端请求的时候,访问不到内筒[root@node2 ~]# curl 192.168.50.100
curl: (7) Failed to connect to 192.168.50.100 port 80 after 0 ms: Connection refused
  • 为什么没有进行漂移呢 因为这个VRRP2协议是检测这个keepalived服务的状态来决定是否漂移,而不是业务状态

  • 因此的话,就需要一个脚本进行检查

2、脚本检查业务

2.1、脚本配置

# 添加+x权限
[root@server keepalived]# cat check_nginx.sh 
#! /bin/bash
systemctl is-active nginx &> /dev/null
if [ $? -ne 0 ];thenexit 10  # keepalvied健康检查可以根据这个退出码,来决定是否转移浮动ip地址
elseexit 0
fi

2.2、配置文件的添加

[root@server keepalived]# cat keepalived.conf
! Configuration File for keepalivedglobal_defs {router_id lvs1
}vrrp_script nginx_check {script "/etc/keepalived/check_nginx.sh"interval 2  # 间隔时间执行fail 3  # 重试次数
}vrrp_instance lvs1 {state MASTERinterface ens33virtual_router_id 10priority 254advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.50.100/24}track_script {  # 引用脚本nginx_check
}
}

2.3 停掉业务

[root@server keepalived]# systemctl stop nginx# 查看messages日志,发现移走了浮动ip地址
Oct 19 00:19:17 template systemctl[4202]: [systemctl stop nginx] called by PID 2385 (-bash)
Oct 19 00:19:17 template systemd[1]: Stopping The nginx HTTP and reverse proxy server...
Oct 19 00:19:17 template systemd[1]: nginx.service: Deactivated successfully.
Oct 19 00:19:17 template systemd[1]: Stopped The nginx HTTP and reverse proxy server.
Oct 19 00:19:18 template Keepalived_vrrp[3816]: Script `nginx_check` now returning 10
Oct 19 00:19:18 template Keepalived_vrrp[3816]: VRRP_Script(nginx_check) failed (exited with status 10)
Oct 19 00:19:18 template NetworkManager[855]: <info>  [1760804358.0874] policy: set-hostname: current hostname was changed outside NetworkManager: 'server'
Oct 19 00:19:18 template Keepalived_vrrp[3816]: (lvs1) Entering FAULT STATE
Oct 19 00:19:18 template Keepalived_vrrp[3816]: (lvs1) sent 0 priority
Oct 19 00:19:18 template Keepalived_vrrp[3816]: (lvs1) removing VIPs.[root@node1 keepalived]# ip a | grep ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group inet 192.168.50.21/24 brd 192.168.50.255 scope global noprefixroute ens33inet 192.168.50.100/24 scope global secondary ens33# 恢复业务,发现浮动ip回来了
[root@server keepalived]# systemctl start nginxOct 19 00:20:29 template systemctl[4281]: [systemctl start nginx] called by PID 2385 (-bash)
Oct 19 00:20:29 template systemd[1]: Starting The nginx HTTP and reverse proxy server...
Oct 19 00:20:29 template nginx[4286]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Oct 19 00:20:29 template nginx[4286]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Oct 19 00:20:29 template systemd[1]: Started The nginx HTTP and reverse proxy server.
Oct 19 00:20:30 template Keepalived_vrrp[3816]: Script `nginx_check` now returning 0
Oct 19 00:20:30 template Keepalived_vrrp[3816]: VRRP_Script(nginx_check) succeeded
Oct 19 00:20:30 template Keepalived_vrrp[3816]: (lvs1) Entering BACKUP STATE
Oct 19 00:20:30 template Keepalived_vrrp[3816]: (lvs1) received lower priority (100) advert from 192.168.50.21 - discarding
Oct 19 00:20:31 template Keepalived_vrrp[3816]: (lvs1) received lower priority (100) advert from 192.168.50.21 - discarding
Oct 19 00:20:32 template Keepalived_vrrp[3816]: (lvs1) received lower priority (100) advert from 192.168.50.21 - discarding
Oct 19 00:20:33 template Keepalived_vrrp[3816]: (lvs1) Receive advertisement timeout
Oct 19 00:20:33 template Keepalived_vrrp[3816]: (lvs1) Entering MASTER STATE
Oct 19 00:20:33 template NetworkManager[855]: <info>  [1760804433.1051] policy: set-hostname: current hostname was changed outside NetworkManager: 'server'
Oct 19 00:20:33 template Keepalived_vrrp[3816]: (lvs1) setting VIPs.
Oct 19 00:20:33 template Keepalived_vrrp[3816]: (lvs1) Sending/queueing gratuitous ARPs on ens33 for 192.168.50.100
  • 就是可以发现这个脚本是在运行的,只不是不是那么容易观察到的,可以写一个date命令脚本来发现在运行的

3、keepalived+lvs

3.1 拓补图

  • 4个机器

  • 就是对这个vip进行高可用

  • 健康检查使用http_check就行了,不需要使用脚本检查

3.2 配置文件更改

[root@lvs1 keepalived]# cat keepalived.conf
! Configuration File for keepalivedglobal_defs {router_id lvs1 
}vrrp_instance lvs1 {state MASTERinterface ens33virtual_router_id 10priority 255advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.50.100/24}
}virtual_server 192.168.50.100 80 {delay_loop 6lb_algo rrlb_kind DR
#    persistence_timeout 50protocol TCPreal_server 192.168.50.11 80 {weight 1HTTP_GET {url {path /status_code 200}connect_timeout 3retry 3delay_before_retry 3}}real_server 192.168.50.22 80 {weight 1HTTP_GET {url {path /status_code 200}connect_timeout 3retry 3delay_before_retry 3}}}# 备用节点配置
[root@lvs2 keepalived]# cat keepalived.conf
! Configuration File for keepalivedglobal_defs {router_id lvs2
}vrrp_instance lvs2 {state BACKUPinterface ens33virtual_router_id 10priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.50.100/24}
}virtual_server 192.168.50.100 80 {delay_loop 6lb_algo rrlb_kind DR
#    persistence_timeout 50protocol TCPreal_server 192.168.50.11 80 {weight 1HTTP_GET {url {path /status_code 200}connect_timeout 3retry 3delay_before_retry 3}}real_server 192.168.50.22 80 {weight 1HTTP_GET {   # 这个http_get健康检查,后端服务url {path /status_code 200}connect_timeout 3retry 3delay_before_retry 3}}}

3.3 后端业务配置

echo node1 > index.htmlecho "node2" > index.html

3.4 ipvsadm查看和配置后端服务arp屏蔽

# 写完配置文件后,启动这些配置会自动的生效
[root@lvs1 keepalived]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags-> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.50.100:80 rr-> 192.168.50.11:80             Route   1      0          0         -> 192.168.50.22:80             Route   1      0          0      

配置lvs 内核参数

# 2个LVS节点都需要做
sysctl -w net.ipv4.ip_forward=1
[root@lvs1 keepalived]# sysctl -a | grep net.ipv4.ip_forward
net.ipv4.ip_forward = 1

屏蔽arp和配置环回接口

# 2个后端服务器都需要完成
[root@nginx1 html]# nmcli connection add type dummy ifname dummy2 con-name dummy2 ipv4.method manual ipv4.addresses 192.168.50.100/24 autoconnect yes 
Connection 'dummy2' (8b8a3477-cd61-4e5d-97ba-071c7f0e8c4d) successfully added.[root@nginx1 html]# cat /etc/sysctl.conf net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.dummy2.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.dummy2.arp_announce=2# 生效配置
sysctl -p /etc/sysctl.conf

3.5 测试

[C:\~]$ curl 192.168.50.100 -s
node1[C:\~]$ curl 192.168.50.100 -s
node2

3.5.1 停掉一个keepalived服务

[root@lvs1 keepalived]# systemctl stop keepalived.service 
# lvs信息也都没有了,vip地址也被转移了
[root@lvs1 keepalived]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags-> RemoteAddress:Port           Forward Weight ActiveConn InActConn

测试

[C:\~]$ curl 192.168.50.100 -s
node2[C:\~]$ curl 192.168.50.100 -s
node1# 发现服务没有受到任何影响

3.5.2 停掉一个业务服务(nginx)

  • 先将上面的keepalived恢复
[root@lvs1 keepalived]# systemctl start keepalived.service# 停掉一个nginx后,这个ipvsadm会自动移除这个故障服务器,因为有这个http_get健康检查
[root@nginx1 html]# systemctl stop nginx
[root@lvs1 keepalived]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags-> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.50.100:80 rr-> 192.168.50.22:80             Route   1      0          11   

测试

# 将请求转发到正常的后端服务器上了
[C:\~]$ curl 192.168.50.100 -s
node2[C:\~]$ curl 192.168.50.100 -s
node2

四、总结

  • keepalvied实现高可用,通过这个VRRP2协议来实现的,心跳检查

  • 对后端服务器的健康检查,lvs和keepalived

五、生产环境中怎么实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/995625.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P5304 [GXOI/GZOI2019] 旅行者 题解

P5304 [GXOI/GZOI2019] 旅行者 题解P5304 [GXOI/GZOI2019] 旅行者 Description 给你一个 \(n\) 个点,\(m\) 条边的有向连通图,给出 \(k\) 个点的编号,让你求出这些点中距离最近的两点之间距离。 \(n\le 10^5,m\le 5…

2025 年面膜消费指南:告别盲目囤货,10款补水保湿抗老修护爆款适配干油敏肌,精准解决护肤痛点 - 资讯焦点

一抹精华浸润肌底,熬夜的蜡黄倦容悄然褪去;一贴膜布贴合脸颊,换季的泛红干痒即刻舒缓;分区护理精准发力,T 区的油光与 U 区的干纹同时消失 —— 这是 2025 年新一代功效型面膜带来的护肤新体验。 据华泰研究所 20…

P3275 [SCOI2011] 糖果 题解

P3275 [SCOI2011] 糖果 题解P3275 [SCOI2011] 糖果 Description 给你 \(k\) 个指令(约束条件),让你构造一个长度为 \(n\) 的正整数序列 A,满足这个条件的同时让所有元素的和最小。 指令的格式如下:1 a b 表示 \(A…

the attitude

some Chinese talked with people comes from R. they will discuss that one with their friends, is the people just monkey to be discussed? I will never do that.

2025年国内正规的微动开关工厂怎么选购,家电微动开关/大电流微动开关/新能源微动开关/小型微动开关/汽车微动开关供货商怎么选 - 品牌推荐师

随着工业自动化、智能家电及新能源汽车等领域的蓬勃发展,作为关键控制元件的微动开关,其市场需求持续攀升。面对市场上众多的微动开关制造商,采购方如何甄别与选择一家技术可靠、品质稳定、供货能力强的正规工厂,成…

win10 vscode 使用ssh登录 ubuntu

win10 vscode 使用ssh登录 ubuntuvscode ssh在Ubuntu上建立SSH服务器,然后从Windows 10上的VSCode连接。 git操作 cd到项目目录 如果要在局域网中搭建git仓库,先要将下载的项目中有git工程配置文件删除掉 rm -rf .gi…

P4064 [JXOI2017] 加法 题解

P4064 [JXOI2017] 加法 题解P4064 [JXOI2017] 加法 Description 给你一个长度为 \(n\) 的正整数序列 \(A\),再给你 \(m\) 个区间,让你在这 \(m\) 个区间中选出 \(k\) 个进行区间加 \(a\) 操作(\(a\) 为常数),使得…

2025年河南工业大学2025新生周赛 (7)

A 回声 将连续的字母和连字符视为同一个单词bool isWordChar(char c) {if ((c >= a && c <= z) ||(c >= A && c <= Z) ||c == -) {return true;}return false; }从头到尾遍历,并存单词即…

P3076 [USACO13FEB] Taxi G 题解

P3076 [USACO13FEB] Taxi GP3076 [USACO13FEB] Taxi G Description 有一条长度为 \(m\) 的数轴,有 \(n\) 头牛需要坐车前往别的地方,起点和终点分别为 \(a_i\) 和 \(b_i\)。 现在一辆出租车从原点出发,要运送完所有…

第四章 串

串的定义和实现 串的基本概念 串的定义 串,即字符串,是由零个或多个字符组成的有限序列,一般记为 \[S=a_{1}a_{2}a_{3}...a_{n}(n\ge0) \]其中,S是串名,单引号括起来的字符序列是串的值,\(a_{i}\)可以是字母、数…

数据采集第四次作业-102302128吴建良

作业1:基于 Selenium 和 MySQL 的股票数据爬取 码云仓库:https://gitee.com/wujianliang9/2025-data-collection/tree/master/第四次作业/作业1 一、核心代码与方法 (Code & Methodology) 核心代码 以下是实现爬…

102302142罗伟钊第四次作业

作业1: - 要求: ▪ 熟练掌握 Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内 容。 ▪ 使用Selenium框架+ MySQL数据库存储技术路线爬取“沪深A股”、“上证A股”、 “深证A股”3个板块的股票数据信息。 ▪…

北京SAT辅导机构选课指南:高分攻略与机构测评(2025最新) - 品牌测评鉴赏家

北京SAT辅导机构选课指南:高分攻略与机构测评(2025最新)一、选机构先看 “硬指标”:三大核心维度帮你筛出优质选项 (一)师资实力:实考经验 + 教研能力是提分 “双保险” 真正懂 SAT 的老师,不仅要会教,更要 “…

第四次作业-何玮鑫

作业4 一、沪深 A 股数据爬取:Ajax 动态数据抓取与结构化存储 1.1 实现方案与核心代码 需求背景与整体思路 本次任务核心目标是爬取东方财富网沪深 A 股、上证 A 股、深证 A 股三大板块的股票数据,解决Ajax 动态加载…

[ABC212D] Querying Multiset 题解

[ABC212D] Querying Multiset 题解[ABC212D] Querying Multiset Description 给你一个集合,让你支持三种操作:将 \(x\) 加入集合。把集合中的数都加上 \(x\)。将集合中最小的数删除,并且输出这个数。Solution 考虑使…

P4105 [HEOI2014] 南园满地堆轻絮 题解

P4105 [HEOI2014] 南园满地堆轻絮 题解P4105 [HEOI2014] 南园满地堆轻絮 Description 给你一个长度为 \(n\) 的正整数序列 \(a\),让你构造一个单调不降的正整数序列 \(b\),使得下面式子的值尽量小。 \[\max_{i=1}^{n…

【树莓派】【v4l2】在树莓派环境下取流-编码-存储

硬件环境:树莓派3B+ Camera模块:rpi Camera(500像素) 编码库:x264 工程代码 #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <fcntl.h>…

Daily Report — Day 4 (Beta)

Daily Report — Day 4 (Beta) 📅 日期:2025/12/05 👥 参与人:zc、lzy、shr ✅ 昨日完成工作(Day 3 落地成果)单元测试体系落地(CI 集成完成)完成 Jest + TS 环境配置,成功挂载至 GitHub Actions 流水线; …

[ABC241D] Sequence Query 题解

[ABC241D] Sequence Query 题解[ABC241D] Sequence Query Description 有一个空序列 \(a\)。给定 \(q\) 次操作,每次询问是以下三种之一:1 x:向 \(a\) 中插入元素 \(x\)。 2 x k:输出 \(a\) 中所有 \(\le x\) 的元…

Prometheus + Grafana 原理和用法

Prometheus + Grafana 原理和用法(通俗易懂版) 我们可以把这个组合想象成 「智能体检中心」:Prometheus = 体检医生:主动上门,定期采集服务器/应用的“健康数据”(CPU、内存、接口响应时间等),并把数据存起来。…