一次解决Go编译问题的经过

news/2024/12/21 23:41:27/

图片

用Go语言编写了一个小的项目,项目开发环境是在本地的Windows环境中,一切单元测试和集成测试通过后,计划将项目部署到VPS服务器上自动运行,但在服务器上执行go run运行时,程序没有任何响应和回显,甚至main函数一开始的fmt.Println()都没有任何输出。

出现两个环境相同程序执行结果的不同,无外乎两类问题:配置问题和环境问题。

首先,检查了两个环境的Go语言配置和模块配置区别,包括Go语言版本差异(本地是1.22.4版本,服务器是1.23.0版本),并通过go clean -modcache和go mod tidy重新拉取了涉及的模块,发现问题依然存在。

其次,将程序中的几个单元测试文件单独执行,go test -v命令并没有任何输出,这意味着单元测试文件执行时候也有同样的问题,起初怀疑是和模块引用路径或程序中的路径或程序在Linux下的权限设置相关,但单元测试执行的问题排除了模块引用和路径问题,问题指向程序中数据库操作相关的函数。

因此,将主程序分步注释和执行,确定导致程序无响应的代码块,最终发现问题的根本在于:

import modernc.org/sqlite

这是一个操作SQLite数据库的第三方模块,是用Go语言编写,理论上是不存在环境兼容问题的。要查清楚问题的原因,需要单独编写一个程序验证该模块的问题,新的验证程序只引入了这个模块:

package mainimport ("fmt"_ "modernc.org/sqlite"
)func main() {fmt.Println("This is a test for sqlite")
}

通过go run单独执行该测试程序也出现相同现象,接下来通过go build-v手动编译检查模块引入过程中的问题,过程显示:

modernc.org/sqlite/lib: /usr/local/go/pkg/tool/linux_amd64/compile: signal: killed

编译过程到此结束,意味着sqlite模块在编译过程中编译进程被杀死,导致后续程序均无法执行,结合htop工具检查下编译过程中编译进程和系统资源的情况:

图片

进一步再用dmesg | grep -i ‘killed’,发现是由于Out of memory问题导致进程被杀死,和上图中的内存使用情况吻合(内存和Swap都满了),毕竟VPS服务器的内存有限,只有500Mb,Swap也只有265Mb。

问题的原因确定后,对应的解决思路就有两种:要么增加内存,要么在其他环境编译后移植可执行文件。

增加内存

由于内存本身有限,增加内存只能通过增加Swap解决,即在现有的/swap文件之外设置一个新的swap文件,并将新文件设置为新的swap。命令如下:

falloate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

另外,通过编辑/etc/fstab文件和添加下面命令,将新swap文件设置为系统启动时候自动加载的swap文件:

/swapfile swap swap defaults 0 0

完成以上配置之后,重新在测试代码目录下执行go build -v便可以完成编译过程,经过htop对于资源利用的观测,实际编译modernc.org/sqlite至少需要1G的内存。

交叉编译

交叉编译是在Windows系统上编译Linux系统运行的可执行文件,这样可以利用Windows系统的性能完成编译工作,直接在Linux系统上运行可执行文件。

进行交叉编译需要设定Go语言的环境变量GOOS和GOARCH,前者是系统类型,比如windows、linux,后者是架构类型,比如amd64、arm。笔者使用的两个环境都是amd64的64位系统,因此只需要设置系统类型:

go env -w GOOS=linux

之后再执行go build创建可执行文件,最后将可执行文件上传到VPS服务器执行即可。

洞源实验室
安全工程师:裴伟伟
2024 年 10 月 4 日 


http://www.ppmy.cn/news/1534636.html

相关文章

linux第二课:常用命令

Kali Linux,黑客必备神器。跟着我,带你从入门到入狱! 第二课,常用命令。 1.whoami 翻译为中文:我是谁 用途:输出现在自己的用户身份(用户名) 参数:无参数 好吧,这透明度一调都不…

springboot项目配置部分依赖从私服拉取,部分从阿里云拉取

在Java项目中,配置部分依赖从私服拉取,部分从阿里云拉取,可以在Maven的配置文件settings.xml中设置多个镜像,Maven会根据镜像的顺序尝试下载依赖。 ‌配置私服镜像‌:首先配置你的私服镜像,例如Nexus私服&…

Linux学习笔记(五):shell脚本,强大的文本处理工具awk,sed

Linux学习笔记(五):shell脚本,awk,sed,服务管理 1. Shell 脚本 Shell 脚本是一种使用 Shell 编写的脚本,它可以在 Linux 系统中执行各种任务。 1.1 变量 声明变量: 使用 export 命令…

828华为云征文|部署敏捷项目管理系统工具 ZenTao

828华为云征文|部署敏捷项目管理系统工具 ZenTao 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 ZenTao3.1 ZenTao 介绍3.2 ZenTao 部署3.3 ZenTao 使用 四、总…

如何保护自己电脑以及服务器的ip地址

保护你的电脑和服务器的IP地址,可以采取以下措施: 1. 使用代理服务器 HTTP/HTTPS代理:通过代理服务器访问网络,隐藏真实IP地址。SOCKS代理:提供更高级的网络流量转发,可以更好地处理各种网络协议。 2. 配…

Spring(学习笔记)

<context:annotation-config/>是 Spring 配置文件中的一个标签&#xff0c;用于开启注解配置功能。这个标签可以让 Spring 容器识别并处理使用注解定义的 bean。例如&#xff0c;可以使用 Autowired 注解自动装配 bean&#xff0c;或者使用 Component 注解将类标记为 bea…

掌握 C# 中的 LINQ(语言集成查询)

LINQ&#xff08;Language Integrated Query&#xff0c;语言集成查询&#xff09;是 C# 中的一项强大功能&#xff0c;它使得我们能够使用查询语法处理不同的数据源&#xff0c;如对象、XML、数据库等。LINQ 通过提供统一的查询语法&#xff0c;使开发者能够更加简洁、高效地操…

1G,2G,3G,4G,5G各代通信技术的关键技术,联系和区别

目录 1G2G3G4G5G各代通信技术的联系和区别联系区别 1G 1G的主要特点是无线移动化。关键技术为蜂窝组网&#xff0c;支持频率复用和移动切换&#xff0c;可以实现个人和个人移动状态下不间断的语音通信。 1G通信系统现已关闭&#xff0c;其主要缺点是串好和盗号。 2G 数字化…