haproxy七层代理

目录

一、haproxy简介

二、haproxy实验

1.环境部署

2.haproxy的基本部署方法及负载均衡的实现

2.1安装软件

2.2haproxy的基本配置

3.haproxy的全局配置参数及日志分离

3.1多线程设定

3.2自定义日志

4.haproxy-proxies中的常用配置参数

4.1设置backup --- sorryserver的端口

4.2访问重定向

5.haproxy热更新方法

5.1socat

6.haproxy中的算法

6.1静态算法

6.1.1static-rr:基于权重的轮询调度

6.1.2 first

6.2动态算法

6.2.1roundrobin

6.2.2 leastconn

6.3其他算法

6.3.1source

6.3.1.1 map-base 取模法

6.3.1.2 一致性hash

6.3.2 uri

6.3.2.1 uri 取模法配置示例

6.3.3 url_param

6.3.3.1 url_param取模法配置示例

6.3.4 hdr

6.3.4.1 hdr取模法配置示例

6.3.6 算法总结

6.3.7 各算法使用场景

三.高级功能及配置

3.1基于cookie的会话保持

3.1.1 配置选项

​编辑

3.2HAProxy状态页

3.2.1 状态页配置项

3.3 IP透传

3.3.2 四层IP透传

3.3.3 七层IP透传

3.4 ACL

基于源IP或子网调度访问

基于浏览器的访问控制

基于文件后缀名实现动静分离

 重定向错误文件

3.5 haproxy的四层负载

3.6 haproxy中https实现

3.6.1 证书制作


一、haproxy简介

HAProxy 是法国开发者 威利塔罗 (Willy Tarreau) 2000 年使用 C 语言开发的一个开源软件
是一款具备高并发 ( 万级以上 ) 、高性能的 TCP HTTP 负载均衡器
支持基于 cookie 的持久性,自动故障切换,支持正则表达式及 web 状态统计
企业版网站: https://www.haproxy.com
社区版网站: http://www.haproxy.org
github https://github.com/haprox
企业版本和社区版功能对比

二、haproxy实验

1.环境部署

haproxy192.168.5.100
webserver1192.168.5.10
webserver2192.168.5.20

2.haproxy的基本部署方法及负载均衡的实现

2.1安装软件
dnf install haproxy -y
2.2haproxy的基本配置

3.haproxy的全局配置参数及日志分离

3.1多线程设定

3.2自定义日志
vim /etc/rsyslog.conf

4.haproxy-proxies中的常用配置参数

4.1设置backup --- sorryserver的端口

disabled指定下线的后端服务器

4.2访问重定向

5.haproxy热更新方法

5.1socat

下载

dnf install socat -y
# 查看 haproxy 状态
[root@haproxy ~]# echo "show info" | socat stdio /var/lib/haproxy/stats

# 查看集群状态
[root@haproxy ~]# echo "show servers state" | socat stdio /var/lib/haproxy/stats

# 查看集群权重
[root@haproxy ~]# echo get weight webcluster/web1 | socat stdio /var/lib/haproxy/stats
2 (initial 2)
[root@haproxy ~]# echo get weight webcluster/web2 | socat stdio /var/lib/haproxy/stats
1 (initial 1)
# 设置权重
[root@haproxy ~]# echo "set weight webcluster/web1 1 " | socat stdio /var/lib/haproxy/stats
[root@haproxy ~]# echo "set weight webcluster/web1 2 " | socat stdio /var/lib/haproxy/stats
# 下线后端服务器
[root@haproxy ~]# echo "disable server webcluster/web1 " | socat stdio
/var/lib/haproxy/stats
# 上线后端服务器
[root@haproxy ~]# echo "enable server webcluster/web1 " | socat stdio /var/lib/haproxy/stats
针对多进程问题

6.haproxy中的算法

6.1静态算法
静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度 等,且无法实时修改权重( 只能为 0 1, 不支持其它值 ) ,只能靠重启 HAProxy 生效。
6.1.1static-rr:基于权重的轮询调度

6.1.2 first
# 在两台主机上分别执行此循环,可以观察是否 102 被调度到
while true;do curl 172.25.254.100 ; sleep 0.1;done
6.2动态算法
6.2.1roundrobin

动态调整权重
[root@haproxy ~]# echo "set weight webserver_80/webserver1 2" | socat stdio
/var/lib/haproxy/haproxy.sock
6.2.2 leastconn

6.3其他算法
6.3.1source

