41-软件部署实战(中):IAM系统生产环境部署实战

 

 下面四个步骤来部署IAM应用:

  1. 在服务器上部署IAM应用中的服务。
  2. 配置Nginx,实现反向代理功能。通过反向代理,我们可以通过Nginx来访问部署在内网的IAM服务。
  3. 配置Nginx,实现负载均衡功能。通过负载均衡,我们可以实现服务的水平扩缩容,使IAM应用具备高可用能力。
  4. 配置Keepalived,实现Nginx的高可用。通过Nginx + Keepalived的组合,可以实现整个应用架构的高可用。

部署IAM应用

 分别在10.0.4.2010.0.4.21服务器上部署IAM应用。

10.0.4.20服务器上部署IAM应用

首先,我来介绍下如何在10.0.4.20服务器上部署IAM应用。

我们要在这个服务器上部署如下组件:

  • iam-apiserver
  • iam-authz-server
  • iam-pump
  • MariaDB
  • Redis
  • MongoDB

 

此外,我们还需要设置MariaDB,给来自于10.0.4.21服务器的数据库连接授权,授权命令如下:

$ mysql -hlocalhost -P3306 -uroot -proot # 先以root用户登陆数据库
MariaDB [(none)]> grant all on iam.* TO iam@10.0.4.21 identified by 'iam1234';
Query OK, 0 rows affected (0.000 sec)MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.000 sec)

10.0.4.21服务器上部署IAM应用

然后,在10.0.4.21服务器上安装好iam-apiserver、iam-authz-server 和 iam-pump。这些组件通过10.0.4.20 IP地址,连接10.0.4.20服务器上的MariaDB、Redis和MongoDB。

配置Nginx作为反向代理

假定要访问的API Server和IAM Authorization Server的域名分别为iam.api.marmotedu.comiam.authz.marmotedu.com,我们需要分别为iam-apiserver和iam-authz-server配置Nginx反向代理。整个配置过程可以分为5步(在10.0.4.20服务器上操作)。

第一步,配置iam-apiserver。

新建Nginx配置文件/etc/nginx/conf.d/iam-apiserver.conf,内容如下:

