负载均衡(3)

文章目录

  • 一、HAProxy介绍
    • 企业版
    • 社区版
    • 版本对比
    • HAProxy功能
    • 支持功能
    • 不具备的功能
  • 二、编译安装HAProxy
    • 解决lua环境
      • Centos 基础环境
    • 编译安装HAProxy
    • 验证HAProxy版本
    • HAProxy启动脚本
    • 配置文件
    • 启动haproxy
    • 验证haproxy状态
    • 查看haproxy的状态页面
  • 三、HAProxy基础配置详解
    • global配置
      • global 配置参数说明
      • 多进程和线程
    • 日志配置
      • HAProxy配置
      • Rsyslog配置
      • 验证HAProxy日志
  • 四、Proxies配置
    • Proxies配置-defaults
    • Proxies配置-frontend
    • Proxies配置-backend
      • option 配置
    • frontend+backend配置实例
    • listen替代frontend+backend
    • 使用子配置文件保存配置
  • 五、HAProxy调度算法
    • 静态算法
      • static-rr
      • first
    • 动态算法
      • roundrobin
      • leastconn
      • random
    • 其他算法
      • source
      • map-base取模法
      • 一致性hash
      • uri
      • url_param
      • hdr
      • rdp-cookie
    • 算法总结
    • 各算法使用场景
  • 六、HAProxy状态页
    • backend server信息
  • 七、利用状态页实现haproxy服务器的健康性检查

一、HAProxy介绍

​ HAProxy是法国开发者威利塔罗(Willy Tarreau)在2000年使用C语言开发的一个开源软件,是一款具备高并发(一万以上)、高性能的TCP和HTTP负载均衡器,支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计,目前最新TLS版本为2.0

历史版本:

  • 历史版本更新功能:1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2-dev
  • 1.8:多线程,HTTP/2缓存……
  • 1.7:服务器动态配置,多类型证书……
  • 1.6:DNS解析支持,HTTP连接多路复用……
  • 1.5:开始支持SSL,IPV6,会话保持……

从2013年HAProxy 分为社区版和企业版,企业版将提供更多的特性和功能以及全天24小时的技术支持等服务。

企业版

企业版网站:https://www.haproxy.com/
在这里插入图片描述

社区版

社区版网站:http://www.haproxy.org/

github:https://github.com/haproxy
在这里插入图片描述

版本对比

功能社区版企业版
高级HTTP / TCP负载平衡和持久性支持支持
高级健康检查支持支持
应用程序加速支持支持
高级安全特性支持支持
高级管理支持支持
HAProxy Dev Branch新功能支持
24*7 支持服务支持
实时仪表盘支持
VRRP和Route Health Injection HA工具支持
ACL,映射和TLS票证密钥同步支持
基于应用程序的高级DDoS和Bot保护(自动保护)支持
Bot(机器人)监测支持
Web应用防火墙支持
HTTP协议验证支持
实时集群追踪支持

HAProxy功能

在这里插入图片描述
在这里插入图片描述

支持功能

  • TCP 和 HTTP反向代理
  • SSL/TSL服务器
  • 可以针对HTTP请求添加cookie,进行路由后端服务器
  • 可平衡负载至后端服务器,并支持持久连接
  • 支持所有主服务器故障切换至备用服务器
  • 支持专用端口实现监控服务
  • 支持停止接受新连接请求,而不影响现有连接
  • 可以在双向添加,修改或删除HTTP报文首部
  • 响应报文压缩
  • 支持基于pattern实现连接请求的访问控制
  • 通过特定的URI为授权用户提供详细的状态信息
  • 支持动态程序的反向代理
  • 支持基于数据库的反向代理

不具备的功能

  • 正向代理–squid,nginx
  • 缓存代理–varnish
  • web服务–nginx、tengine、apache、php、tomcat
  • UDP–目前不支持UDP协议
  • 单机性能–相比LVS性能较差

二、编译安装HAProxy

编译安装HAProxy 2.0 LTS版本,更多源码包下载地址:http://www.haproxy.org/download/

  • centos7自带的源中yum安装的版本是较老的1.5的版本
    在这里插入图片描述

解决lua环境

HAProxy 支持基于lua实现功能扩展,lua是一种小巧的脚本语言,于1993年由巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组开发,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

Lua 官网:www.lua.org

  • Lua 应用场景
    • 游戏开发
    • 独立应用脚本
    • Web 应用脚本
    • 扩展和数据库插件,如MySQL Proxy
    • 安全系统,如入侵检测系统

Centos 基础环境

参考链接:http://www.lua.org/start.html
在这里插入图片描述
由于CentOS7 之前版本自带的lua版本比较低并不符合HAProxy要求的lua最低版本(5.3)的要求,因此需要编译安装较新版本的lua环境,然后才能编译安装HAProxy,过程如下

  • 当前系统版本
[root@localhost ~]# lua -v
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
  • 安装基础命令及编译依赖环境
[root@localhost ~]# yum -y install gcc readline-devel
[root@localhost ~]# wget http://www.lua.org/ftp/lua-5.3.5.tar.gz
[root@localhost ~]# tar xvf lua-5.3.5.tar.gz -C /usr/local/src
[root@localhost ~]# cd /usr/local/src/lua-5.3.5
[root@localhost lua-5.3.5]# make linux test
  • 查看编译安装的版本
[root@localhost lua-5.3.5]# src/lua -v
Lua 5.3.5 Copyright (C) 1994-2018 Lua.org, PUC-Rio

编译安装HAProxy

  • HAProxy 1.8及1.9版本编译参数
make ARCH=x86_64 TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_CPU_AFFINITY=1 PREFIX=/usr/local/haproxy
  • HAProxy 2.0以上版本编译参数