6.3.1.1 map-base 取模法

所谓取模运算,就是计算两个数相除之后的余数, 10%7=3, 7%4=3
map-based 算法:基于权重取模, hash(source_ip)% 所有后端服务器相加的总权重
比如当源 hash 值时 1111 1112 1113 ,三台服务器 a b c 的权重均为 1
abc 的调度标签分别会被设定为 0 1 2 1111%3=1 1112%3=2 1113%3=0
1111 ----- > nodeb
1112 ------> nodec
1113 ------> nodea
如果 a 下线后,权重数量发生变化
1111%2=1 1112%2=0 1113%2=1
1112 1113 被调度到的主机都发生变化,这样会导致会话丢失
# 不支持动态调整权重值
[root@haproxy ~]# echo "set weight webserver_80/webserver1 2" | socat stdio
/var/lib/haproxy/haproxy.sock
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.
# 只能动态上线和下线
[root@haproxy ~]# echo "set weight webserver_80/webserver1 0" | socat stdio
/var/lib/haproxy/haproxy.sock
[root@haproxy ~]# echo "get weight webserver_80/webserver1" | socat stdio
/var/lib/haproxy/haproxy.sock
0 (initial 1)
6.3.1.2 一致性hash

一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动 hash o ) mod n
hash 算法是动态的,支持使用 socat 等工具进行在线权重调整,支持慢启动
1 、后端服务器哈希环点 keyA=hash( 后端服务器虚拟 ip)%(2^32)
2 、客户机哈希环点 key1=hash(client_ip)%(2^32) 得到的值在 [0---4294967295] 之间,
3 、将 keyA key1 都放在 hash 环上,将用户请求调度到离 key1 最近的 keyA 对应的后端服务器

hash 环偏斜问题
增加虚拟服务器 IP 数量,比如:一个后端服务器根据权重为 1 生成 1000 个虚拟 IP ,再 hash 。而后端服务器权 重为2 则生成 2000 的虚拟 IP ,再 bash, 最终在 hash 环上生成 3000 个节点,从而解决 hash 环偏斜问题
hash 对象
Hash 对象到后端服务器的映射关系:
一致性 hash 示意图
后端服务器在线与离线的调度方式
一致性 hash 配置示例
6.3.2 uri
基于对用户请求的 URI 的左半部分或整个 uri hash ,再将 hash 结果对总权重进行取模后
根据最终结果将请求转发到后端指定服务器
适用于后端是缓存服务器场景
默认是静态算法,也可以通过 hash-type 指定 map-based consistent ,来定义使用取模法还是一致性hash
注意:此算法基于应用层,所以只支持 mode http ,不支持 mode tcp
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
左半部分: /<path>;<params>
整个 uri /<path>;<params>?<query>#<frag>
6.3.2.1 uri 取模法配置示例

6.3.3 url_param
url_param 对用户请求的 url 中的 params 部分中的一个参数 key 对应的 value 值作 hash 计算,并由服务器
总权重相除以后派发至某挑出的服务器 , 后端搜索同一个数据会被调度到同一个服务器,多用与电商
通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个 real server
如果无没 key ,将按 roundrobin 算法
# 假设:
url = http://www.timinglee.com/foo/bar/index.php?key=value
# 则:
host = "www.timinglee.com"
url_param = "key=value"
6.3.3.1 url_param取模法配置示例

6.3.4 hdr
针对用户每个 http 头部 (header) 请求中的指定信息做 hash
此处由 name 指定的 http 首部将会被取出并做 hash 计算,
然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。
6.3.4.1 hdr取模法配置示例

6.3.6 算法总结
# 静态
static-rr--------->tcp/http
first------------->tcp/http
# 动态
roundrobin-------->tcp/http
leastconn--------->tcp/http
# 以下静态和动态取决于 hash_type 是否 consistent
source------------>tcp/http
Uri--------------->http
url_param--------->http
hdr--------------->http
6.3.7 各算法使用场景
first # 使用较少
static-rr # 做了 session 共享的 web 集群
roundrobin
leastconn # 数据库
source
# 基于客户端公网 IP 的会话保持
Uri--------------->http # 缓存服务器, CDN 服务商,蓝汛、百度、阿里云、腾讯
url_param--------->http # 可以实现 session 保持
hdr # 基于客户端请求报文头部做下一步处理

三.高级功能及配置