server {listen       80;server_name  iam.api.marmotedu.com;root         /usr/share/nginx/html;location / {proxy_set_header X-Forwarded-Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass  http://127.0.0.1:8080/;client_max_body_size 5m;}error_page 404 /404.html;location = /40x.html {}error_page 500 502 503 504 /50x.html;location = /50x.html {}
}

有几点你在配置时需要注意,这里说明下。

  • server_name需要为iam.api.marmotedu.com,我们通过iam.api.marmotedu.com访问iam-apiserver。
  • iam-apiserver默认启动的端口为8080
  • 由于Nginx默认允许客户端请求的最大单文件字节数为1MB,实际生产环境中可能太小,所以这里将此限制改为5MB(client_max_body_size 5m)。如果需要上传图片之类的,可能需要设置成更大的值,比如50m
  • server_name用来说明访问Nginx服务器的域名,例如curl -H 'Host: iam.api.marmotedu.com' http://x.x.x.x:80/healthzx.x.x.x为Nginx服务器的IP地址。
  • proxy_pass表示反向代理的路径。因为这里是本机的iam-apiserver服务,所以IP为127.0.0.1。端口要和API服务端口一致,为8080

 

第二步,配置iam-authz-server。

新建Nginx配置文件/etc/nginx/conf.d/iam-authz-server.conf,内容如下:

server {listen       80;server_name  iam.authz.marmotedu.com;root         /usr/share/nginx/html;location / {proxy_set_header X-Forwarded-Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass  http://127.0.0.1:9090/;client_max_body_size 5m;}error_page 404 /404.html;location = /40x.html {}error_page 500 502 503 504 /50x.html;location = /50x.html {}
}

下面是一些配置说明。

  • server_name需要为iam.authz.marmotedu.com,我们通过iam.authz.marmotedu.com访问iam-authz-server。
  • iam-authz-server默认启动的端口为9090
  • 其他配置跟/etc/nginx/conf.d/iam-apiserver.conf一致。

第三步,配置完Nginx后,重启Nginx:

$ sudo systemctl restart nginx

第四步,在/etc/hosts中追加下面两行:

127.0.0.1 iam.api.marmotedu.com
127.0.0.1 iam.authz.marmotedu.com

第五步,发送HTTP请求:

$ curl http://iam.api.marmotedu.com/healthz
{"status":"ok"}
$ curl http://iam.authz.marmotedu.com/healthz
{"status":"ok"}

我们分别请求iam-apiserver和iam-authz-server的健康检查接口,输出了{"status":"ok"},说明我们可以成功通过代理访问后端的API服务。

在用curl请求http://iam.api.marmotedu.com/healthz后,后端的请求流程实际上是这样的:

  1. 因为在/etc/hosts中配置了127.0.0.1 iam.api.marmotedu.com,所以请求http://iam.api.marmotedu.com/healthz实际上是请求本机的Nginx端口(127.0.0.1:80)。
  2. Nginx在收到请求后,会解析请求,得到请求域名为iam.api.marmotedu.com。根据请求域名去匹配 Nginx的server配置,匹配到server_name iam.api.marmotedu.com;配置。
  3. 匹配到server后,把请求转发到该server的proxy_pass路径。
  4. 等待API服务器返回结果,并返回客户端。

配置Nginx作为负载均衡

这门课采用Nginx轮询的负载均衡策略转发请求。负载均衡需要至少两台服务器,所以会分别在10.0.4.2010.0.4.21服务器上执行相同的操作。下面我分别来介绍下如何配置这两台服务器,并验证配置是否成功。

10.0.4.20服务器配置

登陆10.0.4.20服务器,在/etc/nginx/nginx.conf中添加upstream配置,配置过程可以分为3步。

第一步,在/etc/nginx/nginx.conf中添加upstream:

http {log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log  /var/log/nginx/access.log  main;sendfile            on;tcp_nopush          on;tcp_nodelay         on;keepalive_timeout   65;types_hash_max_size 2048;include             /etc/nginx/mime.types;default_type        application/octet-stream;# Load modular configuration files from the /etc/nginx/conf.d directory.# See http://nginx.org/en/docs/ngx_core_module.html#include# for more information.include /etc/nginx/conf.d/*.conf;upstream iam.api.marmotedu.com {server 127.0.0.1:8080server 10.0.4.21:8080}upstream iam.authz.marmotedu.com {server 127.0.0.1:9090server 10.0.4.21:9090}
}

配置说明:

  • upstream是配置在/etc/nginx/nginx.conf文件中的http{ … }部分的。
  • 因为我们要分别为iam-apiserver和iam-authz-server配置负载均衡,所以我们创建了两个upstream,分别是iam.api.marmotedu.comiam.authz.marmotedu.com。为了便于识别,upstream名称和域名最好保持一致。
  • 在upstream中,我们需要分别添加所有的iam-apiserver和iam-authz-server的后端(ip:port),本机的后端为了访问更快,可以使用127.0.0.1:<port>,其他机器的后端,需要使用<内网>:port,例如10.0.4.21:808010.0.4.21:9090

第二步,修改proxy_pass。

修改/etc/nginx/conf.d/iam-apiserver.conf文件,将proxy_pass修改为:

proxy_pass http://iam.api.marmotedu.com/;

修改/etc/nginx/conf.d/iam-authz-server.conf文件,将proxy_pass修改为:

proxy_pass http://iam.authz.marmotedu.com/;

当Nginx转发到http://iam.api.marmotedu.com/域名时,会从iam.api.marmotedu.com upstream配置的后端列表中,根据负载均衡策略选取一个后端,并将请求转发过去。转发http://iam.authz.marmotedu.com/域名的逻辑也一样。

第三步,配置完Nginx后,重启Nginx:

$ sudo systemctl restart nginx

最终配置好的配置文件,你可以参考下面这些(保存在configs/ha/10.0.4.20目录下):

  • nginx.conf:configs/ha/10.0.4.20/nginx.conf。
  • iam-apiserver.conf:configs/ha/10.0.4.20/iam-apiserver.conf。
  • iam-authz-server.conf:configs/ha/10.0.4.20/iam-authz-server.conf。

10.0.4.21服务器配置

登陆10.0.4.21服务器,在/etc/nginx/nginx.conf中添加upstream配置。配置过程可以分为下面4步。

第一步,在/etc/nginx/nginx.conf中添加upstream:

http {log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log  /var/log/nginx/access.log  main;sendfile            on;tcp_nopush          on;tcp_nodelay         on;keepalive_timeout   65;types_hash_max_size 2048;include             /etc/nginx/mime.types;default_type        application/octet-stream;# Load modular configuration files from the /etc/nginx/conf.d directory.# See http://nginx.org/en/docs/ngx_core_module.html#include# for more information.include /etc/nginx/conf.d/*.conf;upstream iam.api.marmotedu.com {server 127.0.0.1:8080server 10.0.4.20:8080}upstream iam.authz.marmotedu.com {server 127.0.0.1:9090server 10.0.4.20:9090}
}

upstream中,需要配置10.0.4.20服务器上的iam-apiserver和iam-authz-server的后端,例如10.0.4.20:808010.0.4.20:9090

第二步,创建/etc/nginx/conf.d/iam-apiserver.conf文件(iam-apiserver的反向代理+负载均衡配置),内容如下:

server {listen       80;server_name  iam.api.marmotedu.com;root         /usr/share/nginx/html;location / {proxy_set_header X-Forwarded-Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass  http://iam.api.marmotedu.com/;client_max_body_size 5m;}error_page 404 /404.html;location = /40x.html {}error_page 500 502 503 504 /50x.html;location = /50x.html {}
}

第三步,创建/etc/nginx/conf.d/iam-authz-server文件(iam-authz-server的反向代理+负载均衡配置),内容如下:

server {listen       80;server_name  iam.authz.marmotedu.com;root         /usr/share/nginx/html;location / {proxy_set_header X-Forwarded-Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass  http://iam.authz.marmotedu.com/;client_max_body_size 5m;}error_page 404 /404.html;location = /40x.html {}error_page 500 502 503 504 /50x.html;location = /50x.html {}
}

第四步,配置完Nginx后,重启Nginx:

$ sudo systemctl restart nginx

最终配置好的配置文件,你可以参考下面这些(保存在configs/ha/10.0.4.21目录下):

  • nginx.conf:configs/ha/10.0.4.21/nginx.conf。
  • iam-apiserver.conf:configs/ha/10.0.4.21/iam-apiserver.conf。
  • iam-authz-server.conf:configs/ha/10.0.4.21/iam-authz-server.conf。

测试负载均衡

上面,我们配置了Nginx负载均衡器,这里我们还需要测试下是否配置成功。

第一步,执行测试脚本(test/nginx/loadbalance.sh):

#!/usr/bin/env bashfor domain in iam.api.marmotedu.com iam.authz.marmotedu.com
dofor n in $(seq 1 1 10)doecho $domainnohup curl http://${domain}/healthz &>/dev/null &done
done

第二步,分别查看iam-apiserver和iam-authz-server的日志。

这里我展示下iam-apiserver的日志(iam-authz-server的日志你可自行查看)。

10.0.4.20服务器的iam-apiserver日志如下图所示:

图片

10.0.4.21服务器的iam-apiserver日志如下图所示:

图片

通过上面两张图,你可以看到10.0.4.2010.0.4.21各收到5/healthz请求,说明负载均衡配置成功。

配置Keepalived

在 40讲,我们分别在10.0.4.2010.0.4.21服务器上安装了Keepalived。 为了避免故障恢复时,VIP切换造成的服务延时,这一讲采用Keepalived的非抢占模式。

配置Keepalived的流程比较复杂,分为创建腾讯云HAVIP、主服务器配置、备服务器配置、测试Keepalived、VIP绑定公网IP和测试公网访问六大步,每一步中都有很多小步骤,下面我们来一步步地看下。

第一步:创建腾讯云HAVIP

公有云厂商的普通内网IP,出于安全考虑(如避免ARP欺骗等),不支持主机通过ARP宣告IP 。如果用户直接在keepalived.conf文件中指定一个普通内网IP为virtual IP,当Keepalived将virtual IP从MASTER机器切换到BACKUP机器时,将无法更新IP和MAC地址的映射,而需要调API来进行IP切换。所以,这里的VIP需要申请腾讯云的HAVIP。

申请的流程可以分为下面4步:

  1. 登录私有网络控制台
  2. 在左侧导航栏中,选择【IP与网卡】>【高可用虚拟IP】。
  3. 在HAVIP管理页面,选择所在地域,单击【申请】。
  4. 在弹出的【申请高可用虚拟IP】对话框中输入名称,选择HAVIP所在的私有网络和子网等信息,单击【确定】即可。

这里选择的私有网络和子网,需要和10.0.4.2010.0.4.21相同。HAVIP 的 IP 地址可以自动分配,也可以手动填写,这里我们手动填写为10.0.4.99。申请页面如下图所示:

图片

第二步:主服务器配置

进行主服务器配置,可以分为两步。

首先,修改Keepalived配置文件。

登陆服务器10.0.4.20,编辑/etc/keepalived/keepalived.conf,修改配置,修改后配置内容如下(参考:configs/ha/10.0.4.20/keepalived.conf):

# 全局定义,定义全局的配置选项
global_defs {
# 指定keepalived在发生切换操作时发送email,发送给哪些email
# 建议在keepalived_notify.sh中发送邮件notification_email {acassen@firewall.loc}notification_email_from Alexandre.Cassen@firewall.loc # 发送email时邮件源地址smtp_server 192.168.200.1 # 发送email时smtp服务器地址smtp_connect_timeout 30 # 连接smtp的超时时间router_id VM-4-20-centos # 机器标识,通常可以设置为hostnamevrrp_skip_check_adv_addr # 如果接收到的报文和上一个报文来自同一个路由器,则不执行检查。默认是跳过检查vrrp_garp_interval 0 # 单位秒,在一个网卡上每组gratuitous arp消息之间的延迟时间,默认为0vrrp_gna_interval 0 # 单位秒,在一个网卡上每组na消息之间的延迟时间,默认为0
}
# 检测脚本配置
vrrp_script checkhaproxy
{script "/etc/keepalived/check_nginx.sh" # 检测脚本路径interval 5 # 检测时间间隔(秒)weight 0 # 根据该权重改变priority,当值为0时,不改变实例的优先级
}
# VRRP实例配置
vrrp_instance VI_1 {state BACKUP  # 设置初始状态为'备份'interface eth0 # 设置绑定VIP的网卡,例如eth0virtual_router_id 51  # 配置集群VRID,互为主备的VRID需要是相同的值nopreempt               # 设置非抢占模式,只能设置在state为backup的节点上priority 100 # 设置优先级,值范围0~254,值越大优先级越高,最高的为masteradvert_int 1 # 组播信息发送时间间隔,两个节点必须设置一样,默认为1秒
# 验证信息,两个节点必须一致authentication {auth_type PASS # 认证方式,可以是PASS或AH两种认证方式auth_pass 1111 # 认证密码}unicast_src_ip 10.0.4.20  # 设置本机内网IP地址unicast_peer {10.0.4.21             # 对端设备的IP地址}
# VIP,当state为master时添加,当state为backup时删除virtual_ipaddress {10.0.4.99 # 设置高可用虚拟VIP,如果是腾讯云的CVM,需要填写控制台申请到的HAVIP地址。}notify_master "/etc/keepalived/keepalived_notify.sh MASTER" # 当切换到master状态时执行脚本notify_backup "/etc/keepalived/keepalived_notify.sh BACKUP" # 当切换到backup状态时执行脚本notify_fault "/etc/keepalived/keepalived_notify.sh FAULT" # 当切换到fault状态时执行脚本notify_stop "/etc/keepalived/keepalived_notify.sh STOP" # 当切换到stop状态时执行脚本garp_master_delay 1    # 设置当切为主状态后多久更新ARP缓存garp_master_refresh 5   # 设置主节点发送ARP报文的时间间隔# 跟踪接口,里面任意一块网卡出现问题,都会进入故障(FAULT)状态track_interface {eth0}# 要执行的检查脚本track_script {checkhaproxy}
}

这里有几个注意事项:

  • 确保已经配置了garp相关参数。因为Keepalived依赖ARP报文更新IP信息,如果缺少这些参数,会导致某些场景下主设备不发送ARP,进而导致通信异常。garp相关参数配置如下:
garp_master_delay 1
garp_master_refresh 5
  • 确定没有采用 strict 模式,即需要删除vrrp_strict配置。
  • 配置中的/etc/keepalived/check_nginx.sh/etc/keepalived/keepalived_notify.sh脚本文件,可分别拷贝自scripts/check_nginx.sh和scripts/keepalived_notify.sh。

然后,重启Keepalived:

$ sudo systemctl restart keepalived

第三步:备服务器配置

进行备服务器配置也分为两步。

首先,修改Keepalived配置文件。

登陆服务器10.0.4.21,编辑/etc/keepalived/keepalived.conf,修改配置,修改后配置内容如下(参考:configs/ha/10.0.4.21/keepalived.conf):

# 全局定义,定义全局的配置选项
global_defs {
# 指定keepalived在发生切换操作时发送email,发送给哪些email
# 建议在keepalived_notify.sh中发送邮件notification_email {acassen@firewall.loc}notification_email_from Alexandre.Cassen@firewall.loc # 发送email时邮件源地址smtp_server 192.168.200.1 # 发送email时smtp服务器地址smtp_connect_timeout 30 # 连接smtp的超时时间router_id VM-4-21-centos # 机器标识,通常可以设置为hostnamevrrp_skip_check_adv_addr # 如果接收到的报文和上一个报文来自同一个路由器,则不执行检查。默认是跳过检查vrrp_garp_interval 0 # 单位秒,在一个网卡上每组gratuitous arp消息之间的延迟时间,默认为0vrrp_gna_interval 0 # 单位秒,在一个网卡上每组na消息之间的延迟时间,默认为0
}
# 检测脚本配置
vrrp_script checkhaproxy
{script "/etc/keepalived/check_nginx.sh" # 检测脚本路径interval 5 # 检测时间间隔(秒)weight 0 # 根据该权重改变priority,当值为0时,不改变实例的优先级
}
# VRRP实例配置
vrrp_instance VI_1 {state BACKUP  # 设置初始状态为'备份'interface eth0 # 设置绑定VIP的网卡,例如eth0virtual_router_id 51  # 配置集群VRID,互为主备的VRID需要是相同的值nopreempt               # 设置非抢占模式,只能设置在state为backup的节点上priority 50 # 设置优先级,值范围0~254,值越大优先级越高,最高的为masteradvert_int 1 # 组播信息发送时间间隔,两个节点必须设置一样,默认为1秒
# 验证信息,两个节点必须一致authentication {auth_type PASS # 认证方式,可以是PASS或AH两种认证方式auth_pass 1111 # 认证密码}unicast_src_ip 10.0.4.21  # 设置本机内网IP地址unicast_peer {10.0.4.20             # 对端设备的IP地址}
# VIP,当state为master时添加,当state为backup时删除virtual_ipaddress {10.0.4.99 # 设置高可用虚拟VIP,如果是腾讯云的CVM,需要填写控制台申请到的HAVIP地址。}notify_master "/etc/keepalived/keepalived_notify.sh MASTER" # 当切换到master状态时执行脚本notify_backup "/etc/keepalived/keepalived_notify.sh BACKUP" # 当切换到backup状态时执行脚本notify_fault "/etc/keepalived/keepalived_notify.sh FAULT" # 当切换到fault状态时执行脚本notify_stop "/etc/keepalived/keepalived_notify.sh STOP" # 当切换到stop状态时执行脚本garp_master_delay 1    # 设置当切为主状态后多久更新ARP缓存garp_master_refresh 5   # 设置主节点发送ARP报文的时间间隔# 跟踪接口,里面任意一块网卡出现问题,都会进入故障(FAULT)状态track_interface {eth0}# 要执行的检查脚本track_script {checkhaproxy}
}

然后,重启Keepalived:

$ sudo systemctl restart keepalived

第四步:测试Keepalived

上面的配置中,10.0.4.20的优先级更高,所以正常情况下10.0.4.20将被选择为主节点,如下图所示:

图片

接下来,我们分别模拟一些故障场景,来看下配置是否生效。

场景1:Keepalived故障

10.0.4.20服务器上执行sudo systemctl stop keepalived模拟Keepalived故障,查看VIP,如下图所示:

图片

可以看到,VIP从10.0.4.20服务器上,漂移到了10.0.4.21服务器上。查看/var/log/keepalived.log,可以看到10.0.4.20服务器新增如下一行日志:

[2020-10-14 14:01:51] notify_stop

10.0.4.21服务器新增如下日志:

[2020-10-14 14:01:52] notify_master

场景2:Nginx故障

10.0.4.2010.0.4.21服务器上分别执行sudo systemctl restart keepalived,让VIP漂移到10.0.4.20服务器上。

10.0.4.20服务器上,执行 sudo systemctl stop nginx 模拟Nginx故障,查看VIP,如下图所示:

图片

可以看到,VIP从10.0.4.20服务器上,漂移到了10.0.4.21服务器上。查看/var/log/keepalived.log,可以看到10.0.4.20服务器新增如下一行日志:

[2020-10-14 14:02:34] notify_fault

10.0.4.21 服务器新增如下日志:

[2020-10-14 14:02:35] notify_master

场景3:Nginx恢复

基于场景2,在10.0.4.20服务器上执行sudo systemctl start nginx恢复Nginx,查看VIP,如下图所示:

图片

可以看到,VIP仍然在10.0.4.21服务器上,没有被10.0.4.20抢占。查看/var/log/keepalived.log,可以看到10.0.4.20服务器新增如下一行日志:

[2020-10-14 14:03:44] notify_backup

10.0.4.21服务器没有新增日志。

第五步:VIP绑定公网IP

到这里,我们已经成功配置了Keepalived + Nginx的高可用方案。但是,我们的VIP是内网,还不能通过外网访问。这时候,我们需要将VIP绑定一个外网IP,供外网访问。在腾讯云上,可通过绑定弹性公网IP来实现外网访问,需要先申请公网IP,然后将VIP绑定弹性公网IP。下面我来讲讲具体步骤。

申请公网IP:

  1. 登录私有网络控制台。
  2. 在左侧导航栏中,选择【IP与网卡】>【弹性公网IP】。
  3. 在弹性公网IP管理页面,选择所在地域,单击【申请】。

将VIP绑定弹性公网IP:

  1. 登录私有网络控制台
  2. 在左侧导航栏中,选择【IP与网卡】>【高可用虚拟】。
  3. 单击需要绑定的HAVIP所在行的【绑定】。
  4. 在弹出界面中,选择需要绑定的公网IP即可,如下图所示:

图片

绑定的弹性公网IP是106.52.252.139

这里提示下,腾讯云平台中,如果HAVIP没有绑定实例,绑定HAVIP的EIP会处于闲置状态,按¥0.2/小时 收取闲置费用。所以,你需要正确配置高可用应用,确保绑定成功。

第六步:测试公网访问

最后,你可以通过执行如下命令来测试:

$ curl -H"Host: iam.api.marmotedu.com" http://106.52.252.139/healthz -H"iam.api.marmotedu.com"
{"status":"ok"}

可以看到,我们可以成功通过公网访问后端的高可用服务。到这里,我们成功部署了一个可用性很高的IAM应用。

 

 

课后练习

  1. 思考下,当前部署架构下如果iam-apiserver需要扩容,可以怎么扩容?
  2. 思考下,当VIP切换时,如何实现告警功能,给系统运维人员告警?

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

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

相关文章

合并两个单链表

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 但行前路&#xff0c;不负韶华&#…

【教学类-50-05】20240410“数一数”4类图片添加“难度星号”

作品展示 背景需求 前期已经制作了四类“数一数”学具&#xff0c;具体样式如下&#xff1a; 1、难度1.0 【教学类-50-01】20240407“数一数”图片样式01&#xff1a;图形与边框不重合&#xff0c;图形和其他图形不相交-CSDN博客文章浏览阅读293次&#xff0c;点赞20次&…

STL容器之unordered_set类

文章目录 STL容器之unordered_set类1、unordered系列关联式容器2、unordered_set2.1、unordered_set介绍2.2、unordered_set的使用2.2.1、unordered_set的常见构造2.2.2、unordered_set的迭代器2.2.3、unordered_set的容量2.2.4、unordered_set的增删查2.2.5、unordered_set的桶…

考研数学|武忠祥各阶段用书搭配及分享

看到有人问武忠祥老师&#xff0c;不请自来 武忠祥老师&#xff0c;绝对的宝藏老师&#xff0c;我在考研强化阶段的时候听过他的强化课程&#xff0c;听完之后&#xff0c;很多问题都想通了&#xff0c;所以&#xff0c;如果有人想问武忠祥老师行不行&#xff0c;那我就一个字…

短剧在线搜索PHP网站源码

源码简介 短剧在线搜索PHP网站源码&#xff0c;自带本地数据库500数据&#xff0c;共有6000短剧视频&#xff0c;与短剧猫一样。 搭建环境 PHP 7.3 Mysql 5.6 安装教程 1.上传源码到网站目录中 2.修改【admin.php】中&#xff0c; $username ‘后台登录账号’; $passwor…

(2022级)成都工业学院数据库原理及应用实验一:CASE工具概念数据模型建模

写在前面 1、基于2022级软件工程/计算机科学与技术实验指导书 2、代码仅提供参考 3、如果代码不满足你的要求&#xff0c;请寻求其他的途径 运行环境 window11家庭版 PowerDesigner 16.1 实验要求 某医院一个门诊部排班管理子系统涉及如下信息&#xff1a; 若干科室&a…

【.Net】Polly

文章目录 概述服务熔断、服务降级、服务限流、流量削峰、错峰、服务雪崩Polly的基本使用超时策略悲观策略乐观策略 重试策略请求异常响应异常 降级策略熔断策略与策略包裹&#xff08;多种策略组合&#xff09; 参考 概述 Polly是一个被.NET基金会支持认可的框架&#xff0c;同…

通过 Cookie、Redis共享Session 和 Spring 拦截器技术,实现对用户登录状态的持有和清理(四)

本篇内容对应 “2.5 开发登录、退出功能” 小节 “4.7 优化登陆模块” 小节 2.6 显示登录信息 2.7 账号设置 2.8 检查登录状态 登录功能的流程是什么&#xff1f; UUID为什么不会重复&#xff1f; 因为UUID是基于mac物理地址、时间戳、随机数等信息生成。因此UUID居于极高的唯…

【鸿蒙开发】ArkTS和组件

1. 初识ArkTS语言 ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript生态基础上做了进一步扩展&#xff0c;继承了TS的所有特性。 当前&#xff0c;ArkTS在TS的基础上主要扩展了如下能力&#xff1a; 基本语法&#xff1a;ArkTS定义了声明式UI描述、自…

Java事件处理机制

一、介绍 java事件处理是采取“委派事件模型”。当事件发生时&#xff0c;产生事件的对象&#xff0c;会把此“信息”传递给"事件的监听者"处理&#xff0c;这里所说的"信息"实际上就是java.awt.event事件类库里某个类所创建的对象&#xff0c;把它称为&q…

2024年AI带来的革命性变革与创新

大家好&#xff01;相信大家对于AI&#xff08;人工智能&#xff09;的发展已经有了一定的了解&#xff0c;但你是否意识到&#xff0c;到了2024年&#xff0c;AI已经变得如此强大和普及&#xff0c;带来了我们从未想象过的便利和创新呢&#xff1f;让我们一起来看看AI在这个时…

基于springboot+vue+Mysql的职称评审管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

4.9日总结

1.MySQL概述 1.数据库基本概念&#xff1a;存储数据的仓库&#xff0c;数据是有组织的进行存储 2.数据库管理系统&#xff1a;操纵和管理数据库的大型软件 3.SQL&#xff1a;操作关系型数据库的编程语言&#xff0c;定义了一套操作型数据库统一标准 2.MySQL数据库 关系型数…

数据结构---顺序表实现

目录 1.顺序表 2.动态顺序表的实现 &#xff08;4&#xff09;顺序表初始化 &#xff08;5&#xff09;顺序表销毁 &#xff08;6&#xff09;顺序表的插入 a.尾插 b.头插 &#xff08;7&#xff09;顺序表的删除 a.尾删 b.头删 &#xff08;8&#xff09;指定位置之…

GitHub 仓库 (repository) Watch - Star - Fork - Follow

GitHub 仓库 [repository] Watch - Star - Fork - Follow References 眼睛图标旁边写着 Watch 字样。点击这个按钮就可以 Watch 该仓库&#xff0c;今后该仓库的更新信息会显示在用户的公开活动中。Star 旁边的数字表示给这个仓库添加 Star 的人数。这个数越高&#xff0c;代表…

HuggingFists-如何复用流程

在使用HuggingFists进行业务流程编写时&#xff0c;很可能会发现多个流程间拥有相同的流程片段。按照通常的思考&#xff0c;如果能将这些相同的片段封装为一个可复用的子流程&#xff0c;在各个主流程中引用使用&#xff0c;就可以避免每次重复编写该片段&#xff0c;省去不必…

泰迪智能科技高职人工智能专业人才培养方案

人工智能行业近年来得到了快速发展&#xff0c;全球科技公司都在竞相投入人工智能的研发&#xff0c;从硅谷到北京&#xff0c;都在人工智能上取得了显著的进步。人工智能已经从学术研究转变为影响制造业、医疗保健、交通运输和零售等多个行业的关键因素。我国政策的积极推动下…

Windows下docker-compose部署DolphinScheduler

参照&#xff1a;快速上手 - Docker部署(Docker) - 《Apache DolphinScheduler v3.1.0 使用手册》 - 书栈网 BookStack 下载源文件 地址&#xff1a;https://dolphinscheduler.apache.org/zh-cn/download/3.2.1 解压到指定目录&#xff0c;进入apache-dolphinscheduler-xxx-…

4.2.4 理解路由器数据包过程

1、实验目的 通过本实验可以掌握&#xff1a; 了解IP路由原理了解数据包封装和解封装的概念了解路由器路由和交换过程 2、实验拓扑 观察路由器路由数据包过程的实验拓扑如图4-3所示&#xff0c;设备接口地址信息如表4-2所示。 图4-3 观察路由器路由数据包过程的实验拓扑 本…

H.265视频直播点播录像EasyPlayer.js流媒体播放器用户常见问题及解答

EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;无须安装任何插件&#xff0c;起播快、延迟低、兼容性强&#xff0c;使用非常便捷。 今天我们来汇总下用户常见的几个问题及解答。 1、EasyPlayer.js播放多路H.265视…