6.Haproxy常见功能压缩报文修改健康性检查

haproxy如何携带用户信息

正常后端服务器看到的IP都是haproxy的IP地址

client IP就是192.168.126.133👇

image-20240903103325184

后端server看到的就是haproxy中过来的IP地址👇

image-20240903103334452

haproxy透传

1、option forwardfor 实现7层透传

image-20240903105522542

一般写到主配置文件的里默认值语块就行了

image-20240903113519659

请求

image-20240903105539067

可见x-forward-for

image-20240903105749476

后端nginx需要修改log格式才能看到这个参数

image-20240903112722264

log_format的格式有个规律:就是比如,要抓取抓包里看到的x-forwarded-for字段,写到log里就要

1、http头部标识$http,

2、然后-换成_下划线,

3、全部小写

此时后端就可以看到真实的用户IP了👇

image-20240903112955717

总结

image-20240904102918252

需要注意的是,header 大小写,还有减号-,在后端nginx日志里都转成 小写,和下划线。

image-20240904103408040

后端nginx日志里转小写和下划线👇

image-20240904103509338

总结,补充:

image-20240904105417822

image-20240904105539496

2、四层透传-不推荐的方式,其实是mode tcp而不是lvs那种四层透传

#haproxy配置:
listen web_http_nodes
    bind 192.168.126.132:80
    mode tcp
    balance roundrobin
    server web1 www.testtttt.com:80 send-proxy check inter 1000 fall 2 rise 10  # 比常规的转发cli多一个send-proxy,会造成大量PROXY TCP4 a.b.c.d a.b.c.d xxxxx 报文 


--------------------------------------------

#后端服务器的nginx配置:在访问日志中通过变量$proxy_protocol_addr 记录透传过来的客户端IP
http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" "$proxy_protocol_addr"'
    server {
        listen 80 proxy_protocol;  # 启动此项,将无法直接访问此网站,只能通过四层代理访问
        server_name www.testtttt.com;
    }
}

实操过程处理截图,含故障注意点:

​ 就是send-proxy的配置,要么server xxx 都配置上,要么都不配,否则会导致send-proxy配置的那个后端请求失败,可能是初始实验理解不到位,其实就是后端nginx没有配置proxy_protocol。继续往下看就行了。不要太纠结。纠结的话,实验敲一下就行了。

比如错误案例

haproxy的配置👇

image-20240903162857648

对应的后端126.134的nginx的配置👇

image-20240903162934576

不过好像无法复现了,现在上面配置也不会报错了,

可以复现,就是上图的listen 80后的proxy_protocol去掉,就能看到了(看到这些大量的haproxy 发过来的PROXY TCP4),不仅如此,而且此时如果观察log可见,其实也已经可以携带了client IP了。👇只不过,就是页面还不正常。

image-20240904094250960

同样抓包可见,需要知道的是上图除了192.168.126.1高亮的那一行是HTTP包👇,其他的都是TCP包--这些192.168.126.132频繁发给192.168.126.134的包是没有像下图一样携带什么IP信息来着。

image-20240904094735994

比较好奇的是continuation关键字

image-20240904095819605

然后,再在后端nginx服务,加了proxy_protocol后就不能直接访问了

image-20240904092706153

只能通过proxy进行访问了,此时页面正常,但是log里就看不到这个真实的IP了,以及的频繁的PROXY TCP4 也看不到了--但是这个频繁的报文只是看不到,其实抓包可见还是一直再发送的

但是log和抓包都看不到continuation这个报文,以及真实的客户端IP也看不到了,不过只需要再来一步

就是log日志里写上$proxy_protocol变量就行了

image-20240904100219004

image-20240904100247326

此时log里有了

image-20240904100235153

抓包依旧没有,抓包看来就是后端nginx配置正确了,抓包反而看不到了,哈哈,应该是有的,否则log里不可能看到。果然,抓包工具显示问题,再敲一下回车就出来了

image-20240904101839543

但这种方式其实也是2个TCP,haproxy越是说做4层透传,LVS才是。

也可以两个方式都用上,就是mode tcp及支持x-forward-for,也支持proxy_protocol_addr

image-20240918112307178

image-20240918112333197

然后去后端nginx配置

image-20240918112400702

image-20240918112421413

看看log就两种携带真实客户IP的方式都生效了

image-20240918112516224

image-20240903103518611

image-20240903114342124

报文修改

理论

代理可以修改的报文一般就是自己发出去的报文,也就是②和④两个包

image-20240918115328273

http-request就是②的改包

http-response就是④的改包

image-20240918115444171

image-20240918115744923

image-20240918115844886

image-20240918115900514

