首页 > 其他分享 >2023 的一些总结

2023 的一些总结

时间:2024-01-23 23:33:07浏览次数:27  
标签:总结 goroutine logrus 2023 chan 使用 netns 一些 日志

2023 的一些总结

李宗盛在山丘开头里面写道,"想说却还没说的 还很多 攒着是因为想写成歌"。

同样的,在印象中在 2023 好像做了很多东西,接触了很多技术,但是一直没有整理,攒着攒着就到年底了。

细细思考了一下,有两个板块是今年主要发力的点

  1. 对网络的探索
  2. 对业务代码优化的思考

对网络的探索

整个过程围绕着一个主题 “如何在一个机器内构建一个虚拟 VXLAN/VLAN 网络”。

netns

netns 是其中最关键的技术,使用非常简单,主要用来解决隔离问题

  1. VXLAN 的不同 VNI 的相同 IP 不能够进行区分,只能够使用 netns 进行隔离
  2. rp_filter/路由之类问题,很容易就造成丢包

如果网络被隔离了,意味被模块化分,管理起来也更简单,排查问题也更简单

  1. tcpdump 在 netns 内只能看到进入 netns 的流量,减少和各种流量斗智斗勇的时间
  2. iptables/ipset 在 4.x 以上的内核版本也完整支持(ipset 在 3.10 内核未进行隔离)

再结合 veth-peer/bridge,将 物理网卡(也可以是其它虚拟网卡) 和 veth-peer 同时挂在 bridge 上,这样 netns 和外界网络就连接起来了。

如果有两个物理网卡,分别挂在不同网桥上,并且物理网卡都没有配置 IP 只在连接的 netns 内配置 IP,那么这两个物理网卡就被完全隔离了,对于一个机器连接不同的物理网络是一个非常好的方案。

延伸

如何在所有的 netns 内监听端口

  1. 最简单粗暴,在 netns 内启动一个进程监听端口,再把流量通过 UNIX SOCKET 代理出来
  2. 将线程切换至 netns 内,然后进行端口监听,线程的消耗总是要比进程要小的,至少启动速度是要快的,那就保持数量比 netns:thread = 1:1
  3. 只绑定 sockfd 至 netns 中,常数个线程来监听所有 netns 内的端口

方案3是前两天才发现的,在 stackoverflow 上看到有人 setns 后直接 listen,然后继续 setne listen,这样只用了一个线程同时在两个命名空间内进行监听,在本地用 python 代码验证的确如此;方案二中的一个线程的内存占用大概在 2M 左右,并且在数量多的情况下退出也比较费时,方案3胜出

有两个场景可以使用这个方案

  1. 在虚拟网络的前提下,虚拟端口进行欺骗访问,类似 portspoof
  2. 对容器流量进行劫持分析,在容器内使用 iptables nat 将符合条件的流量代理到固定端口中,在服务内进行分析完成后再代理回原有的端口上

修改 flannel

年初有一个需求,跨设备使用 VXLAN 打通虚拟机(只有内部 IP)网络,当时对 flannel 进行修改,不再使用 etcd 转而对接内部的服务。
当时还有另外一种方案是使用 主机路由,同样 flannel 也支持,不过想到如果后面还要打通虚拟机内部的容器网络,那么使用双层 VXLAN 就是一种非常自然的手段了。
有一点遗憾的是,其实 flannel 完全可以不修改,而是直接拿 backend 的 vxlan 代码合并至内部服务内,从软件工程的角度 “非必要不增加实体”,这也就成为了一部分技术债了。

选择 frr

在 flannel 之前 VXLAN 的网络打通都是基于点对点的方案,不能动态的管理寻址信息,不过 flannel 同样不能应用在这里,因为数据中心的 VXLAN 网络并不是 etcd 为中心,数据中心通用使用 BGP 协议来进行路由协议的交互,故 frr 被选中。

不使用 frr 的情况下,写入 FDB 也可以达到一个动态路由的过程的,当然写入 FDB 这个过程就不动态(适用于替换 flannel)

构建网络场景

对于 VXLAN 来说,将 VTEP 和 veth-peer 挂在 bridge 上,veth-peer 另外一段在命名空间内

对于 VLAN 来说,直接将 物理网卡 和 veth-peer 挂在 bridge 上,veth-peer 另一段在命名空间内,命名空间内的默认路由自定义配置就行

对业务代码优化的思考

日志

第一个就是日志,非常认同戈君对日志的打印的看法,使用结构化的日志,在 Go 里面使用 logrus 即可,不必在乎性能,真有性能瓶颈再考虑日志打印的代码是否需要调整。