[root@localhost ~]# yum -y install gcc openssl-devel pcre-devel systemd-devel
[root@localhost ~]# wget http://www.haproxy.org/download/2.1/src/haproxy-2.1.3.tar.gz
[root@localhost ~]# tar xvf haproxy-2.1.3.tar.gz -C /usr/local/src
[root@localhost ~]# cd /usr/local/src/haproxy-2.1.3/
[root@localhost haproxy-2.1.3]# cat README
  • 参考INSTALL文件进行编译安装
[root@localhost haproxy-2.1.3]# make ARCH=x86_64 TARGET=linux-glibc \
USE_PCRE=1 \
USE_OPENSSL=1 \
USE_ZLIB=1 \
USE_SYSTEMD=1 \
USE_LUA=1 \
LUA_INC=/usr/local/src/lua-5.3.5/src/ \
LUA_LIB=/usr/local/src/lua-5.3.5/src/
[root@localhost haproxy-2.1.3]# make install PREFIX=/apps/haproxy
[root@localhost haproxy-2.1.3]# ln -s /apps/haproxy/sbin/haproxy /usr/sbin/
  • 查看生成的文件
[root@localhost ~]# tree -C /apps/haproxy/
/apps/haproxy/
├── doc
│ 	└── haproxy
│ 	├── 51Degrees-device-detection.txt
│ 	├── architecture.txt
│ 	├── close-options.txt
│ 	├── configuration.txt
│ 	├── cookie-options.txt
│ 	├── DeviceAtlas-device-detection.txt
│ 	├── intro.txt
│ 	├── linux-syn-cookies.txt
│ 	├── lua.txt
│ 	├── management.txt
│ 	├── netscaler-client-ip-insertion-protocol.txt
│ 	├── network-namespaces.txt
│ 	├── peers.txt
│ 	├── peers-v2.0.txt
│ 	├── proxy-protocol.txt
│ 	├── regression-testing.txt
│ 	├── seamless_reload.txt
│ 	├── SOCKS4.protocol.txt
│ 	├── SPOE.txt
│ 	└── WURFL-device-detection.txt
├── sbin
│ 	└── haproxy
└── share
	└── man
		└── man1
			└── haproxy.1

6 directories, 22 files

验证HAProxy版本

[root@localhost ~]# which haproxy
/usr/sbin/haproxy
[root@localhost ~]# haproxy -v
HA-Proxy version 2.1.3 2020/02/12 - https://haproxy.org/
Status: stable branch - will stop receiving fixes around Q1 2021.
Known bugs: http://www.haproxy.org/bugs/bugs-2.1.3.html

[root@localhost ~]# haproxy -vv
HA-Proxy version 2.1.3 2020/02/12 - https://haproxy.org/
Status: stable branch - will stop receiving fixes around Q1 2021.
Known bugs: http://www.haproxy.org/bugs/bugs-2.1.3.html
Build options :
	TARGET = linux-glibc
	CPU = generic
	CC = gcc
	CFLAGS = -m64 -march=x86-64 -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement -fwrapv -Wno-unused-label -Wno-sign-compare -Wno-unused-parameter -Wno-old-style-declaration -Wno-ignored-qualifiers -Wno-clobbered -Wno-missing-field-initializers -Wtype-limits
	OPTIONS = USE_PCRE=1 USE_OPENSSL=1 USE_LUA=1 USE_ZLIB=1 USE_SYSTEMD=1
	
Feature list : +EPOLL -KQUEUE -MY_EPOLL -MY_SPLICE +NETFILTER +PCRE -PCRE_JIT -PCRE2 -PCRE2_JIT +POLL -PRIVATE_CACHE +THREAD -PTHREAD_PSHARED -REGPARM -STATIC_PCRE -STATIC_PCRE2 +TPROXY +LINUX_TPROXY +LINUX_SPLICE +LIBCRYPT +CRYPT_H -VSYSCALL +GETADDRINFO +OPENSSL +LUA +FUTEX +ACCEPT4 -MY_ACCEPT4 +ZLIB -SLZ +CPU_AFFINITY +TFO +NS +DL +RT -DEVICEATLAS -51DEGREES -WURFL +SYSTEMD -OBSOLETE_LINKER +PRCTL +THREAD_DUMP -EVPORTS

Default settings :
	bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
	
Built with multi-threading support (MAX_THREADS=64, default=4).
Built with OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017
Running on OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : SSLv3 TLSv1.0 TLSv1.1 TLSv1.2
Built with Lua version : Lua 5.3.5
Built with network namespace support.
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Built with PCRE version : 8.32 2012-11-30
Running on PCRE version : 8.32 2012-11-30
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Encrypted password support via crypt(3): yes
Built with zlib version : 1.2.7
Running on zlib version : 1.2.7
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")

Available polling systems :
	epoll : pref=300, test result OK
	poll : pref=200, test result OK
	select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.

Available multiplexer protocols :
(protocols marked as <default> cannot be specified using 'proto' keyword)
	h2 : mode=HTTP side=FE|BE mux=H2
	fcgi : mode=HTTP side=BE mux=FCGI
	<default> : mode=HTTP side=FE|BE mux=H1
    <default> : mode=TCP side=FE|BE mux=PASS
    
Available services : none

Available filters :
	[SPOE] spoe
	[CACHE] cache
	[FCGI] fcgi-app
	[TRACE] trace
	[COMP] compression

HAProxy启动脚本

[root@localhost ~]# vim /usr/lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target

[Service]
ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p
/var/lib/haproxy/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target
  • 默认缺少配置文件,无法启动
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl start haproxy
Job for haproxy.service failed because the control process exited with error code. See "systemctl status haproxy.service" and "journalctl -xe" for details.


