【原创】编译 c++ gRPC 时遇到的坑……
由于项目需要,我要基于 gRPC 开发一个通用的 wrapper ,前期已经将服务器侧相关的 gRPC 代码完成了集成,并基于 fake golang client 进行了功能测试,原以为生成 C/C++ gRPC 代码肯定是手到擒来的事情,没想到……居然“编译过程”本身成为了拦路虎。
按照 quickstart 文档的说明,可以使用的编译工具有如下三种
- cmake
- bazel(复杂,较高学习成本,且后续用不到)
- make(不推荐,人家说这个过时了)
既然如此,直接按照 cmake 的要求进行操作即可
# Choose a directory to hold locally installed packages. $ export MY_INSTALL_DIR=$HOME/.local $ mkdir -p $MY_INSTALL_DIR $ export PATH="$MY_INSTALL_DIR/bin:$PATH" # 安装高版本 cmake $ wget -q -O cmake-linux.sh https://github.com/Kitware/CMake/releases/download/v3.19.6/cmake-3.19.6-Linux-x86_64.sh $ sh cmake-linux.sh -- --skip-license --prefix=$MY_INSTALL_DIR $ rm cmake-linux.sh # Install the basic tools required to build gRPC $ sudo apt install -y build-essential autoconf libtool pkg-config
结果……
0x01 困难一:公司网络环境下无法成功将相应内容下载到本地
这个命令其实隐含了很多外网下载内容,正常情况下很难下载完全,dddd
$ git clone --recurse-submodules -b v1.41.0 https://github.com/grpc/grpc
好在,我有国外 vps 可用,下载、打包,回传,一条龙解决问题
0x02 困难二:构建 c++gRPC 过程中对内存有相当高的要求
按照官方文档,只要执行如下命令,就可以得到需要的二进制程序了
# Build and install gRPC and Protocol Buffers $ cd grpc $ mkdir -p cmake/build $ pushd cmake/build $ cmake -DgRPC_INSTALL=ON \ -DgRPC_BUILD_TESTS=OFF \ -DCMAKE_INSTALL_PREFIX=$MY_INSTALL_DIR \ ../.. $ make -j $ make install $ popd
然而,实际执行时,你会发现……一般的机器根本就无法正常执行完成上述命令。
NOTE: 下文给出的是,成功编译过程中内存使用情况的记录(之前失败了无数次,浪费了大量时间)
经过无数次的调整,最终在一台内存资源相对充足(可用内存 30G),并开了 55G 的 swap 的机器上,成功解决了编译过程对内存量的“变态”需求(内存不足,会导致编译过程直接挂掉)
-
初始状态
-
执行
make -j
后,可以发现内存占用开始飙升
-
当系统内存被耗光后,开始靠 swap 抗了……
-
编译进入“巅峰”状态时,总计占用了高达 55G 左右的内存量,而这在一般机器上是很难满足的(当然,在 4G 内存的机器上开 80G 的 swap ,理论上也能满足要求,但你会发现,整个编译过程会“快”的如蜗牛在爬行)
-
编译的后半程,系统内存和 swap 均被逐渐释放
-
最后,恢复到了正常水平
结论:要想成功编译出来 C++ gRPC 相关的东西,对编译机有非常高的要求(注:这里是严格按照官方命令进执行的,可能存在调整了一些参数后,相应要求会变低的可能,但我没有去验证这个猜想)
最后,提供一张由于内存不足,编译过程中被强行杀掉的现场图
0x03 困难三:vbox 虚拟盘大小只增不减问题
这个问题准确来说,是在解决第二个问题时出现的“衍生”问题。
问题是这样的:我的开发环境是在 vbox 虚拟机中创建的,最初分给该虚拟机的内存只有 2G,当我通过 make -j
编译时,很容易就会因为内存不足而被系统杀死,于是我第一时间就想到了通过创建 swap 缓解内存不足问题的手段。在创建了一个 10G 的 swap 分区重新编译后发现,依然会出现内存不足情况,于是继续增加 swap 大小,一路从 10G 调整到了 50G ,之后发现新的问题产生了,这时不再报内存不足的错误,而是 vbox 虚拟机直接挂掉了~~
简单排查后发现,居然是因为 vbox 所属物理机上对应分区的磁盘空间不足了,此时我第一反应是“不应该啊”,之前明明还有50G 左右的空间呢呀~~我靠……难道是……
是的,没错,开了 swap 之后,随着编译的进行,随着虚拟机内部对“内存”的疯狂占用,间接导致了物理机上的磁盘空间被“真实”的用光了
然而,从上面的编译过程来看,编译结束之后,内存占用会被完全释放掉的,那么物理机上被占用的空间能否被释放掉么?
此时,需要补充两个关于 vbox 虚拟机的知识点:
第一,vbox 虚拟盘的设定大小和实际占用大小在最初并不是一致的,而是在实际使用后,按需逐渐增大的
例如,这个由 vbox 默认创建的虚拟盘,“虚拟分配空间”大小为10G,但“实际分配空间”大小为 1.31G
另外一个虚拟盘是我最初规划时就为虚拟机额外挂载的、最大可达 100G 的虚拟盘;当我创建了 50G 的 swap ,并开始编译 c++ gRPC 之后,由于系统内存不足,触发了对 swap 的使用,最终该盘的“实际分配空间”逐渐增大到了 54.59G
第二,vbox 虚拟盘的“实际分配空间大小”只能增加不能减少,这也就意味着,虽然我是为了编译 c++ gRPC 临时分配了 50G 的 swap ,并且事后在虚拟机内部将其完全删除,但在物理机上看,该空间依然存在,且会一直存在了……
针对 vdi 格式的虚拟盘,网上能够找到的“攻略”都是教你如何“增大”的
软件界面上确实也直接告之了“存储空间缩减的功能尚未实现”
尝试了下“增大”功能,确实可以
最后,还剩下一个问题,由于“只增不减”的缘故,vbox 虚拟盘已经将我的 xx 盘几乎撑爆 ,仅剩下可怜的几十M空间,这个问题也得解决,要不然影响后续使用
常规操作,“复制粘贴”大法走起,确实解决了磁盘空间问题,但搬移后发现,虚拟机启动直接报错,大致意思是“找不到盘了”,嗯,合理,毕竟被移动了
于是,将原来挂的盘片删掉
再将搬移到新位置的盘片挂上……结果,又报错了,错误类似下图(原图当时没截取)
大致意思是,新挂上去的虚拟盘的 UUID 和原来已经注册过的虚拟盘的 UUID 相同,不允许挂;
具体解决办法可以参考如下链接文章,这里就不赘述了:
-
https://www.vdiskrecovery.com/blog/fix-virtualbox-cannot-register-hard-disk/
-
https://www.wintips.org/fix-virtualbox-failed-to-open-hard-disk-file-cannot-register-virtual-hard-disk-because-a-disk-with-the-same-uuid-already-exists/
最后的最后,终于成功的挂上了盘,终于再次成功的启动了我的开发机……
OK, 到这里,我只是解决了编译环境问题,真正的 c++ gRPC 代码的开发调试,还没开始呢……
PS:本文敏感字如下,呵呵
更多精彩内容,欢迎关注我个人微信公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
深度换脸、加密货币和移动钱包:网络犯罪分子在 2022 年发现新机会
Check Point®软件技术公司发布了其 2022 年网络安全预测,详细说明了企业在未来一年将面临的主要安全挑战。在网络犯罪分子继续利用新冠疫情影响的同时,他们还将从深度换脸、加密货币、移动钱包等方面寻找新的攻击机会。 2022 年全球网络安全预测报告的主要亮点包括: 虚拟新闻和谣言卷土重来:在整个 2021 年,有关新冠疫情和疫苗接种的谣言大肆传播。2022 年,不法分子仍将继续利用假新闻来实施各种网络钓鱼攻击和诈骗。 供应链网络攻击继续增加:供应链攻击将变得更加普遍,政府将开始制定法规来应对这些攻击和保护网络,并与私营部门和其他国家合作,在全球范围内识别和打击更多的威胁团体。 数据泄露的规模更大,代价更高:数据泄露将更频繁地发生,规模更大,企业和政府的恢复成本将会更高。2021 年 5 月,美国保险巨头向黑客支付了 4,000 万美元的赎金。这创下了新高,我们可以预见,在 2022 年,攻击者要求的赎金还会增加。 加密货币获得攻击者的青睐:当金钱变成纯粹的软件时,为防止黑客窃取和操纵比特币和另类货币,所需的网络安全肯定会发生意想不到的变化。 攻击者瞄准移动设备:随着移动钱包和移...
- 下一篇
长文捋明白 Spring 事务!隔离性?传播性?一网打尽!
@[toc] 事务的重要性不言而喻,Spring 对事务也提供了非常丰富的支持,各种支持的属性应有尽有。 然而很多小伙伴知道,这里有两个属性特别绕: 隔离性 传播性 有多绕呢?松哥都一直懒得写文章去总结。不过最近有小伙伴问到这个问题,刚好有空,就抽空总结一下,我不会干巴巴的和大家讲概念,接下来的所有内容,松哥都会通过具体的案例来和大家演示。 好啦,不废话啦,请看大屏幕。 1. 什么是事务 数据库事务是指作为单个逻辑工作单元执行的一系列操作,这些操作要么一起成功,要么一起失败,是一个不可分割的工作单元。 在我们日常工作中,涉及到事务的场景非常多,一个 service 中往往需要调用不同的 dao 层方法,这些方法要么同时成功要么同时失败,我们需要在 service 层确保这一点。 说到事务最典型的案例就是转账了: > 张三要给李四转账 500 块钱,这里涉及到两个操作,从张三的账户上减去 500 块钱,给李四的账户添加 500 块钱,这两个操作要么同时成功要么同时失败,如何确保他们同时成功或者同时失败呢?答案就是事务。 事务有四大特性(ACID): 原子性(Atomicity): ...
相关文章
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS8编译安装MySQL8.0.19
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- MySQL8.0.19开启GTID主从同步CentOS8
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Red5直播服务器,属于Java语言的直播服务器