对于 logrus 所有的变量只应该出现在 logrus.WithFied(s) 中,logrus.Info 一定是字面量的字符串。

日志尽量不要转移字符串,不然像一些 json 的字符串,复制出来没办法直接格式化。

对于一些命令执行的逻辑,要提供日志输出的 Option(Option 的设计可以单独展开),比如 debug 打开,不然有一些命令执行错了就陷入一个抓瞎的过程,排查很浪费时间。

启动/停止的关键路径应该有日志,整个服务的运作路径可以清晰通过日志了解,并且这部分日志多一些也不会有问题,毕竟只会执行一次。

必要时,可以日志可以对业务进行分日志文件

控制流

启动/停止

对于一个后台服务来说,启动逻辑应该被阻塞,如同 http.Serve,优先传递 context 而不是 chan,
context 处理有几个好处

  1. 传递value
  2. 传递取消,context 可以取消所有的子树 context
  3. 可以重复 cancel,可以在一些具有主动暂停和执行完成的地方,代码写起来简单一些

退出的逻辑应该是单独的一个 goroutine 中,等待接受信号或者其它逻辑,一旦满足条件,cancel 启动逻辑的 context,然后所有的处理模块自然退出。

尽量不要出现在退出函数里面等待运行函数中关闭/写入 chan,因为一旦运行函数失败了,外部没有判断错误的情况(很常见,因为有一些代码不影响运行),chan 不会再被写入/关闭,那么久死锁了。

同理,命令的执行尽量使用封装 exec.CommandContext 进行使用,有一些命令运行时间很长,那么可以通过 context 来取消执行。

可调试性工具

将内部的一些状态通过网络进行 request/response 输出,这样一些排查问题时需要的数据直接通过请求就能拿到,不再需要去打日志,适用场景

  1. 热点路径的统计数据
  2. 内存中的动态数据,规模较大,不适直接在日志中输出

将服务的功能命令行化,不再依赖其它服务的数据输入,总体也能提高服务的灵活性

并发控制

通过 chan 来完成 goroutine 间的数据及控制传递,由生产端gorouting关闭 chan,消费端goroutine 对 chan 进行 for-range 阻塞,这样单个 chan 就可以同时起到既传输数据和控制 goroutine 的作用。

整个生产-消费的过程一定是生产端 goroutine 关闭 chan,然后消费端 goroutine 自然退出。

同样可以使用 goroutine+chan 的组合来控制生产端的 goroutine 数量,一个比较简单的做法就是保持 chan 的大小和生产端的 goroutine 的数量相等

其它

探索 C++ 编译期构造字符串的方案

想像 Go 的 logrus 那样结构化输出日志,又不想损失性能;最后基于 C++17 可以达到 logrus.WithFields(logrus.WithField{"k", v}, logrus.WithField{"k2", v2})::Info 的效果;

了解如何使用 libevent

对于库中间碰到一个坑,libevent 每次从 fd 中读取字节数最大为 4096 字节,然后网上的人都是把 4096 调大再编译使用;
其实合理的方式为增加一个数据包头,来存当前数据包的大小,结合 watermask 使用即可。

了解 cmake/xmake 的使用

xmake 使用还比较简单,挺好用的,但是在公司推广不开,而且有一个问题在构建 libmnl 的时候,会找不到库,问题只在已经安装过 libmnl-dev 的环境中出现。

后面转而使用到 cmake,结合 add_subdirectory 和 ExternalProject_Add 对三方库进行混合构建。

基于 Dockerfile 的构建环境

对于一些修改过源码的三方代码,不应该在普通的服务器之内进行编译,而基于 Dockerfile

  1. 对于构建的指令,依赖都有备份
  2. 防止构建机器被污染

捐赠了一波博客园

既然和技术相关,那么我觉得这个也算

总结

成长性主要集中在网络的方面,由于和网络打交道,C++ 也涉及了一些,但是无论是语言还是网络技术,总体还是比较肤浅,如果不总结一下是感受不出来的。

对一些源码层面的东西看到少一些,更多的关注了怎么使用,怎么好用,怎么好维护的场景;今年技术迷惘的时间比较少,利用业务驱动了更多技术发展。

缺乏一些交流。

收个尾

  • C++ 的 logrus 库完善一下,写一个文章
  • Golang 的一些工程化优化,也梳理一下
  • libevent xmake 等东西也放一下出来,给互联网一些原创的东西