image-20240918115922390

image-20240918115948026

老版本了解下就行:

image-20240918133127414

实验

1、先看未修改之前的head

image-20240918154242063

👆大段大段每秒一个的都是健康检测的,而拼手速抓到的就是192.168.126.1 去curl出来的包,这个包是可以看到当前的header有哪些,其中client-real-ip是自定义的x-forward-for👇

image-20240918154706620

命令参数配置位置说明:

image-20240918161348420

PS:√! 和 √的区别,就是能用但是有限制,需要点进去看详情的意思。然后就点进去瞧一瞧

image-20240918162318894

这段话就不太好看懂,拆分开来意思大概如下:

1、default默认的就是不带名字的,就是http-request这个指令不能配置在匿名的default下

这就是匿名的👇defaults

image-20240918162841766

而这是命名的default,既然是命名的就需要调用的

1、命名方法,和调用方法

image-20240918164430430

2、所以http-request,如果配置在defaults里,是要用命名的defaults的,

3、而命名的defaults xxx,如何被listen,以及frontend和backend调用

就是用这种方式,或者写在前后端或listen语句块前面就行

image-20240918164736700

4、但是这个http-request写到default xxx里,是不能同时被frontend和backend调用的,也就是不能被listen调用。

5、但是http-requst却可以直接写到listen里,好奇怪....不研究了

实验,实验

给后端转发的时候添加header字段

写到frontend里

image-20240918170634668

此时后端抓包就能看见了👇

image-20240918170710009

写到backend里

image-20240918171227295

同样生效

image-20240918171255289

写到listen里

image-20240918171739826

生效的

image-20240918171801157

给后端转发的时候修改header字段

删除hosts信息,一样不影响转发和用户请求。

image-20240918172653545

image-20240918172607220

image-20240918172620239

给后端转发的时候删除header字段

image-20240918174717444

除了真实的用户IP地址信息,其他确实可以删除

image-20240918174754677

不过删的太多会报错

image-20240918175724536

写到backend里去看看x-forward-for能否被删除

还是不能删除x-forward-for

image-20240918175118967

image-20240918175132594

不过此时用户以及curl报错了

image-20240918175712413

说明x-forward-for是送出去的时候打上真实用户IP的动作实在http-request之后的。正要想删这个字段,就别打上就行了,本来默认就不携带,哈哈。

给用户回包的时候增删改字段

image-20240918180006652

比如正常的响应头里会暴露真实的web服务器的信息,如上图的server:nginx/1.26.1

隐藏掉

image-20240918180302609

自定义日志格式

image-20240919141759500

image-20240919145038674

log指令适配的语法块,就是哪都可以👇

image-20240919145227504

然后看到(*) 其实就是表格前文会有解释,我跟你说,这种一般就是表头,表尾,点进去蓝色就是子链接,三个地方找找ctrl f 搜索下,一般就能找到了。

image-20240919145547382

image-20240919175140751

实验

image-20240919145907743

image-20240919145934368

修改为httplog

image-20240919150020763

image-20240919150053839

上图关键字段解释:这个可以用来排除网络故障哦

image-20240919152635907

PS:主要www.ming.com不要以为是什么IP反解哦,其实只是Haproxy配置文件里的frontend xxx起的名字

改一下就看到了👇

image-20240919152005283

image-20240919152037031

压缩功能-节省带宽

压缩-耗时CPU,节省网络传输空间,CPU一般富裕的都是,所以还是推荐压缩的,这样就是用时间换空间,用CPU的计算时间 来换取 网络传输的小空间占用。其实也提升了传输的时间。也是用时间换时间。哈哈,有点哲学了哦,不过我不太喜欢话术~

image-20240919152801019

实验测试压缩的好处

准备大一点的文件测试用

image-20240919153720723

mess文件补一个后缀.html否则浏览器不识别就会直接下载处理了

image-20240919154421867

image-20240919154016416

之前nginx里也提到过 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types

image-20240919154037953

这个默认行为的资料说明如下

image-20240919154504850

好,回到测试压缩效果,276M的文本耗时情况如下👇

压缩前耗时

image-20240919154720956

稍微等等吧,文件还是给大了哈哈👆

然后

image-20240919154912706

OOM了,,,,卧槽,直接我笔记本报警 内存爆了。。。一个chrome内存占用96%,紧接着就上图报错后,内存才降下来。不过第一次会OOM,后面就不会,可能还是有缓存机制的。也许可以通过清理APPLICATION进一步复现OOM,好像无痕可以复现👇

oom001

再等会就oom了👇

image-20240919160057979

看来我踩了一个前端的坑

image-20240919160421214