3.1基于cookie的会话保持
cookie value :为当前 server 指定 cookie 值,实现基于 cookie 的会话黏性,相对于基于 source 地址 hash调度算法对客户端的粒度更精准,但同时也加大了haproxy 负载,目前此模式使用较少, 已经被 session共享服务器代替
3.1.1 配置选项
cookie name [ rewrite | insert | prefix ][ indirect ] [ nocache ][ postonly ] [
preserve ][ httponly ] [ secure ][ domain ]* [ maxidle <idle> ][ maxlife ]
name #cookie key 名称,用于实现持久连接
insert # 插入新的 cookie, 默认不插入 cookie
indirect # 如果客户端已经有 cookie, 则不会再发送 cookie 信息
nocache # client hapoxy 之间有缓存服务器(如: CDN )时,不允许中间缓存器缓存 cookie
# 因为这会导致很多经过同一个 CDN 的请求都发送到同一台后端服务器

3.2HAProxy状态页
3.2.1 状态页配置项
stats enable # 基于默认的参数启用 stats page
stats hide-version # 将状态页中 haproxy 版本隐藏
stats refresh <delay> # 设定自动刷新时间间隔,默认不自动刷新
stats uri <prefix> # 自定义 stats page uri ,默认值: /haproxy?stats
stats auth <user>:<passwd> # 认证时的账号和密码,可定义多个用户 , 每行指定一个用户
# 默认: no authentication
stats admin { if | unless } <cond> # 启用 stats page 中的管理功能
登录状态页
#pid 为当前 pid 号, process 为当前进程号, nbproc nbthread 为一共多少进程和每个进程多少个线程
pid = 27134 (process #1, nbproc = 1, nbthread = 1)
# 启动了多长时间
uptime = 0d 0h00m04s
# 系统资源限制:内存 / 最大打开文件数 /
system limits: memmax = unlimited; ulimit-n = 200029
# 最大 socket 连接数 / 单进程最大连接数 / 最大管道数 maxpipes
maxsock = 200029; maxconn = 100000; maxpipes = 0
# 当前连接数 / 当前管道数 / 当前连接速率
current conns = 2; current pipes = 0/0; conn rate = 2/sec; bit rate = 0.000 kbps
# 运行的任务 / 当前空闲率
Running tasks: 1/14; idle = 100 %
active UP # 在线服务器
backup UP # 标记为 backup 的服务器
active UP, going down # 监测未通过正在进入 down 过程
backup UP, going down # 备份服务器正在进入 down 过程
active DOWN, going up #down 的服务器正在进入 up 过程
backup DOWN, going up # 备份服务器正在进入 up 过程
active or backup DOWN # 在线的服务器或者是 backup 的服务器已经转换成了 down 状态
not checked # 标记为不监测的服务器
#active 或者 backup 服务器人为下线的
active or backup DOWN for maintenance (MAINT)
#active 或者 backup 被人为软下线 ( 人为将 weight 改成 0)
active or backup SOFT STOPPED for maintenance
backend server 信息
session rate( 每秒的连接会话信息 ):
Errors( 错误统计信息 )
cur: 每秒的当前会话数量 :
Req: 错误请求量
max: 每秒新的最大会话数量
conn: 错误链接量
limit: 每秒新的会话限制量
Resp: 错误响应量
sessions( 会话信息 ):
Warnings( 警告统计信息 )
cur: 当前会话量
Retr: 重新尝试次数
max: 最大会话量
Redis: 再次发送次数
limit: 限制会话量
Total: 总共会话量
Server(real server 信息 )
LBTot: 选中一台服务器所用的总时间
Status: 后端机的状态,包括 UP DOWN
Last :和服务器的持续连接时间
LastChk: 持续检查后端服务器的时间
Wght: 权重
Bytes( 流量统计 )
Act: 活动链接数量
In: 网络的字节输入总量
Bck: 备份的服务器数量
Out: 网络的字节输出总量
Chk: 心跳检测时间
Dwn: 后端服务器连接后都是 DOWN 的数量
Denied( 拒绝统计信息 )
Dwntme: 总的 downtime 时间
Req: 拒绝请求量
Thrtle:server 状态
Resp: 拒绝回复量
####
3.3 IP透传
3.3.2 四层IP透传

# 查看日志内容
[root@rs1 ~]# tail -n 3 /var/log/nginx/access.log
192.168.0.10 - - [10/Jul/2024:15:21:00 +0800] "GET / HTTP/1.1"200 18 "-"
"curl/7.29.0" "-"
192.168.0.10 - - [10/Jul/2024:15:26:11 +0800] "GET / HTTP/1.1"200 18 "-"
"curl/7.29.0" "-"
192.168.0.10 - - [10/Jul/2024:15:41:56 +0800] "GET / HTTP/1.1" "172.25.254.10"200
18 "-" "curl/7.29.0"
3.3.3 七层IP透传

配置 web 服务器,记录负载均衡透传的客户端 IP 地址
#apache 配置:
LogFormat "%{X-Forwarded-For}i %a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%
{User-Agent}i\"" combined
#nginx 日志格式:
$proxy_add_x_forwarded_for: 包括客户端IP和中间经过的所有代理的IP
$http_x_forwarded_For: 只有客户端IP
log_format main '"$proxy_add_x_forwarded_for" - $remote_user [$time_local]
"$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_For';
#查看日志如下:
[root@rs1 ~]# tail -n 3 /var/log/nginx/access.log
"172.25.254.10, 192.168.0.10" 192.168.0.10 - - [10/Jul/2024:16:15:00 +0800] "GET
/ HTTP/1.1"200 18 "-" "curl/7.29.0" "172.25.254.10"
[root@rs2 ~]# tail -n 3 /etc/httpd/logs/access_log
172.25.254.10 192.168.0.10 - - [11/Jul/2024:00:15:00 +0800] "GET / HTTP/1.1" 200
27 "-" "curl/7.29.0
3.4 ACL

基于源IP或子网调度访问
示例:
vim/etc/haproxy/haproxy.cfgfrontend webclusterbind *:80mode httpacl ctrl_ip src 172.25.254.1 172.25.254.20 192.168.0.0/24  -----符合条件的访问RS1use_backend webcluster-host if  ctrl_ipdefault_backend default-hostbackend webcluster-hostmode httpserver web1 172.25.254.10:80 check inter 2 fall 2 rise 5backend default-hostmode httpserver web2 172.25.254.20:80 check inter 2 fall 2 rise 5
测试:
[root@werserver2 ~]# curl 172.25.254.100
webserver1 - 172.25.254.10[root@haproxy ~]# curl www.test.com
webserver2 - 172.25.254.20
[root@haproxy ~]# 
frontend webclusterbind *:80mode httpacl ctrl_ip src 172.25.254.1 172.25.254.20 192.168.0.0/24http-request deny if ctrl_ip    ------ 符合条件的拒绝访问default_backend default-hostbackend webcluster-hostmode httpserver web1 172.25.254.10:80 check inter 2 fall 2 rise 5backend default-hostmode httpserver web2 172.25.254.20:80 check inter 2 fall 2 rise 5
测试:
[root@werserver2 ~]# curl 172.25.254.100
webserver1 - 172.25.254.10
[root@werserver2 ~]# curl 172.25.254.100
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
[root@werserver2 ~]# [root@haproxy ~]# curl www.test.com   ---- 默认走RS2,走的default
webserver2 - 172.25.254.20
基于浏览器的访问控制
示例:
vim/etc/haproxy/haproxy.cfgfrontend webclusterbind *:80mode httpacl badwebrowers hdr_sub(User-Agent) -i wgethttp-request deny if badwebrowersdefault_backend default-hostbackend webcluster-hostmode httpserver web1 172.25.254.10:80 check inter 2 fall 2 rise 5backend default-hostmode httpserver web2 172.25.254.20:80 check inter 2 fall 2 rise 5
基于文件后缀名实现动静分离
RS主机上:
[root@webserver1 ~]# dnf install php -y
[root@webserver1 ~]# systemctl restart nginx.service 
[root@webserver1 ~]# 
[root@webserver1 ~]# vim /usr/share/nginx/html/index.php
<?php   phpinfo();
?>查看是否能访问到php

自定义haproxy的错误界面

两台web服务都给他挂掉
[root@werserver1 ~]# systemctl stop nginx.service 
[root@werserver2 ~]# systemctl stop nginx.service此时访问不到

 重定向错误文件

3.5 haproxy的四层负载

测试

3.6 haproxy中https实现
haproxy 可以实现 https 的证书安全 , 从用户到 haproxy https, haproxy 到后端服务器用 http 通信
但基于性能考虑 , 生产中证书都是在后端服务器比如 nginx 上实现
#配置HAProxy支持https协议,支持ssl会话;
bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE
#指令 crt 后证书文件为PEM格式,需要同时包含证书和所有私钥
cat demo.key demo.crt > demo.pem
#把80端口的请求重向定443
bind *:80
redirect scheme https if !{ ssl_fc }
3.6.1 证书制作
haproxy ~]# mkdir /etc/haproxy/certs/
haproxy ~]# openssl req -newkey rsa:2048 \
-nodes -sha256 –keyout /etc/haproxy/certs/timinglee.org.key \
-x509 -days 365 -out /etc/haproxy/certs/timinglee.org.crt
3.6.2 https 配置示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webserver
bind *:80
redirect scheme https if !{ ssl_fc }
mode http
use_backend webcluster
frontend webserver-https
bind *:443 ssl crt /etc/haproxy/timinglee.org.pem
mode http
use_backend webcluster
backend webcluster
mode http
balance roundrobin
server web1 172.25.254.200:80 check inter 3s fall 3 rise 5
server web2 172.25.254.201:80 check inter 3s fall 3 rise 5
[root@客户端 ~]#curl -IkL http://172.25.254.100
HTTP/1.1 302 Found
content-length: 0
location: https://www.timinglee.org/
cache-control: no-cache
HTTP/1.1 200 OK
date: Sat, 04 Apr 2020 02:31:31 GMT
server: Apache/2.4.6 (CentOS) PHP/5.4.16
last-modified: Thu, 02 Apr 2020 01:44:13 GMT
etag: "a-5a244f01f8adc"
accept-ranges: bytes
content-length: 10
content-type: text/html; charset=UTF-8
[root@centos6 ~]#curl -Ik https://www.timinglee.org
HTTP/1.1 200 OK
date: Sat, 04 Apr 2020 02:31:50 GMT
server: Apache/2.4.6 (CentOS) PHP/5.4.16
last-modified: Thu, 02 Apr 2020 01:44:28 GMT
etag: "a-5a244f0fd5175"
accept-ranges: bytes
content-length: 10
content-type: text/html; charset=UTF-8

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

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