[root@localhost ~]# tail /var/log/messages
Jul 13 10:39:33 localhost systemd: Starting HAProxy Load Balancer...
Jul 13 10:39:33 localhost haproxy: [ALERT] 193/103933 (8156) : Cannot open configuration file/directory /etc/haproxy/haproxy.cfg : No such file or directory
Jul 13 10:39:33 localhost systemd: haproxy.service: control process exited, code=exited status=1
Jul 13 10:39:33 localhost systemd: Failed to start HAProxy Load Balancer.
Jul 13 10:39:33 localhost systemd: Unit haproxy.service entered failed state.
Jul 13 10:39:33 localhost systemd: haproxy.service failed.

配置文件

  • 创建自定义的配置文件
[root@localhost ~]# mkdir /etc/haproxy
[root@localhost ~]# vim /etc/haproxy/haproxy.cfg
global
	maxconn 100000
	chroot /apps/haproxy
	stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
	#uid 99
	#gid 99
	user haproxy
	group haproxy
	daemon
	#nbproc 4
	#cpu-map 1 0
	#cpu-map 2 1
	#cpu-map 3 2
	#cpu-map 4 3
	pidfile /var/lib/haproxy/haproxy.pid
	log 127.0.0.1 local2 info
	
defaults
	option http-keep-alive
	option forwardfor
	maxconn 100000
	mode http
	timeout connect 300000ms
	timeout client 300000ms
	timeout server 300000ms

listen stats
	mode http
	bind 0.0.0.0:9999
	stats enable
	log global
	stats uri /haproxy-status
	stats auth admin:123456

listen web_port
	bind 192.168.175.10:80
	mode http
	log global
	server web1 127.0.0.1:8080 check inter 3000 fall 2 rise 5

启动haproxy

[root@localhost ~]# mkdir /var/lib/haproxy
[root@localhost ~]# useradd -r -s /sbin/nologin -d /var/lib/haproxy haproxy
[root@localhost ~]# systemctl enable --now haproxy

验证haproxy状态

​ haproxy.cfg文件中定义了chroot、pidfile、user、group等参数,如果系统没有相应的资源会导致haproxy无法启动,具体参考日志文件 /var/log/messages

[root@localhost ~]# systemctl status haproxy
[root@localhost ~]# pstree -p |grep haproxy

查看haproxy的状态页面

  • 浏览器访问http://192.168.175.10:9999/haproxy-status
  • 用户名admin,密码123456,这个是在配置文件里定义好的
    在这里插入图片描述
    在这里插入图片描述

三、HAProxy基础配置详解

官方文档:http://cbonte.github.io/haproxy-dconv/2.1/configuration.html

HAProxy 的配置文件haproxy.cfg由两大部分组成,分别是global和proxies部分

  • global:全局配置段

    • 进程及安全配置相关的参数
    • 性能调整相关参数
    • Debug参数
  • proxies:代理配置段

    • defaults:为frontend, backend, listen提供默认配置
    • frontend:前端,相当于nginx中的server {}
    • backend:后端,相当于nginx中的upstream {}
    • listen:同时拥有前端和后端配置

global配置

global 配置参数说明

官方文档:http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#3

chroot #锁定运行目录
deamon #以守护进程运行
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin process 1 #socket文件
user, group, uid, gid #运行haproxy的用户身份
nbproc n #开启的haproxy work 进程数,默认进程数是一个
#nbthread 1 #指定每个haproxy进程开启的线程数,默认为每个进程一个线程,和nbproc互斥(版本有关)
#如果同时启用nbproc和nbthread 会出现以下日志的错误,无法启动服务
Apr 7 14:46:23 haproxy haproxy: [ALERT] 097/144623 (1454) : config : cannot enable multiple processes if multiple threads are configured. Please use either nbproc or nbthread but not both.

cpu-map 1 0 #绑定haproxy 进程至指定CPU,将第一个work进程绑定至0号CPU
maxconn n #每个haproxy进程的最大并发连接数
maxsslconn n #每个haproxy进程ssl最大连接数,用于haproxy配置了证书的场景下
maxconnrate n #每个进程每秒创建的最大连接数量
spread-checks n #后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间,默认值0
pidfile #指定pid文件路径
log 127.0.0.1 local2 info #定义全局的syslog服务器;日志服务器需要开启UDP协议,最多可以定义两个

多进程和线程

范例:多进程和socket文件

[root@localhost ~]# vim /etc/haproxy/haproxy.cfg
global
	maxconn 100000
	chroot /apps/haproxy
	stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin process 1
	stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2
	user haproxy
	group haproxy
	daemon
	nbproc 2

