Go初体验

背景

我不是程序员,只是偶尔用Python写一些对个人有些帮助的小程序。之前了解过Go,朋友也一直在推荐Go,但一直没有深入研究过,自从面对下面几个事后,就萌生了想尝试一下的想法:

  • 我想用Caddy搭一个简易HTTP Server,一般建议Docker部署,比较方便,但发现macOS如果需要支持Docker,需要装Docker虚拟机,光虚拟机就占了1.5g的内存。后来我去Caddy官网下载了支持ARM架构的Caddy,只有小40m左右,下载即可执行,不需要任何环境,此程序是用Go编译而成的,关于Caddy在macOS的使用,可以看这里
  • Java也是编译语言,可是要想执行,仍然需要Java虚拟机提供运行时环境;类比Python类似,是编译+解释语言,需要Python环境才能进行解释运行;
  • 我需要对多个地址发送ICMP探测报文,Terminal其实挺好用的,只是为了多个地址,需要打开多个窗口,不是很灵活,为了CPU不影响ICMP报文,想找一款支持多核的Ping工具,但发现macOS不像Linux,没有Affinity和Taskset来给进程分配内核,最后找到一个用Go做的开源Ping软件,并支持多线程,但这个运行有些问题,需要排障;

此篇文章简单用实例总结Go的初体验,以及Go程序的排错方法,方便以后复习查阅。

机器环境

System: macOS Monterey 12.1
Arch:   darwin/arm64
Go ver: 1.17.5

安装Go及调试环境

安装

安装很简单,直接去官网 https://go.dev/doc/install 选择相应的版本直接下载安装即可,细节不在此说明了。不过问题是国内网络环境不好,需要科学上网才可以(学习知识也需要科学上网,真的很尴尬 -_- );

安装后,可以通过下面命令来验证Go的版本:

xxx@Yongs-MacBook-Pro ~ % go version
go version go1.17.5 darwin/arm64

配置环境

从10.15.x开始,macOS使用zsh作为默认的shell,所以环境变量需要写到~/.zprofile中,而不是~/.bash_profile,看默认的shell是什么,可以用下面命令:

xxx@Yongs-MacBook-Pro ~ % echo $SHELL
/bin/zsh
  • /bin/zsh => zsh => .zprofile
  • /bin/bash => bash => .bash_profile

所以把Go的环境写到~/.zprofile中,如下:

xxx@Yongs-MacBook-Pro ~ % more .zprofile |grep GO
export GOPATH=/Users/xxx/Documents/go

建立Go的相关目录,其中file下存着Go的程序,src中存着各种module/库:

xxx@Yongs-MacBook-Pro go % tree -L 1
.
├── file
└── src

第一个Go程序

xxx@Yongs-MacBook-Pro first % more first.go 
package main
import "fmt"
func main(){
        fmt.Println("This is my first go program")
}

执行程序可以使用Go run,这个是先编译在执行,但执行完后自动删除编译文件:

xxx@Yongs-MacBook-Pro first % go run first.go 
This is my first go program
xxx@Yongs-MacBook-Pro first % ls
first.go
beihe@Yongs-MacBook-Pro first % pwd
/Users/xxx/Documents/go/file/first

执行程序也可以用Go build,先编译,然后执行编译后的程序:

xxx@Yongs-MacBook-Pro first % go build first.go 
xxx@Yongs-MacBook-Pro first % ls 
total 3784
-rwxr-xr-x  1 beihe  staff  1932642 Jan  7 13:34 first
-rw-r--r--  1 beihe  staff       92 Jan  7 12:16 first.go
xxx@Yongs-MacBook-Pro first % ./first 
This is my first go program

第三方库文件加载

原有程序在这个github:https://github.com/feiyu563/nbping;把源文件copy到本地,然后编译,发现有下面错误:

xxx@Yongs-MacBook-Pro nbping % go build nbping.go 
nbping.go:8:2: no required module provides package golang.org/x/net/icmp: go.mod file not found in current directory or any parent directory; see 'go help modules'
nbping.go:9:2: no required module provides package golang.org/x/net/ipv4: go.mod file not found in current directory or any parent directory; see 'go help modules'
xxx@Yongs-MacBook-Pro ping % more ping.go 
package main

import (
        "bufio"
        "errors"
        "flag"
        "fmt"
        "golang.org/x/net/icmp"
        "golang.org/x/net/ipv4"
        "io/ioutil"
        "math/rand"
        "net"
        "os"
        "strings"
        "time"
)
......

Go的import跟Python基本一样,唯一区别的是在引用第三方库文件时,使用地址的方式,比如上面的golang.org/x/net/icmpgolang.org/x/net/ipv4。Get这些库文件可以使用下面命令,但由于环境问题,需要用代理,常规的基于web的科学上网是不行的,即使把GOPROXY改成.cn的也不行:

xxx@Yongs-MacBook-Pro src % go env -w GOPROXY=https://goproxy.cn,direct
xxx@Yongs-MacBook-Pro src % go env -w GO111MODULE=auto
xxx@Yongs-MacBook-Pro src % go env |grep -E "GO111|cn"
GO111MODULE="auto"
GOPROXY="https://goproxy.cn,direct"
xxx@Yongs-MacBook-Pro src % go get -u golang.org/x/net
package golang.org/x/net: unrecognized import path "golang.org/x/net": https fetch: Get "https://golang.org/x/net?go-get=1": dial tcp 142.251.43.17:443: i/o timeout

