haproxy基础

devtools/2024/9/20 1:23:52/ 标签: linux, 运维, 服务器

目录

1 HAProxy介绍

1.1 版本对比

1.2 HAProxy功能

2 参数介绍与实践

2.1 global参数说明

2.2 真实代码格式实例

2.3 常用全局参数

2.3.1 nbproc -- 开启几个进程

2.3.2 cpu-map(CUP绑定)

2.3.3 nbthread 2   --开启2个线程

3 Proxies配置

3.1 Proxies配置-defaults

3.2 Proxies配置-frontend(和backend组合使用)

3.3 Proxies配置-backend(与frontend混合使用)

3.4 frontend+backend配置实例

3.5 Proxies配置-listen替代 frontend+backend

3.6 使用子配置文件保存配置

4 Socat 工具

4.1 下载工具

4.2 Socat 工具的使用

4.2.1 查看帮助

4.2.2 套接字文件添加管理员权限

4.2.3 常用实例

4.2.4 套接字文件配合CPU核心分批次管理


1 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,会话保持……

企业版网站:[HAProxy Technologies | World's Fastest Load Balancer]

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

1.1 版本对比

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

1.2 HAProxy功能

2 参数介绍与实践

2.1 global参数说明

参数类型作用
chroot全局锁定运行目录
deamon全局以守护进程运行
user, group, uid, gid全局运行haproxy的用户身份
stats socket全局套接字文件
nbproc N (和nbproc互斥)全局开启的haproxy worker 进程数,默认进程数是一个
nbthread 1全局指定每个haproxy进程开启的线程数,默认认为每个进程一个线程
cpu-map 0 1全局绑定haproxy worker 进程至指定CPU,将第1个work进程绑定至0号CPU
cpu-map 1 1全局绑定haproxy worker 进程至指定CPU,将第2个work进程绑定至1号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协议,最多可以定义两个

2.2 真实代码格式实例

global# 将工作目录锁定在/var/haproxychroot /var/haproxy# 以守护进程运行daemon# 以haproxy用户和组的身份运行user haproxygroup haproxy# 打开了一个套接字文件,允许管理员通过socket与Haproxy交互stats socket /run/haproxy/admin.sock mode 660 level admin# 开启了两个worker进程nbproc 2# 让每个Haproxy进程开启两个线程nbthread 2# 将第一个worker进程绑定了到0号CPU,第二个worker进程绑定了到1号CPUcpu-map 0 0cpu-map 1 1# 设置每个Haproxy进程的最大并发连接数为4000maxconn 4000# 设置每个Haproxy进程SSL最大连接数为4000maxsslconn 4000# 设置每个进程每秒创建的最大连接数量为1000maxconnrate 1000# 设置后端server状态check随机提前或延迟百分比时间为2%spread-checks 2# 指定了pid文件路径pidfile /var/run/haproxy.pid# 定义全局的syslog服务器,日志服务器需要开启UDP协议,最多可以定义两个log 127.0.0.1 local2 info

2.3 常用全局参数

2.3.1 nbproc -- 开启几个进程

查看此时haproxy的进程数

[root@haproxy ~]# pstree -p | grep haproxy|-haproxy(2307)---haproxy(2309)---{haproxy}(2310)

打开配置文件,增加以下行

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg 

重启服务再次查看进程,由原先的一个进程变成了两个

[root@haproxy ~]# systemctl restart haproxy.service 
[root@haproxy ~]# pstree -p | grep haproxy|-haproxy(2375)-+-haproxy(2377)|               `-haproxy(2378)

但这样子设置会照成一个不好的效果,会使得CPU抖动

CPU抖动:

CPU抖动是指CPU在短时间内频繁地在不同任务间切换,导致性能下降的现象。这种现象通常发生在多核处理器上,因为操作系统会在不同的核心上调度不同的任务,如果任务之间的切换过于频繁,就会出现CPU抖动。

2.3.2 cpu-map(CUP绑定)

所以为了解决这一问题,就得使用到一个新的参数cpu-map(CUP绑定)

2.3.3 nbthread 2   --开启2个线程

注意:多进程与多线程不能同时开多个,不然会报错

查看系统日志文件,说明如果使用多个线程就不能使用多个进程

注释

重启服务

[root@haproxy ~]# systemctl restart haproxy.service 
[root@haproxy ~]# pstree -p | grep haproxy|-haproxy(3388)---haproxy(3390)---{haproxy}(3391)[root@haproxy ~]# cat /proc/3390/status | grep -i thread
Threads:        2
Speculation_Store_Bypass:       thread vulnerable

3 Proxies配置

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

3.1 Proxies配置-defaults

参数功能
option abortonclose服务器负载很高时,自动结束掉当前队列处理比较久的连接,针对业务情况选择开启
option redispatch当server Id对应的服务器挂掉后,强制定向到其他健康的服务器,重新派发
option http-keep-alive开启与客户端的会话保持
option forwardfor透传客户端真实IP至后端web服务器(在apache配置文件中加入:%{X-Forwarded-For}i后在webserer中看日志即可看到地址透传信息)
mode http|tcp设置默认工作类型,使用TCP服务器性能更好,减少压力
timeout http-keep-alive 120ssession 会话保持超长时间,此时间段内会转发出相同的后端服务器
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指定后端服务器的默认设置

3.2 Proxies配置-frontend(和backend组合使用)

frontend 配置参数:

bind:   #指定HAProxy的监听地址,可以是IPV4或IPV6,可以同时监听多个IP或端口,可同时用于listen字段中#格式:
bind [<address>]:<port_range> [, ...] [param*]#注意:如果需要绑定在非本机的IP,需要开启内核参数:net.ipv4.ip_nonlocal_bind=1

生产示例:

frontend  webcluster               #可以采用后面形式命名:业务-服务-端口号bind :80,:8080bind 10.0.0.7:10080,:8801-8810,10.0.0.17:9001-9010mode  http|tcp              #指定负载协议类型use_backend <backend_name>  #调用的后端服务器组名称

3.3 Proxies配置-backend(与frontend混合使用)

定义一组后端服务器,backend服务器将被frontend进行调用。

mode  http|tcp      #指定负载协议类型,和对应的frontend必须一致
option              #配置选项
server              #定义后端real server

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

server  配置

check               #对指定real进行健康状态检查,如果不加此设置,默认不开启检查addr  <IP>        #可指定的健康状态监测IP,可以是专门的数据网段,减少业务网络的流量port  <num>   #指定的健康状态监测端口inter <num>   #健康状态检查间隔时间,默认2000 msfall  <num>       #后端服务器从线上转为线下的检查的连续失效次数,默认为3rise  <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

3.4 frontend+backend配置实例

frontend webclusterbind *:80mode httpuse_backend webcluster-hostbackend webcluster-host# 使用 roundrobin 动态算法balance roundrobinserver web1 192.168.239.10:80 check inter 3000 fall 3 rise 5server web2 192.168.239.20:80 check inter 3000 fall 3 rise 5# check 关键字表示启用健康检查。
# inter 3000 表示健康检查的间隔时间为 3 秒钟。
# fall 3 表示连续失败 3 次之后,HAProxy 认为这个服务器不可用。
# rise 5 表示连续成功 5 次之后,HAProxy 认为这个服务器可用

3.5 Proxies配置-listen替代frontend+backend

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

#官网业务访问入口
listen webclusterbind *:80mode httpbalance roundrobin# inter 健康检查的时间 每隔2毫秒进行一次健康检查# fall 如果连续三次健康检查都失败,那么HAProxy会认为该服务器不可用.# rise 如果连续五次健康检查都成功,那么HAProxy会认为该服务器可用。server web1 192.168.239.10:80 check inter 2 fall 3 rise 5  weight 1server web2 192.168.239.20:80 check inter 2 fall 3 rise 5  weight 1

3.6 使用子配置文件保存配置

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

#创建子配置文件,注意:必须为cfg后缀
[root@node1 ~]# vim   /etc/haproxy/conf.d/test.cfg
listen  WEB_PORT_80bind *:80mode httpbalance roundrobinserver web1  192.168.239.14:80   check inter 3000 fall 3 rise 5server web2  192.168.239.15:80   check inter 3000 fall 3 rise 5

在使用yum安装的版本中服务脚本中是默认加载子配置文件的,不需要在主配置文件里增加配置

4 Socat 工具

Socat 是 Linux 下的一个多功能的网络工具,名字来由是Socket CAT,Socat 的主要特点就是在两个数据流之间建立通道,且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、Socket文件等

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

4.1 下载工具

[root@haproxy ~]# yum -y install socat

4.2 Socat 工具的使用

4.2.1 查看帮助

# 查看帮助[root@haproxy ~]# socat -h
# stdio 是 socat 的一个选项,它表示标准输入/输出。在这个命令中,stdio 用来接收来自 echo 的输入,并将其传递给 /var/lib/haproxy/stats
[root@haproxy ~]# echo help | socat stdio /var/lib/haproxy/stats

4.2.2 套接字文件添加管理员权限

打开haproxy的配置文件

4.2.3 常用实例

[root@haproxy ~]# echo show servers state | socat - /var/lib/haproxy/stats
1
# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port
2 webcluster 1 web1 192.168.239.10 2 0 1 1 171 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
2 webcluster 2 web2 192.168.239.20 2 0 1 1 172 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
2 webcluster 3 web3_sorry 192.168.239.100 2 0 1 1 15732 1 0 2 0 0 0 0 - 8080 - 0 0 - - 0[root@haproxy ~]# echo get weight webcluster/web1 | socat - /var/lib/haproxy/stats
1 (initial 1)# 修改weight,注意只针对单进程有效
[root@haproxy ~]# echo set weight webcluster/web1 2 | socat stdio /var/lib/haproxy/stats[root@haproxy ~]# echo get weight webcluster/web1 | socat - /var/lib/haproxy/stats
2 (initial 1)# 将后端服务器禁用,注意只针对单进程有效
[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# 将后端服务器软下线,即weight设为0
[root@haproxy ~]# echo set weight webcluster/web1 0 | socat - /var/lib/haproxy/stats
[root@client ~]# while true;do curl 192.168.239.100; sleep 0.1; done
this is web2
this is web2
this is web2
this is web2
this is web2# 如果静态算法,如:static-rr,可以更改weight为0或1,但不支持动态更改weight为其它值,否则会提示下面信息
[root@haproxy ~]# echo set weight webcluster/web1 0 | socat - /var/lib/haproxy/stats
[root@haproxy ~]# echo set weight webcluster/web1 1 | socat - /var/lib/haproxy/stats
[root@haproxy ~]# echo set weight webcluster/web1 2 | socat - /var/lib/haproxy/stats
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.

4.2.4 套接字文件配合CPU核心分批次管理

设置第一个套接字文件由第一个进程管,第二个进程管第二个套接字

# nbproc 2:这行配置指定了 HAProxy 进程的数量,这里是 2 个进程。
#
# cpu-map 1 0 cpu-map 2 1:这两行配置指定了每个进程应该绑定到哪个 CPU 核心上。1 0 表示第一个进程
# 绑定到第 0 个核心,2 1 表示第二个进程绑定到第 1 个核心>。这意味着 HAProxy 将创建两个进程,其中一
# 个进程将被绑定到 CPU 的第一个核心,另一个进程将被绑定到 CPU 的第二个核心。这样做的目的是为了更好地
# 利用多核处>理器,提高性能。
#
# stats socket /var/lib/haproxy/stats1 mode 600 level admin process 1:
# 这行配置打开了一个名为 /var/lib/haproxy/stats1 的套接字文件,用于收集 HAProxy 的统计信息。
# mode 600 表示权限为 600,level admin 表示管理员级别,process 1 表示仅限于第一个进程。这意味着
# 只有拥有足够权限的用户才能访问这个套接字,而且>只能访问第一个进程的信息。
#
# stats socket /var/lib/haproxy/stats2 mode 600 level admin process 2:这行配置同上,但仅限于
# 第二个进程。这意味着只有拥有足够权限的用户才能访问这个套接字,而且只能访问第二个进程的信息。
#
# 总的来说,这段代码的作用是启动两个 HAProxy 进程并将它们绑定到不同的 CPU 核心,同时开放了两个套接
# 字供管理员获取这两个进程的统计信息。这样做的好处是可>以更有效地监控和管理 HAProxy,在多核环境中充
# 分利用硬件资源# 这样每个进程就会有单独的sock文件来进行单独管理[root@haproxy ~]# ll /var/lib/haproxy/
总用量 0
srw-------. 1 root root 0  8月 10 00:24 stats
srw-------. 1 root root 0  8月 10 00:33 stats1
srw-------. 1 root root 0  8月 10 00:33 stats2

http://www.ppmy.cn/devtools/92212.html

相关文章

C语言项目——贪吃蛇,为什么用curses,定义上下左右

在Linux系统中&#xff0c;使用ncurses在程序编译时还要加上 -lcurses 即&#xff1a;gcc cursedemo.c -lcurses #include<curses.h> int main() {initscr(); //ncurse界面的初始化函数printw("This is a curses window.\n");//再ncurse模式下的printfgetc…

solidity 以太坊(Ether) 单位(很基础)

一个字面常数可以带一个后缀 wei&#xff0c; gwei 或 ether 来指定一个以太坊的数量&#xff0c; 其中没有后缀的以太数字被认为单位是wei。 在以太坊和许多其他基于以太坊的区块链系统中&#xff0c;以太币&#xff08;Ether&#xff09;是网络中的主要加密货币。 以太可以被…

Stable Diffusion绘画 | 图生图-涂鸦重绘

涂鸦重绘的整体参数配置&#xff0c;与局部重绘基本一致&#xff0c;仅多了一个蒙版透明度的参数。 都是对局部区域进行重新绘制&#xff0c;但它不仅能识别蒙版的区域&#xff0c;同时还能识别画笔颜色。 例如&#xff0c;对图片中的人物脸部&#xff0c;使用蓝色的画笔&…

JDK8优化JVM总结

JDK8优化JVM总结 默认垃圾回收器&#xff1a; 当前大多数应用仍然使用JDK 1.8&#xff0c;并且默认的年轻代垃圾回收器是Parallel Scavenge。Parallel Scavenge回收器旨在最大化吞吐量&#xff0c;适合对CPU使用率有较高要求的应用场景。 AdaptiveSizePolicy&#xff1a; 默认…

如何在linux系统上部署Redis

<1>简介 Redis 全称 Remote Dictionary Server&#xff08;远程字典服务器&#xff09;&#xff0c;是一个高性能的(key/value)分布式内存数据库&#xff0c;基于内存运行并支持持久化的NoSQL数据库&#xff0c;是当前最热门的NoSql数据库之一,也被人们称为数据结构服务…

SpringBoot依赖之H2 Database(一)

基本概念介绍 H2 Database 依赖名称: H2 Database 功能描述: Provides a fast in-memory database that supports JDBC API and R2DBC access, with a small (2mb) footprint. Supports embedded and server modes as well as a browser based console application. 提供支持…

ptrade排坑笔记——get_price函数在早上8点10分获取不了上一交易日的数据

前言 今天想要和大家分享的是使用get_price函数&#xff0c;但是却没有办法获取上一个交易日的一个交易数据&#xff0c;发生时间点是在早上的8点10分&#xff01; 一、问题描述 就和前言中的一样&#xff0c;在8点10分的时候&#xff0c;使用get_price函数&#xff0c;但是…

Spring配置

1.Spring的两大核心思想IOC和AOP思想 1.1类注解 1.Controller, Service, Configuration, Component, Repository 1.2方法注解 bean&#xff08;这个方法搭配上面的五大注解进行使用&#xff09; 2.Bean的名称 2.1.类注解名称 &#xff08;1&#xff09;默认首字母小写驼…

演示:基于WPF的DrawingVisual开发GS(2019)1822号矢量中国地图一

一、目的&#xff1a;基于WPF的DrawingVisual开发的矢量地图 二、预览 默认样式 深黑样式 深蓝色样式 深蓝色透明样式 演示&#xff1a;基于WPF的DrawingVisual开发GS(2019)1822号矢量中国地图二-CSDN博客VS2022&#xff0c;net7演示&#xff1a;基于WPF的DrawingVisual开发GS…

Codeforces Round 964 (Div. 4) (A~G1)

文章目录 题目链接写在前面A- AB Again?思路code B- Card Game思路code C- Showering思路code D- Slavics Exam思路 E- Triple Operations思路code F- Expected Median思路code G1- Ruler (easy version)思路code 题目链接 点击这里 写在前面 昨天晚上打的这场cf打的跟坨⑩…

C语言经典编程题——基础版1.13

【程序14】 题目&#xff1a;输入某年某月某日&#xff0c;判断这一天是这一年地第几天&#xff1f; #include<stdio.h> int main(){int year,m1,d1,num0;scanf("%d,%d,%d",&year,&m1,&d1);int m1,d1;while(m<m1||d<d1){if(m1||m3||m5||m7…

ASP.Net Core设置接口根路径的方法

使用asp.net core开发微服务项目&#xff0c;需要给每个服务设置不同的根路径&#xff0c;这样既能使用网关转发请求&#xff0c;又方便对单个服务进行测试&#xff0c;保证请求路径的统一。 设置方法需要使用中间件&#xff0c;在Program.cs添加如下代码 app.UsePathBase(&qu…

Using Embeddings API in Azure OpenAI

题意&#xff1a;当我在 Azure OpenAI 中使用嵌入功能时&#xff0c;我遇到了 404 错误&#xff08;资源未找到&#xff09; 问题背景&#xff1a; When I use embeddings with Azure OpenAI I am getting 404 (resource not found): 当我在 Azure OpenAI 中使用嵌入功能时&a…

kafka下载|安装

1、下载kafka https://kafka.apache.org/downloads 2、安装kafka 解压下载的kafka安装包即可 tar -xvf kafka_2.13-3.7.0.tgz -C /usr/local/3、查看kafka目录 bin目录&#xff1a;存放了脚本 config目录&#xff1a;主要存放了配置文件

Java语言程序设计——篇十三(1)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 欢迎大家&#xff1a;这里是我的学习笔记、总结知识的地方&#xff0c;喜欢的话请三连&#xff0c;有问题可以私信&#x1f333;&#x1f333;&…

Docker快速入门指南

&#x1f6e0;️ Docker 应用场景 Docker 是一个开源的平台&#xff0c;旨在简化应用程序的开发、部署和管理。它通过容器技术&#xff0c;将应用及其所有依赖打包在一个标准化的环境中&#xff0c;从而确保应用在不同环境中的一致性和可移植性。在 Python 爬虫的场景中&#…

高职院校云计算人才培养成果导向系统构建、实施要点与评量方法

一、引言 随着“十四五”规划的深入实施&#xff0c;云计算作为新一代信息技术的关键组成部分&#xff0c;已成为推动各行业数字化转型的重要驱动力。高职院校作为技术技能人才培养的重要阵地&#xff0c;如何根据云计算产业的发展需求&#xff0c;培养具备云计算技术应用与运…

面试笔记--(正在整理版)

面试常见: Jvm&#xff0c;高并发&#xff0c;多线程&#xff0c;数据库&#xff0c;redis&#xff0c;框架 多线程 1.线程和进程是什么?如何保证线程安全性? 进程线程&#xff08;一&#xff09;——基础知识&#xff0c;什么是进程&#xff1f;什么是线程&#xff1f;_…

【视频监控国标GB/T28181】 如何支持TCP和UDP接入

视频监控国标GB/T28181支持TCP和UDP接入的方式主要依赖于该标准中定义的通信协议和传输机制。以下是对这两种接入方式的详细解释&#xff1a; 一、TCP接入方式 1.1 TCP接入的特点 可靠性&#xff1a;TCP协议提供面向连接的、可靠的字节流服务。在数据传输过程中&#xff0c;…

【区块链+社会公益】透明劳务平台 | FISCO BCOS应用案例

建筑行业农民工工资结算一直以来是社会民生的痛点。一方面&#xff0c;由于行业服务链条长、管理协同效率低、对账复 杂等原因&#xff0c;农民工面临取证难、算量难、讨薪难问题。另一方面&#xff0c;承担实际施工任务的中小微建筑企业&#xff0c;数字化 程度低、转型难&…