相关文章

卷积神经网络(李宏毅老师系列)

自学参考&#xff1a; 一文搞懂卷积神经网络&#xff08;CNN&#xff09;的原理 视频课 课件资料 笔记 一、引入 cnn设计灵感来自于生物学中的视觉系统&#xff0c;旨在模拟人类视觉处理的方式。常用场景&#xff1a;image classification 基本步骤&#xff1a; 把所有图片都先…

数据结构--第六天

--树 -树的基本概念 树结构通常用来储存逻辑关系为“一对多”的数据&#xff0c;例如&#xff1a; 上图的这些元素具有的就是 "一对多" 的逻辑关系&#xff0c;例如元素A同时和B、C、D有关系&#xff0c;元素D同时和A、H、I、J有关系等。 观察这些元素之间的逻辑关…

模拟经营之神:《北境之地》安卓手机游戏,免费分享

《北境之地》&#xff08;Northgard&#xff09;是一款以北欧神话为背景的即时战略游戏&#xff0c;由Shiro Games开发。玩家在游戏中扮演维京部落的领袖&#xff0c;目标是探索新大陆、建立据点、管理资源&#xff0c;并在严酷的冬季和敌人的威胁下生存下来 。 游戏特色包括&a…

gin路由

1主文件 package main import ("github.com/gin-gonic/gin""godade/user""net/http" ) func main() {router : gin.Default()router.GET("/", func(c *gin.Context) {c.String(http.StatusOK, "Hello World")})v1 : router…

如何避免项目发布后用户从浏览器WebPack中看到源码

打包前在config->index.js中设置productionSourceMap为false productionSourceMap: false,

C# AI鉴图宝 利用OCR技术对违规图片进行判别

目录 效果 项目 代码 下载 效果 项目 代码 using Aspose.Cells; using NLog; using OpenCvSharp; using OpenVINO.OCRService; using Sdcb.OpenVINO; using Sdcb.OpenVINO.PaddleOCR; using Sdcb.OpenVINO.PaddleOCR.Models; using System; using System.Collections.Conc…

Jmeter性能压测4000并发

性能测试的底层逻辑 程序为什么会有性能问题 用户操作 客户端&#xff08;web/app/小程序&#xff09;触发网络请求&#xff0c;服务器处理大量网络请求代码运行需要大量服务器资源&#xff08;CPU、内存、网络、磁盘等等&#xff09; 资源不是无限&#xff0c;硬件配置不是随…

使用Python发送PDD直播间弹幕(协议算法分析)

文章目录 1. 写在前面2. 接口分析3. 算法还原 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…

日撸Java三百行(day19:字符串匹配)

目录 一、字符串的一些基础知识 二、代码实现 1.字符类的创建 2.字符类的遍历 3.字符串匹配 4.字符串截取 5.数据测试 6.完整的程序代码 总结 一、字符串的一些基础知识 字符串&#xff08;String&#xff09;是用一对双引号括起来的零个或多个字符组成的有限序列&am…

简单的docker学习 第13章 CI/CD与Jenkins(上)

第13章 CI/CD 与 Jenkins 13.1 平台登录页面 13.1.1 GitLab-8098-root 13.1.2 Jenkins-8080-zhangsan 13.1.3 SonarQube-9000-admin 13.1.4 harbor-80-admin 13.2 CI/CD 与 DevOps 13.2.1 CI/CD 简介 CI > Continuous Integration&#xff0c;持续集成。即将持续不断更新…

如何在linux系统上部署nginx

1&#xff09;首先去 nginx.org/download 官网下载你所需要的版本 我这里是下载的 nginx-1-23-3.tar.gz 2&#xff09;然后执行 yum -y install lrzsz 安装文件上传软件 执行 rz 选择你下载nginx的位置进行上传 yum -y install lrzsz 3&#xff09;执行 tar -zxvf nginx-1.23…

数据可视化(爬取豆瓣网站)

目录 1 绪论 1.1 研究背景 1.2 研究目的和意义 1.3 研究内容和方法 2. 需求分析 2.1 系统功能描述 2.2 数据采集与预处理 2.2.1 数据采集 2.2.2 数据清洗 2.2.3 数据处理 2.3 功能需求 2.3.1 登录模块 2.3.2 数据展示模块 3 系统设计 3.1 系统功能结构设计 3.2 …

Pycharm中重命名项目之后切换虚拟环境

Pycharm中重命名项目之后切换虚拟环境 场景 在Pycharm里面Rename Project/Directory之后&#xff0c;通常需要切换虚拟环境。 步骤 # 退出当前虚拟环境 deactivate # 删除旧的虚拟环境 .venv # 新建新的虚拟环境 python -m venv .venv # 切换到新的工程目录 cd E:\Bigdata\…

排序算法——插入排序

一、插入排序概念 直接插入排序&#xff08;Insertion Sort&#xff09;是一种简单的排序算法&#xff0c;它的工作原理类似于人们手动排序卡片的方式。该算法通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插…

二叉树相关的算法题

二叉树相关的算法题 单值二叉树 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。 只有给定的树是单值二叉树时&#xff0c;才返回 true&#xff1b;否则返回 false。 示例 1&#xff1a; 输入&#xff1a;[1,1,1,1,1,null,1] 输出&#xff1a;t…

初阶数据结构5 排序

排序 1. 排序概念及运用1.1 概念1.2运用1.3 常见排序算法 2. 实现常⻅排序算法2.1 插⼊排序2.1.1 直接插⼊排序2.1.2 希尔排序2.1.2.1 希尔排序的时间复杂度计算 2.2 选择排序2.2.1 直接选择排序2.2.2 堆排序 2.3 交换排序2.3.1冒泡排序2.3.2 快速排序2.3.2.1 hoare版本2.3.2.2…

【云服务器系列】基于华为云OBS实现Picgo和Typora的完美融合

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

STM32-IIC协议详解

一、IIC简介 IC&#xff08;Inter-Integrated Circuit&#xff09;协议由飞利浦公司于1980年代开发&#xff0c;是一种用于集成电路间短距离通信的串行协议。它设计用于连接低速外围设备&#xff0c;特别适合于需要简单数据交换的场景。IC协议使用两根信号线&#xff1a;SCL&am…

Python数值计算(23)——modified akima插值

1. 数学原理 在前面的Akima插值中&#xff0c;计算斜率使用如下公式&#xff1a; 如果记&#xff1a; 在出现分母分子同时为零的情况时&#xff0c;会出现NaN的计算结果&#xff0c;Akima他自己也意识到这种问题&#xff0c;因此&#xff0c;在原来的算法上做了修订&#xff0…

Python | Leetcode Python题解之第330题按要求补齐数组

题目&#xff1a; 题解&#xff1a; class Solution:def minPatches(self, nums: List[int], n: int) -> int:patches, x 0, 1length, index len(nums), 0while x < n:if index < length and nums[index] < x:x nums[index]index 1else:x << 1patches …