规划一下

  • netns 这种东西应该继续往下再深挖一下,阅读一下源码,看看如果结合 ebpf 能够怎么进行优化
  • 提升一下行动力,争取两个月有一篇文章产出,临时的想法也行

标签:总结,goroutine,logrus,2023,chan,使用,netns,一些,日志
From: https://www.cnblogs.com/shuqin/p/17983667

相关文章

  • 痞子衡嵌入式:我拿到了2023年度电子星球(eestar)年度黑马作者
    今天收到了「电源网旗下电子星球」颁发的2023年度黑马作者奖牌,这是痞子衡继2019年和与非网合作后的第二个媒体平台颁发的奖项。这个奖牌做得很有质感,拿在手里沉甸甸的。此外与奖牌配套的还有一本精选作者们的文章合辑而成的VIP技术年刊,仪式感直接拉满了。与电子星球的缘分......
  • SQL的一些通用语句-数据库和表的创建、删除、查询
    SQL的一些通用语句DDL(数据定义语言)-数据库操作查询查询所有数据库SHOWDATABASES;查询当前数据库SELECTDATABASE();创建CREATEDATABASE[IFNOTEXISTS]数据库名[DEFAULTCHARSET字符集][COLLATE排序规则];[IFNOTEXISTS]为可选项[DEFAULTCHARSET字......
  • 今日总结
    统计男女人数,并分别计算出男性和女性的最高和最低身高,数据格式“序号M/F身高” //生成性别身高数据,格式“序号性别(M/F)身高”privatestaticvoidmakeHeightData()throwsIOException{FilenewFile=newFile("src/main/files/heightData.txt");......
  • 项目总结
    时间片轮询:结构体封装每个任务的时间片(也就是执行间隔),计数器,函数指针。采用定时器计时。比如说任务1每2s执行一次,任务2每5s执行一次,定时器每1s产生中断,定时时间一到每个任务的计数器就加1,当计数器和时间片相等时执行该任务。任务冲突:将每个任务对应的结构体装入结构体数组,采用遍......
  • nuxt3:http请求时需要注意得一些地方
    前言nuxt3中获取后端数据总共有三个方法:useFetch()$fetch()useAsynData()本篇教程就针对这三个方法的使用注意事项做一个记录正文通过useFetch()方法请求这个动作,在首次加载时,只在服务端执行一次,客户端是不执行得,客户端是直接使用拿到的数据地;如果和SEO无关得数据,优先......
  • 2024.01 总结
    1.模拟赛总的来说状态较好,只有一次较大的挂分。1-1.优点:思维方面:能够推出DP式子,通过打表找到一些规律。码力方面:基础的数据结构实现很少出错。策略方面:先把自己能拿的分拿满。1-2.缺点:思维方面:推出式子不会优化。码力方面:难以实现复杂的数据结构和代码。......
  • 每日总结(python文本分析)
    导入文本文档并输出在终端#Python3.x版本importos#获取根目录下文件的绝对路径root_path="./"file_path=os.path.join(root_path,'pinglun.txt')try:#打开文本文件并读取所有内容withopen(file_path,'r',encoding='utf-8')asfile:......
  • 高效又稳定的ChatGPT大模型训练技巧总结,让训练事半功倍!
    高效又稳定的ChatGPT大模型训练技巧总结,让训练事半功倍!前言近期,ChatGPT成为了全网热议的话题。ChatGPT是一种基于大规模语言模型技术(LLM,largelanguagemodel)实现的人机对话工具。现在主流的大规模语言模型都采用Transformer网络,通过极大规模的数据进行自监督训练。但是,......
  • 2023 年度龙蜥最佳用户案例奖揭晓,中国移动、小红书、中国人寿财险等企业上榜!
    近日,在2023龙蜥操作系统大会上,龙蜥社区公布了2023年度最佳用户案例获奖企业名单,龙蜥社区副理事长张东、理事李祥凯为中国移动、小红书、中国人寿财险等13家获奖企业颁奖。本次获奖企业是从使用龙蜥操作系统社区版(AnolisOS)或商业版/衍生版的企业用户中进行评选,涵盖政务、互联......
  • mysqlbinlog~导出sql总结
    mysqlbinlog是MySQL数据库中的一个实用程序,它用于处理二进制日志文件(也称为“binlogs”)。这些文件包含了在MySQL服务器上发生的所有更改和操作的信息。mysqlbinlog工具可以帮助你查看、分析或者应用这些日志。基础介绍下面是一些关于mysqlbinlog的基本介绍:功能查看二进制日志......