分页体验没有流式的好,所谓流式其实就是滚轮滚下去才加载到内存里,这样内存在接收大文本的时候可以得到释放。分页不是分页面的意思,可能是区别于流式的一行一行,而是一屏一屏也就是一页一页的加载。

​ 然后浏览器的看到东西都是再内存里的,是不会放到本地磁盘上的。所以浏览器经常占用大量内存

image-20240919162417064

好像系统本身也有一些优化,记得第一次是系统报警内存96%了,后来系统内存就没超过80%,所以还是这个机制自动生效了看来,不过这个机制保护了整体系统,但是对于浏览器的内存一样是限制了的,所以浏览器层面的OOM还是在的。

image-20240919160725605

好 没有启用haproxy压缩的时候一次OOM出来要5分钟👇

image-20240919161559167

同时看看响应头

image-20240919162559292

此时是没有压缩的

启动后端nginx压缩再试试

image-20240919162733836

开启nginx的压缩试试,4分就抵达了OOM了确实加速了,

image-20240919163327868

不过OOM毕竟是故障,不适合用来对比测试。减少加载文本重新对比测试。

image-20240919163629290

还是太大了

find -name "mess_parta[^a]*" -exec rm -rf {} \;
mv mess_partaa mess.html

image-20240919164413408

后端服务器nginx直接压缩,测试多次 5-7s左右的样子。

image-20240919165014996

后端nginx不压缩测试 3-6s的样子,就是nginx不压缩,我TM还快一点。就是用户PC浏览器解压耗时了。。。

image-20240919164628755

image-20240919164851573

等等,调大测试文本,拉开后端nginx启用和不启用压缩的耗时差距

不压缩

测多几次6次的样子,发现稳定再33s的样子,那个下图19s神经病不管他。

image-20240919170543181

image-20240919170748525

image-20240919170903592

开启后端nginx的压缩测多几次,发现25s-1min都有。整体耗时50s的样子,压缩反而变长了。

发现①首先后端nginx开启压缩后,waitting for server response时间变成好多,就是后端要压缩所以耗时变成了。

②其次,整体上content download时间也是加载文件时间,也TMD变长了,

所以还是那句话,还不如不压缩呢。

image-20240919171617834

再通过对比后端nginx 压缩 和没压缩的 log里的字节数看看

image-20240919174036146

结论1:压缩可能带来不好的用户体验

压缩后👆网络传输的文本大小确实小了很多👇417663 : 21032194 的效果,节省了网络带宽,加重了用户加载,用户体验变差。

也有可能是我服务的CPU也就是nginx那台CPU太差了。也不是我对比了TOP查看压缩和不压缩的CPU,都占用很小。那就不知道了。。。

image-20240919174218944

启用haproxy的压缩测试

haproxy的配置示例:

compression alog gzip raw-deflate  # alog是算法的缩写,就是用gzip和raw-deflate压缩算法。
compresssion type text/html text/css text/plain  # 这是针对哪些mime类型进行压缩

image-20240919175701411

此时nginx日志是没有压缩的,因为c---haprox---nginx , haproxy和nginx之间是没有压缩的,

压缩是haproxy做的,是发给c的时候压缩的,所以日志要开哈proxy的发送文件大小

haproxy压缩的效果,在用户浏览器里可以看到,haproxy日志是压缩前的字节数

同样结论2:压缩可能带来不好的用户体验

content download 时间大差不差,整体是压缩后反而时间变长。

image-20240919180220370

image-20240919180122149

haproxy转发了一下多了210字节

观察用户那边吧

haproxy开启压缩:后端nginx未开启压缩

image-20240919180427476

haproxy关闭压缩:后端nginx未开启压缩

image-20240919180636810

image-20240919180612519

client---haproxy---nginxServer,建议压缩在nginx上做,减轻haproxy的压力。

后端服务器的健康性检查

概述

image-20240924162027200

默认也是有健康检查的,不过是L4的,不是http应用的检查

image-20240924163049972

option http就是开启后端的http应用层的检查,望文生义,后端服务的健康检查自然是写到backend、以及合二为一的listen里的,是不能写到frontend里的

image-20240924163359003

实验

image-20240924164343643

此时status页面是报错的👇检查失败,也就是说haproxy的健康检查开启option http默认就是是失败的,要处理

image-20240924165323484

PS:上图由于两个server都是down,所以最后一样的Backend就是DOWN 红色的了。

然后tcpdump抓包也是报错的

image-20240924165307935

-vv也一样

image-20240924165455371

改成option http GET /index.html

image-20240924170149774

此时就可以了

image-20240924170309652

抓包可见

