1.go-iptables功能与源码详解
2.同与不同,源码兜底驱动B端系统的中流砥柱 --- 打开源码聊聊流程引擎的细节
3.最完备的懒加载错误兜底方案,再也不会白屏了!源码兜底
go-iptables功能与源码详解
介绍iptables之前我们先搬出他的源码兜底父亲netfilter,netfilter是源码兜底基于 Linux 2.4.x或更新的内核,提供了一系列报文处理的源码兜底能力(过滤+改包+连接跟踪),具体来讲可以包含以下几个功能:
其实说白了,源码兜底google日历手机版源码netfilter就是源码兜底操作系统实现了网络防火墙的能力(连接跟踪+过滤+改包),而iptables就是源码兜底用户态操作内核中防火墙能力的命令行工具,位于用户空间。源码兜底快问快答,源码兜底为啥计算机系统需要内核态和用户态(狗头)。源码兜底
既然netfilter是源码兜底对报文进行处理,那么我们就应该先了解一下内核是源码兜底如何进行收发包的,发生报文大致流程如下:
netfilter框架就是源码兜底作用于网络层中,在一些关键的源码兜底报文收发处理路径上,加一些hook点,可以认为是一个个检查点,有的在主机外报文进入的位置(PREROUTING ),有的在经过路由发觉要进入本机用户态处理之前(INPUT ),有的在用户态处理完成后发出的地方(OUTPUT ),有的在报文经过路由并且发觉不是本机决定转发走的位置(FOWARD ),有的在路由转发之后出口的位置(POSTROUTING ),每个检查点有不同的规则集合,这些规则会有一定的优先级顺序,如果报文达到匹配条件(五元组之类的)且优先级最高的规则(序号越小优先级越高),内核会执行规则对应的动作,比如说拒绝,放行,记录日志,丢弃。
最后总结如下图所示,vscode源码 设计思路里面包含了netfilter框架中,报文在网络层先后经过的一些hook点:
报文转发视角:
iptables命令行工具管理视角:
规则种类:
流入本机路径:
经过本机路径:
流出本机路径:
由上一章节我们已经知道了iptables是用户态的命令行工具,目的就是为了方便我们在各个检查点增删改查不同种类的规则,命令的格式大致如下,简单理解就是针对具体的哪些流(五元组+某些特定协议还会有更细分的匹配条件,比如说只针对tcp syn报文)进行怎样的动作(端口ip转换或者阻拦放行):
2.1 最基本的增删改查
增删改查的命令,我们以最常用的filter规则为例,就是最基本的防火墙过滤功能,实验环境我先准备了一个centos7的docker跑起来(docker好啊,实验完了直接删掉,不伤害本机),并通过iptables配置一些命令,然后通过主机向该docker发生ping包,测试增删改查的filter规则是否生效。
1.查询
如果有规则会把他的序号显示出来,后面插入或者删除可以用 iptables -nvL -t filter --line
可以看出filter规则可以挂载在INPUT,FORWARD,OUTPUT检查点上,并且兜底的规则都是ACCEPT,也就是没有匹配到其他规则就全部放行,这个兜底规则是可以修改的。 我们通过ifconfig查看出docker的ip,然后主机去ping一波:
然后再去查一下,会发现 packets, bytes ---> 对应规则匹配到的报文的个数/字节数:
2. 新增+删除 新增一条拒绝的报文,我们直接把docker0网关ip给禁了,这样就无法通过主机ping通docker容器了(如果有疑问,下面有解答,会涉及docker的一些小姿势): iptables -I INPUT -s ..0.1 -j DROP (-I不指定序号的话就是头插) iptables -t filter -D INPUT 1
可见已经生效了,拦截了ping包,随后我删除了这条规则,批量下载图片 源码又能够ping通了
3. 修改 通过-R可以进行规则修改,但能修改的部分比较少,只能改action,所以我的建议是先通过编号删除规则,再在原编号位置添加一条规则。
4. 持久化 当我们对规则进行了修改以后,如果想要修改永久生效,必须使用service iptables save保存规则,当然,如果你误操作了规则,但是并没有保存,那么使用service iptables restart命令重启iptables以后,规则会再次回到上次保存/etc/sysconfig/iptables文件时的模样。
再使用service iptables save命令保存iptables规则
5. 自定义链 我们可以创建自己的规则集,这样统一管理会非常方便,比如说,我现在要创建一系列的web服务相关的规则集,但我查询一波INPUT链一看,妈哎,条规则,这条规则有针对mail服务的,有针对sshd服务的,有针对私网IP的,有针对公网IP的,我这看一遍下来头都大了,所以就产生了一个非常合理的需求,就是我能不能创建自己的规则集,然后让这些检查点引用,答案是可以的: iptables -t filter -N MY_WEB
iptables -t filter -I INPUT -p tcp --dport -j MY_WEB
这就相当于tcp目的端口的报文会被送入到MY_WEB规则集中进行匹配了,后面有陆续新规则进行增删时,源码集成安装完全可以只针对MY_WEB进行维护。 还有不少命令,详见这位大佬的总结:
回过头来,讲一个关于docker的小知识点,就是容器和如何通过主机通讯的?
这就是veth-pair技术,一端连接彼此,一端连接协议栈,evth—pair 充当一个桥梁,连接各种虚拟网络设备的。
我们在容器内和主机敲一下ifconfig:
看到了吧,容器内的eth0和主机的vetha9就是成对出现的,然后各个主机的虚拟网卡通过docker0互联,也实现了容器间的通信,大致如下:
我们抓个包看一哈:
可以看出都是通过docker0网关转发的:
最后引用一波 朱老板总结的常用套路,作为本章结尾:
1、规则的顺序非常重要。
如果报文已经被前面的规则匹配到,IPTABLES则会对报文执行对应的动作,通常是ACCEPT或者REJECT,报文被放行或拒绝以后,即使后面的规则也能匹配到刚才放行或拒绝的报文,也没有机会再对报文执行相应的动作了(前面规则的动作为LOG时除外),所以,针对相同服务的规则,更严格的规则应该放在前面。
2、当规则中有多个匹配条件时,条件之间默认存在“与”的关系。
如果一条规则中包含了多个匹配条件,那么报文必须同时满足这个规则中的跑跑双卡源码所有匹配条件,报文才能被这条规则匹配到。
3、在不考虑1的情况下,应该将更容易被匹配到的规则放置在前面。
4、当IPTABLES所在主机作为网络防火墙时,在配置规则时,应着重考虑方向性,双向都要考虑,从外到内,从内到外。
5、在配置IPTABLES白名单时,往往会将链的默认策略设置为ACCEPT,通过在链的最后设置REJECT规则实现白名单机制,而不是将链的默认策略设置为DROP,如果将链的默认策略设置为DROP,当链中的规则被清空时,管理员的请求也将会被DROP掉。
3. go-iptables安装
go-iptables是组件库,直接一波import " github.com/coreos/go-ip...",然后go mod tidy一番,就准备兴致冲冲的跑一波自带的测试用例集,没想到上来就是4个error:
这还了得,我直接去go-iptables的仓库issue上瞅瞅有没有同道中人,果然发现一个类似问题:
虽然都是test failures,但是错的原因是不一样的,但是看他的版本是1.8的,所以我怀疑是我的iptables的版本太老了,一个iptables -v看一眼:
直接用yum update好像不能升级,yum search也没看到最新版本,看来只能下载iptables源码自己编译了,一套连招先打出来:
不出意外的话,那就得出点意外了:
那就继续下载源码安装吧,然后发现libmnl 又依赖libnftnl ,所以直接一波大招,netfilter全家桶全安装:
Finally,再跑一次测试用例就成功了,下面就可以愉快的阅读源码了:
4. 如何使用go-iptables
5. go-iptables源码分析
关键结构体IPTables
初始化函数func New(opts ...option) (*IPTables, error) ,流程如下:
几个重要函数的实现:
其他好像也米有什么,这里面就主要介绍一下,他的命令行执行是怎么实现的:
6. Reference
同与不同,驱动B端系统的中流砥柱 --- 打开源码聊聊流程引擎的细节
企业级平台中,流程引擎与规则引擎并列双子星,承担着至关重要的角色。市面上虽有众多轻量级流程引擎组件,但流程引擎实则是一个古老、严肃而不轻率的话题。本文将通过实践探索开源流程引擎的实现、部署与使用技巧,旨在为正处于选择阶段的读者提供指导。
我们将深入探讨以下场景:企业内部审批协同、商家招商入驻、app上架自检部署、交易正逆向等典型依赖流程串行的业务流程。
首先,为何引入流程引擎?引入流程引擎旨在提高研发效率与业务规模化后的工作效率。它能提供流程管理、编排与节点灵活调整能力,尤其适用于需要流程管控与高度复用的业务场景。
在选择流程引擎时,需考量以下因素:符合BPMN 2.0标准,支持流程运行时的内存服务编排与流程暂停、中断等特性,保持轻量化,采用插件式架构,提供去中心化存储模式。
经过对比调研,我们选择了智能引擎(Smart-engine),它满足了我们的需求,提供了一套精简的核心模块,定制改造成本低,支持本地部署,且社区活跃度良好。
深入智能引擎内部,了解BPMN的基本知识与2.0标准的元素。通过部署与业务应用集成,实现流程引擎的独立运行。
智能引擎提供了一套基础的流程引擎架构,包括产品形态层、服务层与拓展层。代码部署在业务应用内,灵活适配业务需求。引擎层负责流程定义文件的解析与核心层的流程运行,数据层则负责持久化流程变量。
实例演示:我们从一个复杂逆向流程(如商家结束合作流程)开始,展示如何在业务流程生命周期中运行智能引擎,包括启动流程、非暂停业务节点的流转、遇到需要暂停的节点与流程重新唤起等。
智能引擎在处理异常时,遵循性能优先的原则。若流程节点在运行中发生异常中断,流程实例数据不会做异常处理,可能导致数据丢失。为解决这一问题,我们设计了流程节点内业务逻辑异常兜底方案,即在节点执行过程中主动捕获异常,并暂停流程,持久化所有上下文数据,以便后续流程重试或介入排查。
关注微信公众号「小爱同学的企服技术笔记」,获取更多关于流程引擎的详细信息与实践技巧。
最完备的懒加载错误兜底方案,再也不会白屏了!
优化首屏加载渲染速度,减小首屏包体积,项目中大量代码通过懒加载动态导入(dynamic import)实现。然而,动态导入失败未做处理,导致页面白屏问题在慢网或CDN故障时频繁出现。为解决此问题,需制定一套完善的错误兜底方案。
使用 webpack 时,动态导入常通过返回 promise 对象的函数实现。导入成功时,promise 需 resolve 默认导出 (default export) 的模块,失败情况却未被处理。以 React 为例,通过搭配 React.lazy 动态导入,其实现依赖于返回 promise 的函数。然而,动态导入失败时,lazy 并未隐式处理异常。
因此,需在动态导入外层增加异常捕获及处理逻辑。常见的粗放做法是捕捉错误后执行 location.reload(),使页面刷新。然而,对于因非代码逻辑问题导致错误的网络请求,最佳做法是增加重试机制以提升稳定性。针对慢网和 CDN 故障,动态导入失败时的处理需包括重试功能。
Webpack 懒加载原理在于动态插入 script 标签,在 onload 事件触发时调用 promise 的 resolve 方法加载资源,在 onerror 事件触发时调用 reject 方法。在 script 加载失败时,需避免执行原本的 onerror,同时将原本的 onerror 赋给后续尝试加载的 script。此外,mini-css-extract-plugin 将样式单独提取为 css 文件,加载失败时需采取与 script 类似的处理方式,确保不触发 link 标签的 onerror。
为解决 CDN 故障导致的资源加载失败问题,可以引入一个无侵入式的静态资源自动重试包。该包通过 hook 原生的 document.createElement 和 script.onerror 方法,同时监听 document 的 error 事件,实现 CDN 重试机制。引入此包后,项目可直接实现 CDN 重试功能。
针对资源仍无法加载回的情况,虽然错误未抛出,但页面上未展示资源对应的功能,用户仍能正常使用页面,避免了白屏现象。通过此优化方案,首屏加载速度得到显著提升,提高了程序的鲁棒性,减少了前端白屏率,显著提升了用户体验。
总之,针对业务优化场景中的懒加载失败问题,通过深入分析 webpack 源码,借助 import() 网络重试加载机制,提升了前端工程的稳定性,优化了用户体验,为项目带来了明显收益。
如果你觉得本文对你有所帮助,请在下方点赞支持我,你的「赞」是我创作的动力。
欢迎关注公众号「小李的前端小屋」,我会分享更多前端工作思考与心得,助你成为更好的前端。