[root@localhost ~]# systemctl restart haproxy
[root@localhost ~]# pstree -p |grep haproxy
	|-haproxy(8395)-+-haproxy(8399)
	| `-haproxy(8400)
[root@localhost ~]# ll /var/lib/haproxy/
总用量 4
-rw-r--r--. 1 root root 5 713 10:56 haproxy.pid
srw-------. 1 root root 0 713 10:56 haproxy.sock1
srw-------. 1 root root 0 713 10:56 haproxy.sock2

日志配置

HAProxy配置

# 在global配置项定义
log 127.0.0.1 local{1-7} #基于syslog记录日志到指定设备,级别有(err、warning、info、debug),在1-7中选择一个等级
#emerg 0 系统不可用 alert 1 必须马上采取行动的事件 crit 2 关键的事件 err 3 错误事件warning 4 警告事件 notice 5 普通但重要的事件 info 6 有用的信息 debug 7 调试信息
listen web_port
	bind 127.0.0.1:80
	mode http
	log global #开启当前web_port的日志功能,默认不记录日志
	server web1 127.0.0.1:8080 check inter 3000 fall 2 rise 5

# systemctl restart haproxy

Rsyslog配置

[root@localhost ~]# vim /etc/rsyslog.conf

$ModLoad imudp
$UDPServerRun 514
......
#local3.* /var/log/boot.log
local7.* /var/log/haroxy.log

......

# systemctl restart rsyslog

验证HAProxy日志

  • 重启syslog服务并访问app页面,然后验证是否生成日志
[root@localhost ~]# tail -f /var/log/haproxy.log
Aug 14 20:21:06 localhost haproxy[18253]: Connect from 192.168.0.1:3050 to 10.0.0.7:80 (web_host/HTTP)
Aug 14 20:21:06 localhost haproxy[18253]: Connect from 192.168.0.1:3051 to 10.0.0.7:80 (web_host/HTTP)
Aug 14 20:21:06 localhost haproxy[18253]: Connect from 192.168.0.1:3050 to 10.0.0.7:80 (web_host/HTTP)

四、Proxies配置

官方文档:http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#4

  • defaults [<name>]
    • 默认配置项,针对以下的frontend、backend和listen生效,可以多个name也可以没有name
  • frontend <name>
    • 前端servername,类似于Nginx的一个虚拟主机 server和LVS服务集群。
  • backend <name>
    • 后端服务器组,等于nginx的upstream和LVS中的RS服务器
  • listen <name>
    • 将frontend和backend合并在一起配置,相对于frontend和backend配置更简洁,生产常用

注意:name字段只能使用大小写字母,数字,‘-’(dash),’_‘(underscore),’.’ (dot)和 ‘:'(colon),并且严格区分大小写

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Proxies配置-defaults

  • defaults 配置参数
option redispatch #当server Id对应的服务器挂掉后,强制定向到其他健康的服务器,重新派发
option abortonclose #当服务器负载很高时,自动结束掉当前队列处理比较久的链接,针对业务情况选择开启
option http-keep-alive #开启与客户端的会话保持
option forwardfor #透传客户端真实IP至后端web服务器
mode http|tcp #设置默认工作类型,使用TCP服务器性能更好,减少压力
timeout http-keep-alive 120s #session 会话保持超时时间,此时间段内会转发到相同的后端服务器
timeout connect 120s #客户端请求从haproxy到后端server最长连接等待时间(TCP连接之前),默认单位ms
timeout server 600s #客户端请求从haproxy到后端服务端的请求处理超时时长(TCP连接之后),默认单位ms,如果超时,会出现502错误,此值建议设置较大些,访止502错误
timeout client 600s #设置haproxy与客户端的最长非活动时间,默认单位ms,建议和timeout server相同
timeout check 5s #对后端服务器的默认检测超时时间
default-server inter 1000 weight 3 #指定后端服务器的默认设置

Proxies配置-frontend

  • frontend 配置参数
bind: #指定HAProxy的监听地址,可以是IPV4或IPV6,可以同时监听多个IP或端口,可同时用于listen字段中

#格式:
bind [<address>]:<port_range> [, ...] [param*]

#注意:如果需要绑定在非本机的IP,需要开启内核参数:net.ipv4.ip_nonlocal_bind=1
  • 范例
listen http_proxy #监听http的多个IP的多个端口和sock文件
	bind :80,:443,:8801-8810
	bind 10.0.0.1:10080,10.0.0.1:10443
	bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy

listen http_https_proxy #https监听
	bind :80
	bind :443 ssl crt /etc/haproxy/site.pem #公钥和私钥公共文件

listen http_https_proxy_explicit #监听ipv6、ipv4和unix sock文件
	bind ipv6@:80
	bind ipv4@public_ssl:443 ssl crt /etc/haproxy/site.pem
	bind unix@ssl-frontend.sock user root mode 600 accept-proxy

listen external_bind_app1 #监听file descriptor
	bind "fd@${FD_APP1}"
  • 生产示例
frontend web_port #可以采用后面形式命名:业务-服务-端口号
	bind :80,:8080
	bind 10.0.0.7:10080,:8801-8810,10.0.0.17:9001-9010
	mode http|tcp #指定负载协议类型
	use_backend <backend_name> #调用的后端服务器组名称

Proxies配置-backend

  • 定义一组后端服务器,backend服务器将被frontend进行调用。
mode 	http|tcp 	#指定负载协议类型,和对应的frontend必须一致
option 		#配置选项
server 		#定义后端real server

注意:option后面加 httpchk,smtpchk,mysql-check,pgsql-check,ssl-hello-chk方法,可用于实现更多应用层检测功能。

option 配置

check #对指定real进行健康状态检查,如果不加此设置,默认不开启检查
	addr <IP> #可指定的健康状态监测IP,可以是专门的数据网段,减少业务网络的流量
	port <num> #指定的健康状态监测端口
	inter <num> #健康状态检查间隔时间,默认2000 ms
	fall <num> #后端服务器从线上转为线下的检查的连续失效次数,默认为3
	rise <num> #后端服务器从下线恢复上线的检查的连续有效次数,默认为2
weight <weight> #默认为1,最大值为256,0表示不参与负载均衡,但仍接受持久连接
backup #将后端服务器标记为备份状态,只在所有非备份主机down机时提供服务,类似Sorry Server
disabled #将后端服务器标记为不可用状态,即维护状态,除了持久模式,将不再接受连接
redirect prefix http://www.baidu.com/ #将请求临时(302)重定向至其它URL,只适用于http模式
redir http://www.baidu.com #将请求临时(302)重定向至其它URL,只适用于http模式
maxconn <maxconn> #当前后端server的最大并发连接数
backlog <backlog> #当前端服务器的连接数达到上限后的后援队列长度,注意:不支持backend

frontend+backend配置实例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • node1和node2搭建一个网站
[root@node1 ~]# yum -y install httpd
[root@node1 ~]# echo "node1 ..." > /var/www/html/index.html
[root@node1 ~]# systemctl start httpd
[root@node1 ~]# systemctl enable httpd
  • haproxy配置文件
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
global
	maxconn 100000
	chroot /apps/haproxy
	stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
	#uid 99
	#gid 99
	user haproxy
	group haproxy
	daemon
	#nbproc 4
	#cpu-map 1 0
	#cpu-map 2 1
	#cpu-map 3 2
	#cpu-map 4 3
	pidfile /var/lib/haproxy/haproxy.pid
	log 127.0.0.1 local2 info

defaults
	option http-keep-alive
	option forwardfor
	maxconn 100000
	mode http
	timeout connect 300000ms
	timeout client 300000ms
	timeout server 300000ms

listen stats
	mode http
	bind 0.0.0.0:9999
	stats enable
	log global
	stats uri /haproxy-status
	stats auth admin:123456

frontend test-http
	bind :80
	mode tcp
	use_backend test-http-nodes

backend test-http-nodes
	mode tcp
	default-server inter 1000 weight 6
	server web1 192.168.175.20:80 check inter 3000 fall 3 rise 5 weight 2 addr 192.168.175.20 port 3306
	server web2 192.168.175.30:80 check inter 3000 fall 3 rise 5

[root@haproxy ~]# systemctl restart haproxy
  • 验证结果
    在这里插入图片描述

  • 因为检查node1的3306接口并没有启动,所以node1始终是down的
    在这里插入图片描述

  • 装个数据库。试一下开启3306之后会不会正常

[root@haproxy ~]# yum install -y mariadb-server
[root@haproxy ~]# systemctl start mariadb
[root@haproxy ~]# mysqladmin password '123456'
打开之后看健康检测就正常了,可以正常进行负载均衡

listen替代frontend+backend

使用listen替换上面的frontend和backend的配置方式,可以简化设置,通常只用于TCP协议的应用

listen WEB_PORT_80
	bind :80
	mode http
	option forwardfor
	server web1 192.168.175.20:80 check inter 3000 fall 3 rise 5
	server web2 192.168.175.30:80 check inter 3000 fall 3 rise 5

[root@haproxy ~]# systemctl restart haproxy

使用子配置文件保存配置

​ 当业务众多时,将所有配置都放在一个配置文件中,会造成维护困难。可以考虑按业务分类,将配置信息拆分,放在不同的子配置文件中,从而达到方便维护的目的。

  • 创建子配置目录
[root@haproxy ~]# mkdir /etc/haproxy/conf.d/
  • 创建子配置文件,注意:必须为cfg后缀
[root@haproxy ~]# vim /etc/haproxy/conf.d/test.cfg
listen WEB_PORT_80
	bind :80
	mode http
	option forwardfor
	balance roundrobin
	server web1 192.168.175.20:80 check inter 3000 fall 3 rise 5
	server web2 192.168.175.30:80 check inter 3000 fall 3 rise 5
  • 添加子配置目录到unit文件中
[root@haproxy ~]# vim /lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target

[Service]
ExecStartPre=/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -c -q
ExecStart=/usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -p /var/lib/haproxy/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID

[Install]
WantedBy=multi-user.target

删掉主配置文件里的listen web_port否则会冲突
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
[root@haproxy ~]# systemctl daemon-reload
[root@haproxy ~]# systemctl restart haproxy

五、HAProxy调度算法

HAProxy通过固定参数 balance 指明对后端服务器的调度算法,该参数可以配置在listen或backend选项中。

HAProxy的调度算法分为静态和动态调度算法,但是有些算法可以根据参数在静态和动态算法中相互转换。

官方文档:http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#4-balance

静态算法

静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、链接数和响应速度等,且无法实时修改权重,只能靠重启HAProxy生效。

static-rr

static-rr:基于权重的轮询调度,不支持权重的运行时利用socat进行动态调整及后端服务器慢启动,其后端主机数量没有限制,相当于LVS中的 wrr

listen web_host
	bind :80
	mode http
	log global
	balance static-rr
	server web1 192.168.175.20:80 weight 1 check inter 3000 fall 2 rise 5
	server web2 192.168.175.30:80 weight 2 check inter 3000 fall 2 rise 5

测试访问效果,同时运行下面命令,观察结果

while true;do curl http://192.168.175.10/index.html ; sleep 0.1;done

first

first:根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置,此方式使用较少

listen web_host
	bind :80
	mode http
	log global
	balance first
	server web1 192.168.175.20:80 maxconn 2 weight 1 check inter 3000 fall 2 rise 5
	server web2 192.168.175.30:80 weight 1 check inter 3000 fall 2 rise 5

动态算法

​ 动态算法:基于后端服务器状态进行调度适当调整,优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整无需重启。

roundrobin

roundrobin:基于权重的轮询动态调度算法,支持权重的运行时调整,不同于lvs中的rr轮询模式,HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),其每个后端backend中最多支持4095个real server,支持对real server权重动态调整,roundrobin为默认调度算法

listen web_host
	bind :80
	mode http
	log global
	balance roundrobin
	server web1 192.168.175.20:80 weight 1 check inter 3000 fall 2 rise 5
	server web2 192.168.175.30:80 weight 2 check inter 3000 fall 2 rise 5

支持动态调整权重

# 对服务器动态权重和其它状态可以利用 socat工具进行调整,Socat 是 Linux 下的一个强大的多功能的网络工具,Socat 的主要特点就是在两个数据流之间建立双向通道,且支持众多协议和链接方式,如IP,TCP,UDP,IPv6,pipe,exec,system,open,proxy,openssl,socket等。
# 使用Socat工具修改时 这行配置文件stats socket /var/lib/haproxy/stats mode 600 level admin 这里要指定为admin,否则可能socat会有权限错误
# echo "get weight WEB_PORT_80/web1" | socat stdio /var/lib/haproxy/haproxy.sock #weight WEB_PORT_80/web1这里是和配置文件对应的
1 (initial 1)
# echo "set weight web_host/web1 3" | socat stdio /var/lib/haproxy/haproxy.sock

# echo "get weight web_host/web1" | socat stdio /var/lib/haproxy/haproxy.sock
3 (initial 1)

leastconn

leastconn加权的最少连接的动态,支持权重的运行时调整和慢启动,即当前后端服务器连接最少的优先调度(新客户端连接),比较适合长连接的场景使用,比如:MySQL等场景。

listen web_host
	bind :80
	mode http
	log global
	balance leastconn
	server web1 192.168.175.20:80 weight 1 check inter 3000 fall 2 rise 5
	server web2 192.168.175.30:80 weight 1 check inter 3000 fall 2 rise 5

random

​ 在1.9版本开始增加一个叫做random的负载平衡算法,其基于随机数作为一致性hash的key,随机负载平衡对于大型服务器场或经常添加或删除服务器非常有用,支持weight的动态调整,weight较大的主机有更大概率获取新请求

listen web_host
	bind :80
	mode http
	log global
	balance random
	server web1 192.168.175.20:80 weight 1 check inter 3000 fall 2 rise 5
	server web2 192.168.175.30:80 weight 1 check inter 3000 fall 2 rise 5

其他算法

其它算法即可作为静态算法,又可以通过选项成为动态算法

source

源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type支持的选项更改

这个算法一般是在不插入Cookie的TCP模式下使用,也可给拒绝会话cookie的客户提供最好的会话粘性,适用于session会话保持但不支持cookie和缓存的场景

源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash

map-base取模法

map-based:取模法,对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 指定的默认值为此算法

所谓取模运算,就是计算两个数相除之后的余数,10%7=3, 7%4=3 map-based算法:基于权重取模,hash(source_ip)%所有后端服务器相加的总权重

listen web_host
	bind :80
	mode tcp
	log global
	balance source
	hash-type map-based
	server web1 192.168.175.20:80 weight 1 check inter 3000 fall 2 rise 3
	server web2 192.168.175.30:80 weight 1 check inter 3000 fall 2 rise 3
	
[root@haproxy ~]#echo "set weight web_host/192.168.175.20 10" | 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 web_host/192.168.175.20 0" | socat stdio /var/lib/haproxy/haproxy.sock

[root@haproxy conf.d]#echo "get weight web_host/192.168.175.20" | socat stdio /var/lib/haproxy/haproxy.sock
0 (initial 1)

一致性hash

一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动,hash(o)mod n ,该hash算法是动态的,支持使用 socat等工具进行在线权重调整,支持慢启动

1、key1=hash(source_ip)%(2^32) [0—4294967295]

2、keyA=hash(后端服务器虚拟ip)%(2^32)

3、将key1和keyA都放在hash环上,将用户请求调度到离key1最近的keyA对应的后端服务器

listen web_host
	bind :80
	mode tcp
	log global
	balance source
	hash-type consistent
	server web1 192.168.175.20:80 weight 1 check inter 3000 fall 2 rise 5
	server web2 192.168.175.30:80 weight 1 check inter 3000 fall 2 rise 5

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>
  • uri 取模法配置示例
listen web_host
	bind :80
	mode http
	log global
	balance uri
	server web1 192.168.175.20:80 weight 1 check inter 3000 fall 2 rise 5
	server web2 192.168.175.30:80 weight 1 check inter 3000 fall 2 rise 5
  • uri 一致性hash配置示例
listen web_host
	bind :80
	mode http
	log global
	balance uri
	hash-type consistent
	server web1 192.168.175.20:80 weight 1 check inter 3000 fall 2 rise 5
	server web2 192.168.175.30:80 weight 1 check inter 3000 fall 2 rise 5

url_param

url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server,如果无没key,将按roundrobin算法

假设:
url = http://www.test.com/foo/bar/index.php?key=value

则:
host = "www.test.com"
url_param = "key=value"
  • url_param取模法配置示例
listen web_host
	bind :80
	mode http
	log global
	balance url_param userid #url_param hash
	server web1 192.168.175.20:80 weight 1 check inter 3000 fall 2 rise 5
	server web2 192.168.175.30:80 weight 1 check inter 3000 fall 2 rise 5
  • url_param一致性hash配置示例
listen web_host
	bind :80
	mode http
	log global
	balance url_param userid #对url_param的值取hash
	hash-type consistent
	server web1 192.168.175.20:80 weight 1 check inter 3000 fall 2 rise 5
	server web2 192.168.175.30:80 weight 1 check inter 3000 fall 2 rise 5

hdr

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

  • hdr取模法配置示例
listen web_host
	bind :80
	mode http
	log global
	balance hdr(User-Agent)
	#balance hdr(host)
	server web1 192.168.175.20:80 weight 1 check inter 3000 fall 2 rise 5
	server web2 192.168.175.30:80 weight 1 check inter 3000 fall 2 rise 5
  • 一致性hash配置示例
listen web_host
	bind :80
	mode http
	log global
	balance hdr(User-Agent)
	hash-type consistent
	server web1 192.168.175.20:80 weight 1 check inter 3000 fall 2 rise 5
	server web2 192.168.175.30:80 weight 1 check inter 3000 fall 2 rise 5

rdp-cookie

rdp-cookie对远windows远程桌面的负载,使用cookie保持会话,默认是静态,也可以通过hashtype指定map-based和consistent,来定义使用取模法还是一致性hash。

  • rdp-cookie取模法配置示例
listen RDP
	bind :3389
	balance rdp-cookie
	mode tcp
	server rdp0 192.168.175.20:3389 check fall 3 rise 5 inter 2000 weight 1
  • rdp-cookie一致性hash配置示例
[root@haproxy ~]#cat /etc/haproxy/conf.d/windows_rdp.cfg
listen magedu_RDP_3389
	bind 172.16.0.100:3389
	balance rdp-cookie
	hash-type consistent
	mode tcp
	server rdp0 10.0.0.200:3389 check fall 3 rise 5 inter 2000 weight 1

[root@haproxy ~]#hostname -I
10.0.0.100 172.16.0.100

算法总结

static-rr--------->tcp/http 静态
first------------->tcp/http 静态

roundrobin-------->tcp/http 动态
leastconn--------->tcp/http 动态
random------------>tcp/http 动态

以下静态和动态取决于hash_type是否consistent
source------------>tcp/http
Uri--------------->http
url_param--------->http
hdr--------------->http
rdp-cookie-------->tcp

各算法使用场景

first #使用较少

static-rr #做了session共享的web集群
roundrobin
random

leastconn #数据库
source #基于客户端公网IP的会话保持

uri--------------->http #缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯
url_param--------->http

hdr #基于客户端请求报文头部做下一步处理

rdp-cookie #很少使用

六、HAProxy状态页

通过web界面,显示当前HAProxy的运行状态

官方帮助:http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#4-stats%20admin

  • 状态页配置项
stats enable #基于默认的参数启用stats page
stats hide-version #将状态页中haproxy版本隐藏
stats refresh <delay> #设定自动刷新时间间隔,默认不自动刷新
stats uri <prefix> #自定义stats page uri,默认值:/haproxy?stats
stats realm <realm> #账户认证时的提示信息,示例:stats realm HAProxy\Statistics
stats auth <user>:<passwd> #认证时的账号和密码,可使用多次,默认:no authentication,可有多行用户
stats admin { if | unless } <cond> #启用stats page中的管理功能
  • 启用状态页
listen stats
	bind :9999
	stats enable
	#stats hide-version
	stats uri /haproxy-status
	stats realm HAPorxy\ Stats\ Page
	stats auth haadmin:123456 #两个用户
	stats auth admin:123456
	#stats refresh 30s
	stats admin if TRUE #安全原因,不建议打开
  • 状态页信息
pid = 27134 (process #1, nbproc = 1, nbthread = 1) #pid为当前pid号,process为当前进程号,nbproc和nbthread为一共多少进程和每个进程多少个线程
uptime = 0d 0h00m04s #启动了多长时间
system limits: memmax = unlimited; ulimit-n = 200029 #系统资源限制:内存/最大打开文件数/
maxsock = 200029; maxconn = 100000; maxpipes = 0 #最大socket连接数/单进程最大连接数/最大管道数maxpipes
current conns = 2; current pipes = 0/0; conn rate = 2/sec; bit rate = 0.000kbps #当前连接数/当前管道数/当前连接速率
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 or backup DOWN for maintenance (MAINT) #active或者backup服务器人为下线的
active or backup SOFT STOPPED for maintenance #active或者backup被人为软下线(人为将weight改成0)

在这里插入图片描述

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:拒绝回复量

七、利用状态页实现haproxy服务器的健康性检查

  • 通过curl 命令对haproxy的状态页的访问实现健康检查
[root@haproxy ~]# curl -I http://admin:123456@192.168.175.10:9999/haproxy-status
HTTP/1.1 200 OK
cache-control: no-cache
content-type: text/html

[root@haproxy ~]# curl -I -u admin:123456 http://192.168.175.10:9999/haproxystatus
HTTP/1.1 200 OK
cache-control: no-cache
content-type: text/html

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基金是什么

一、基金是什么&#xff1f; 买基金就是委托别人帮我们投资&#xff0c;替我们买卖股票债券。 二、为什么委托别人&#xff1f; 因为我们不懂投资方面的知识&#xff0c;或者我们没有时间来做投资&#xff0c;那么就可以找专业人士帮我们投资。就像家长帮小孩报辅导班&#…

蓝桥杯(Web大学组)2022国赛真题:水果消消乐

思路&#xff1a; 记录点击次数&#xff0c;点击次数为1时&#xff0c;记录点击下标&#xff08;用于隐藏or消除&#xff09;、点击种类&#xff0c;点击次数为2时&#xff0c;判断该下标所对应种类与第一次是否相同 相同&#xff1a;两个都visibility:hidden &#xff08;占…

PV、UV、IP

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1. PV1.1 PV 计算1.2 PV 的影响因素 2. UV2.1 UV 计算2.2UV 的影响因素 3. IP3.1 IP和UV①UV大于IP②UV小于IP 三者的关系PV 和 UV 前言 PV、UV、IP是我们在运…

网络学习:数据链路层VLAN原理和配置

一、简介&#xff1a; VLAN又称为虚拟局域网&#xff0c;它是用来将使用路由器的网络分割成多个虚拟局域网&#xff0c;起到隔离广播域的作用&#xff0c;一个VLAN通常对应一个IP网段&#xff0c;不同VLAN通常规划到不同IP网段。划分VLAN可以提高网络的通讯质量和安全性。 二、…

专业140+总分420+华中科技大学824信号与系统考研经验电子信息与通信工程,真题,大纲,参考书。

今年考研分数自己感觉还是比较满意&#xff0c;专业824信号与系统考的最好140&#xff0c;总分420&#xff0c;如愿上岸华科&#xff0c;回顾自己的这一年的复习&#xff0c;总结一些自己的经验&#xff0c;希望对报考华科的同学有帮助。 专业课&#xff1a; 824信号与系统在…

【高阶数据结构】位图布隆过滤器

文章目录 1. 位图1.1什么是位图1.2为什么会有位图1.3 实现位图1.4 位图的应用 2. 布隆过滤器2.1 什么是布隆过滤器2.2 为什么会有布隆过滤器2.3 布隆过滤器的插入2.4 布隆过滤器的查找2.5 布隆过滤器的模拟实现2.6 布隆过滤器的优点2.7 布隆过滤器缺陷 3. 海量数据面试题3.1 哈…

【C++11】右值引用 | 移动构造赋值 | 万能引用 | 完美转发

文章目录 一、引言二、左值和右值什么是左值什么是右值 三、左值引用和右值引用左值引用右值引用左值引用与右值引用的比较 四、右值引用的使用场景和意义左值引用的使用场景左值引用的短板用右值引用和移动语义解决上述问题移动构造移动赋值 右值引用引用左值 - std::move()ST…

spring boot学习第十二篇:mybatis框架中调用存储过程控制事务性

1、MySQL方面&#xff0c;已经准备好了存储过程&#xff0c;参考&#xff1a;MYSQL存储过程&#xff08;含入参、出参&#xff09;-CSDN博客 2、pom.xml文件内容如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"…

3.4-媒资管理之视频处理+xx-job分布式任务

文章目录 媒资管理6 视频处理6.1 需求6.1.1 总体需求6.7.3 FFmpeg 的基本使用6.7.4 视频处理工具类 6.2 分布式任务处理6.2.1 什么是分布式任务调度6.2.2 XXL-JOB介绍6.2.3 搭建XXL-JOB6.2.3.1 调度中心6.2.3.2 执行器6.2.3.3 执行任务 6.2.4 分片广播 6.3 技术方案6.3.1 作业分…

Optimism为 CQT提供价值 20 万美元的生态系统资助,以表彰其支持

Covalent Network&#xff08;CQT&#xff09; 是 Web3 生态系统中关键的“数据可用性”层&#xff0c;在与 Optimism Collective 多年的合作中取得了骄人的成果。Covalent Network&#xff08;CQT&#xff09;对于 Optimism 跨链数据的增长产生了直接的影响&#xff0c;而这一…

Java并发基础:Deque接口和Queue接口的区别?

核心概念 Deque&#xff08;double ended queue&#xff0c;双端队列&#xff09;和Queue&#xff08;队列&#xff09;都是Java集合框架中的接口&#xff0c;它们用于处理元素的排队和出队&#xff0c;但是它们之间存在一些重要的区别&#xff0c;如下&#xff1a; 1、Queue…

C语言——oj刷题——调整数组使奇数全部都位于偶数前面

题目&#xff1a; 输入一个整数数组&#xff0c;实现一个函数&#xff0c;来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分&#xff0c;所有偶数位于数组的后半部分。 一、实现方法&#xff1a; 当我们需要对一个整数数组进行调整&#xff0c;使得奇数位于数…

Git详细讲解

文章目录 一、Git相关概念二、本地分支中文件的添加 、提交2.1 文件状态2.2 创建Git仓库2.2.1 git init2.2.2 git clone 2.3 添加操作(git add)2.4 提交操作&#xff08;git commit&#xff09;2.5 撤销操作2.5.1 撤销 add操作2.5.2 撤销 commit操作2.5.3 覆盖上一次的commit操…

机器学习系列——(十八)K-means聚类

引言 在众多机器学习技术中&#xff0c;K-means聚类以其简洁高效著称&#xff0c;成为了数据分析师和算法工程师手中的利器。无论是在市场细分、社交网络分析&#xff0c;还是图像处理等领域&#xff0c;K-means都扮演着至关重要的角色。本文旨在深入解析K-means聚类的原理、实…

EF Core 模型优先——根据类对象创建数据表

需要的nuget包&#xff1a; Microsoft.EntityframeworkCore.SqlServer &#xff08;根据自己的数据库类型选择对应的nuget包&#xff09; Microsoft.EntityframeworkCore.Tools Microsoft.VisualStudio.Web.CodeGeneration.Design 说明&#xff1a; &#xff08;1&#xf…

排序算法---插入排序

原创不易&#xff0c;转载请注明出处。欢迎点赞收藏~ 插入排序是一种简单直观的排序算法&#xff0c;它的基本思想是将待排序的元素分为已排序和未排序两部分&#xff0c;每次从未排序部分中选择一个元素插入到已排序部分的合适位置&#xff0c;直到所有元素都插入到已排序部分…

考研数据结构笔记(3)

顺序表存储结构 存储结构顺序结构定义基本操作的实现静态分配问题 动态分配代码功能 顺序表的特点: 顺序表小结顺序表的插入删除插入删除小结 顺序表的查找按位查找按值查找小结 存储结构 顺序结构 定义 线性表是具有相同数据类型的n(n>0)个数据元素的有限序列(每个数据元素…

大数据 - Spark系列《五》- Spark常用算子

Spark系列文章&#xff1a; 大数据 - Spark系列《一》- 从Hadoop到Spark&#xff1a;大数据计算引擎的演进-CSDN博客 大数据 - Spark系列《二》- 关于Spark在Idea中的一些常用配置-CSDN博客 大数据 - Spark系列《三》- 加载各种数据源创建RDD-CSDN博客 大数据 - Spark系列《…

vue3 之 组合式API—模版引用

模版引用的概念 通过ref标识获取真实的dom对象或者组件实例对象 如何使用&#xff08;以获取dom为例 组件同理&#xff09; 1️⃣调用ref函数生成一个ref对象 2️⃣通过ref标识绑定ref对象到标签 dom中使用 父组件中可以看到打印出来proxy里面只有一个属性&#xff0c;其他…

Vue中 常用的修饰符有哪些

Vue是一款建立在JavaScript框架上的开源前端库&#xff0c;已经成为当今前端开发人员最喜爱的选择之一。它的简洁语法和强大的功能使得开发者可以轻松地构建交互性的网页应用程序。在Vue中&#xff0c;修饰符是一个重要的概念&#xff0c;它们可以帮助我们更好地控制和定制DOM元…