有没有不用代理解决此问题的方法?经过查找,可以直接从github(https://github.com/golang/)下载库文件到src目录下,这个github地址就是go做的一个镜像,所以可以无脑用:

xxx@Yongs-MacBook-Pro go % mkdir -p $GOPATH/src/golang.org/x   
xxx@Yongs-MacBook-Pro go % cd $GOPATH/src/golang.org/x
xxx@Yongs-MacBook-Pro x % git clone https://github.com/golang/net.git
Cloning into 'net'...
remote: Enumerating objects: 10910, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 10910 (delta 1), reused 6 (delta 1), pack-reused 10902
Receiving objects: 100% (10910/10910), 8.88 MiB | 808.00 KiB/s, done.
Resolving deltas: 100% (7781/7781), done.
xxx@Yongs-MacBook-Pro x % git clone https://github.com/golang/sys.git
Cloning into 'sys'...
remote: Enumerating objects: 12852, done.
remote: Counting objects: 100% (1322/1322), done.
remote: Compressing objects: 100% (462/462), done.
remote: Total 12852 (delta 998), reused 1044 (delta 858), pack-reused 11530
Receiving objects: 100% (12852/12852), 11.02 MiB | 1.74 MiB/s, done.
Resolving deltas: 100% (10922/10922), done.
xxx@Yongs-MacBook-Pro ping % 
xxx@Yongs-MacBook-Pro ping % go build ping.go
xxx@Yongs-MacBook-Pro go % tree -L 4
.
├── file
│   ├── first
│   │   ├── first
│   │   └── first.go
│   └── ping
│       ├── ping
│       └── ping.go
└── src
    └── golang.org
        └── x
            ├── net
            └── sys

8 directories, 4 files

202406-更新:交叉编译

我在MBP上写了2个程序,编译后转到linux发现执行不了,想了下应该是MBP是ARM架构,编译默认是ARM架构,所以Linux无法执行,那么需要交叉编译,很简单,一条命令即可搞定,秒出:

Frank@Franks-MacBook-Pro all2all % ls -l
total 19504
-rwxr-xr-x  1 Frank staff  2472610 Jun  9 22:12 client
-rw-r--r--@ 1 Frank staff     4776 Jun  9 21:56 client.go
-rw-r--r--@ 1 Frank staff   372172 Jun  9 22:09 client_output.txt
-rw-r--r--@ 1 Frank staff      767 Jun  9 20:22 credentials.txt
-rwxr-xr-x  1 Frank staff  2472610 Jun  9 22:12 server
-rw-r--r--@ 1 Frank staff     4797 Jun  9 21:58 server.go
-rw-r--r--@ 1 Frank staff  1416510 Jun  9 22:06 server_output.txt
-rw-r--r--  1 Frank staff     6448 Jun  9 22:21 temp_ports.txt
Frank@Franks-MacBook-Pro all2all % CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -o client_x86 client.go
Frank@Franks-MacBook-Pro all2all % CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -o server_x86 server.go
Frank@Franks-MacBook-Pro all2all % ls -l
total 24456
-rwxr-xr-x  1 Frank  staff  2472610 Jun  9 22:12 client
-rw-r--r--@ 1 Frank  staff     4776 Jun  9 21:56 client.go
-rw-r--r--@ 1 Frank  staff   372172 Jun  9 22:09 client_output.txt
-rwxr-xr-x  1 Frank  staff  2534697 Jun  9 22:28 client_x86
-rw-r--r--@ 1 Frank  staff      767 Jun  9 20:22 credentials.txt
-rwxr-xr-x  1 Frank  staff  2472610 Jun  9 22:12 server
-rw-r--r--@ 1 Frank  staff     4797 Jun  9 21:58 server.go
-rw-r--r--@ 1 Frank  staff  1416510 Jun  9 22:06 server_output.txt
-rwxr-xr-x  1 Frank  staff  2534545 Jun  9 22:28 server_x86
-rw-r--r--  1 Frank  staff     6448 Jun  9 22:21 temp_ports.txt

下面是linux平台上:

c@tme97:~/frank$ chmod +x server_x86 
c@tme97:~/frank$ chmod +x client_x86
c@tme97:~/frank$ sudo apt-get install sshpass
clounix@tme97:~/frank$ ./server_x86 
2024/06/09 14:38:14 2024-06-09 14:38:14.005981 - Connecting to 10.22.1.69:22
2024/06/09 14:38:14 2024-06-09 14:38:14.005963 - Connecting to 10.22.1.69:22
2024/06/09 14:38:14 2024-06-09 14:38:14.012501 - Connecting to 10.22.1.69:22
2024/06/09 14:38:14 2024-06-09 14:38:14.025972 - Connecting to 10.22.1.8:22

Go程序排障

等待更新……

参考文章

本文出自 Frank's Blog

版权声明:


本文链接:Go初体验
版权声明:本文为原创文章,仅代表个人观点,版权归 Frank Zhao 所有,转载时请注明本文出处及文章链接
你可以留言,或者trackback 从你的网站

留言哦

blonde teen swallows load.xxx videos