工作中的一些问题记录
-
2023年9月15日:测试CIDR需求时,发现如果有两个CIDR表示的地址范围有重复,那么使用之前的CIDR匹配算法匹配某些IP会不上?
之前的CIDR匹配算法:CIDR表示的是一个IP段,一个IP可以表示成一个long类型数字,因此CIDR表示的范围就是两个long类型数字范围。将这些范围的起始long值保存至treeMap中。匹配一个IP时,将IP转成long值,查找大于此long值的最小元素对应的CIDR,然后再判断此long值是否小于此CIDR的结束long值,如果是,则表示匹配到该CIDR,否则没有匹配上。
分析:该算法必须保证所有的CIDR段是没有重复的,但实际场景中无法保证。
不满足场景:如果CIDR地址有重复的,比如字典中有两个CIDR地址,10.100.78.0/29和10.100.78.0/24,前者包含的地址范围是10.100.78.0-10.100.78.7,后者包含的地址范围是10.100.78.0-10.100.78.255,如果用10.100.78.8来匹配,应该是匹配到10.100.78.0/24这个CIDR地址。但是基于之前的匹配算法,两个都匹配不上。
原因:因为现在的TreeMap根据起始地址来排序,查找大于此long值的最小元素对应的CIDR,获取到的CIDR范围是10.100.78.0-10.100.78.7,但第二步比较结束地址时发现此IP10.100.78.8不在此CIDR表示的范围内,导致没有匹配上。
算法改进:treeMap中保存结束地址,使用结束地址来匹配。
-
解析规则中date解析规则比较特殊
date解析规则采用的date字段来源有两处:元数据中的date字段,前面的解析规则中生成的date字段。
从原理上说,date匹配用正则表示法即可匹配,但是实际场景中,date表示格式有很多种,因此就需要写很多种date匹配的正则表达式,但正则表达式有学习门槛或写错,所以会增加交付难度。因此采用事先计算好date字段值的起始和结束位置,解析date时采用字符串截取的方式解析date字段。
-
下发任务到agent前,将配置中的key的["、"]和开头的.去掉
超哥的解释是:因此golang的unflattern的方式和java的不一样(filebeat的解析,flat展开a[0].xxx,就变成了 a.0.xxx),对数组的表示方式不一致,所以java下发的配置前做次转换。
我还是有疑问:因为不管java和golang的unflattern实现如何不同,他们内部是自洽的。而json格式肯定是统一的,因此下发json即可,因此此疑问仍然还在。
-
本地agent调试问题
问题描述:开发后,肯定需要在本地调试,但是当前调试会有问题,比如管理端和网关都使用100.8的,agent本地启动,但本地agent注册到网关上的地址不是本地真实的地址(可能是VPN地址),会导致任务下发时网关连不上agent而失败。
解决办法:网关也用本地网关,这样网关就能跟本地网关通信。
疑问:本地启动管理端或解析服务,nacos上的ip地址都是本地IP地址,为何我们的网关使用的IP却是VPN地址呢?(虽然有办法解决,但是疑问未能消除)
另外,本地如果要调试任务变更,只能将agent打包,通过deamon来启动,但是这样就没办法debug了,只能看日志,也挺麻烦的。可以研究下如何不打包调试。
-
Windows服务的agent-deamon没有打印日志
之前使用了多个writer写操作,一个是窗口,一个是文件,内部逻辑是for循环写,按照输入的顺序写。但因为Windows服务模式下没有窗口,因此第一个会写失败,而内部逻辑就写失败就退出了,不会继续写第二个。因此不会执行写文件。
如果要同时写,就要把文件写在前面,这样可以把内容输出到文件中。
-
测试发现采集的数据无法写到ES
采集任务配置时,选中索引。但是采集到数据没有写到ES,解析服务报“拒绝连接”错误。
原因:管理后端和解析服务配置的ES地址不一样。
分析:这里还好是解析服务写ES失败,如果写成功,那肯定没有异常信息,会更让人疑惑。
解决思路:管理后端和解析服务相同配置统一到一个配置文件中,后续要跟踪解决进展。
-
东财交付发现Logger后端日志报websocket相关的错误
原因在于nginx的websocket的URL的location配置有问题,需要在对应location下新增配置:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
HTTP/1.1起,在header信息中允许定义一个Upgrade字段,用来告诉服务端后续要使用新的http协议版本或者换一个协议,websocket就是从http协议发起要更换到ws协议的,所以websocket需要添加这个字段。Connection表示后续连接状态,譬如我们熟悉的keep-alive,而Connection: Upgrade是告诉服务器后续要进行Upgrade。
-
Docker 在window上执行打镜像,执行容器报exec ./entrypoint.sh failed: No such file or directory
原因在于Windows文件换行符跟Linux不一样,通过file entrypoint.sh可以看到“with CRLF line terminators”:
cat -v entrypoint.sh也能看到可视化看不到的字符:
使用dos2unix转码即可解决这个问题。因此所有在Windows编辑过的sh文件,执行前都需要经过dos2unix处理。
-
alpine的jdk镜像很小,应用比较广泛,但随之而来的问题就是配套的工具不全,比如top,如何解决?
alpine的jdk镜像中top只能查看进程,无法查看线程信息,在排查CPU高等需要线程信息的场景下无法满足要求。经过实验,alpine中的top在Dockerfile中无论升级还是安装,均无法跟普通Linux上的top命令一样。因此只能另辟蹊径,有个htop工具可以替代top,经实验可以查看线程信息。
htop查看线程信息命令:htop -p <PID,PID...>
-
Swagger+Knife4j的组合,前端访问http://192.168.10.90:8183/doc.html#/home报“Knife4j文档请求异常”
原因:响应swagger的接口JSON是一个非法JSON,一般出现此情况,是因为后端在给List集合的属性赋予了exmpale属性。导致生成出来的JSON并非是一个标准的JSON,而Knife4j组件在前端是通过JSON.parse()方法对后端返回回来的数据进行JSON转换,这会导致转换失败。
解决办法:把集合属性中的example属性去掉,交给springfox-swagger2框架来自动解析。
-
Windows服务删除不了,如何解决?
打开注册表编辑器,找到下面的键值:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 一般服务会以相同的名字在这里显示一个主健,直接删除相关的键值便可。
-
后台日志报nacos相关的longPolling error错误,如何解决?
原因是nacos版本和spring-cloud-alibaba版本不匹配造成的。需要使用对应版本:
-
ES无法启动,命令行启动日志打印中,突然报killed(已杀死),如何解决?
报错原因:服务器可用内存没有达到ES所需内存的默认值。
解决办法:
使用free -h 命令,查看系统内存情况,available列即系统当前系统可用的内存,根据此值调整ES的内存设置。
ES的JVM配置文件路径:config/jvm.options。修改-Xmx和-Xms即可。
-
docker容器安装MySQL,有的环境通过外部机器无法远程连接MySQL,如何解决?
1、排查防火墙状态
防火墙打开可能会导致网络不通。
查看防火墙状态:service iptables status
关闭防火墙:service iptables stop
2、查看ping和telnet的结果
能ping通,但telnet不通。说明网络是通的,只是端口无法连接上。
3、查看MySQL容器端口映射
通过docker ps |grep mysql,查看正常环境和异常环境端口映射情况:
正常环境:
异常环境:
对比之下,发现异常环境少了:::3306->3306/tcp的映射,也就是说此环境的MySQL容器只支持IPV4网卡的请求。
4、查看监听端口状态
正常环境:
异常环境:
对比之下,发现异常环境只监听了IPV6网卡的此端口,没有监听IPV4网卡的此端口。而我们外部机器使用的是IPV4网段发送请求,所以无法访问MySQL容器就是正常的。
5、分析原因
为什么两个环境的docker-compose.yml文件一样,为何打出来的镜像不一样?查看docker版本,
正常环境:
异常环境:
对比发现,原来是两个docker版本不一致导致。
6、解决问题
方法一:将异常环境docker版本跟正常环境统一。但鉴于已经部署好了,此方法有点麻烦。
方法二:利用Linux的数据包转发功能,即net.ipv4.ip_forward参数,此参数默认为0,表示不开启数据包转发功能(为了安全)。我们可以手动开启此功能,使用命令:sysctl -w net.ipv4.ip_forward=1。此命令实时生效,如果要永久生效,需要修改对应配置文件。

浙公网安备 33010602011771号