image-20240924170338756

然后nginx的log也可以看到,不过实验遇到点问题

192.168.126.133和134两个http检查都是OK的

image-20240924171748343

但是两台nginx的log,133的tcpdump明明是有的,但是log就是看不到,134 是正常的。

image-20240924172024863

研究下为什么133的log看不到健康检查过来的http请求。

image-20240924172039786

手动curl,两台nginx的log倒是都可以看到

image-20240924171803717

image-20240924174007984

妈的,出BUG了,删掉a.conf让default.conf抢先,haproxy的option http有日志了.

不管了,反正有了,操作过程就是复制了一个134的a.conf过来抢了,然后删掉只剩default.conf就好了。

image-20240924174903362

image-20240924172322207

再一个error.log里的notice可能级别看不全,不过和这里的实验没关系,就是OPTIONS发过去也是在nginx的access日志里而不是在error日志里

image-20240924172729409

修改index.html造成故障

造成:健康检查option httpchk GET /index.html的故障

image-20240924181239029

image-20240924181254234

鼠标悬浮那边就是image-20240924181315142

好玩的是192.168.126.132的access和error日志都看的到

image-20240924181534339

减轻7层健康检查的负担

如果默认是访问首页,首页很大会导致每次健康检查都要打开很大的页面。

所以 自定义一个简单页面用来检测就行了

后端服务器弄一个状态页👇

echo ready > /usr/share/nginx/html/check.html

也许我可以弱化实验,因为 实验过程繁复,我已经有一些基础应对,所以记录操作和关键,就会凸显步骤,脉络更为清晰,而不必每个实验,甚至小实验都开几台模拟器敲一遍。 错!!! 模拟器打开要1分钟,敲实验也就几分钟,不要为懒找借口。正所谓道理怎么讲都是通的,不讲道理的坚守往往更为宝贵。

不过倒是提醒了我,实验要敲,梳理脉络也要清晰,不要什么都往笔记里扔。

工作案例

1、gitlab拆库,用户无感

2、我的环境是gitlab虚拟机,所以直接克隆3份出来,每份只留1个不同的库

3、不同库的url使用location转到不同的后端VM

4、针对登录这些同样域名的处理就用会话保持来做

浏览器没问题可以做出来,但是git clone由于不支持重定向所以做不了。而gitlab主要就是给研发用的git clone不支持就没戏了。所以gitlab拆库 无感 做不了。

附详情:

image-20241022111040433

proxy_set_header Host $host;作用就是让后端gitlab认定为你设定的host头,也就是域名咯,如果不改就是:

不重定向分库的难点:client请求的nginx代理的域名,会作为后端gitlab 认证登入页面的域名处理,这样nginx的一个域名两个库的登入url都是一样的,就不太可能实现路由的区分;

重定向分库的缺点:如果repo1和repo2分别改为proxy_set_header Host www.repo1.com和www.repo2.com就会让后后端gitlab基于这个host生成login的url,返还给用户,用户就跳转到这两个域名去了,所以分库实现,不过这是浏览器支持了,git clone不支持的。

工作案例-service里的环境变量问题

1、cli运行没问题

[root@network001 log]# nohup /root/bin/python /pythonProject/netPolicyAuto/ssgAuto/devIpPermitTemporarily/transApi/api002.py &

2、改成service运行的起来,貌似也没问题

[root@network001 log]# cat /usr/lib/systemd/system/policytmp.service
[Unit]
Description=API 002 Python Service
After=network.target

[Service]
ExecStart=/root/bin/python /pythonProject/netPolicyAuto/ssgAuto/devIpPermitTemporarily/transApi/api002.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

[root@network001 log]#

但是api002这个其实是api咯,调用的时候通过status 看到报错的👇

image-20241022165426162

58行就是ssh登入的时候用了os调用变量

image-20241022165506536

image-20241022165546832

而变量值通过os.environ.get这句取出来的,service里就取不出来,修改为实际的密码后,测试ok,说明就是这里os的调用在service服务里实现不了。

进一步研究发现可以取出来的,通过service里设置环境变量的方式,但是即使取出来还是报错一样的。

工作案例-DNS 53丢包

1、现象

192.168.10.2的tcp 53丢包,这是tcping测试可见的,

同样dig解析也就是udp 53 卡顿

ssh端口都是不丢包,但是存在ssh登入卡几秒的情况,偶发

2、处理:

https://www.cnblogs.com/lemon-flm/p/7975812.html

Copyright 🌹 © oneyearice@126.com 2022 all right reserved,powered by Gitbook文档更新时间: 2024-10-23 16:37:56

results matching ""

    No results matching ""