嵌入式linux之go语言开发(一)环境搭建

简介: 嵌入式linux之go语言开发(一)环境搭建

go语音被称作互联网时代的"c" 。简单和高效率,用在嵌入式上也是非常合适的。应该做一个大胆的尝试......



意义何在? 现在的设备都在朝着物联网,智能化方面发展,已不是传统的单片机控制就能完成的简单的功能,


普遍带有更高级的操作系统,比如linux和Android.而Android上开发可以使用高级语言java,或者如reaect native的html5混合开发。


但是嵌入式linux上目前还是单纯的c语言开发,涉及到网络https,json格式通信,用c去处理起来开发效率太低。还要用c去拼接字符串?而go语言的强大和高效率,正好满足这方面的要求。在这方面做个尝试,看能否带来开发效率和稳定性方面的提升,


同时也是一种学习,探索,创新的过程......


一、环境搭建:


嵌入式机器环境Imx6 ARM, ARM Cortex-A7 内核


虚拟机环境ubutu14.04 64位


先下载go1.4的源码,因为自go1.4版本之后的go版本编译器都是go写的,用go自己编译自己的,go1.4是最后一个用gcc来编译的版本。


下载链接:https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz


go1.4-bootstrap-20171003.tar.gz


编译go1.4:


编译也很简单,


tar -zxvf go1.4-bootstrap-20171003.tar.gz -C /home/yang/go1.4/


cd /home/yang/go1.4/go/src


GOOS=linux GOARCH=amd64 ./make.bash


编译完后,自动在源码所在目录里生成了bin文件夹,里面带编译好的 go命令二进制文件


要想接下来编译最新的源码使用,需把它先添加到系统的环境变量里


在/home/yang目录里有个隐藏文件 .bashrc,打开它配置环境变量


export GOROOT_BOOTSTRAP=/home/yang/go1.4/go


以下是我的环境变量的设置:


export GOROOT_BOOTSTRAP= /home/yang/go1.4/go


编译新版本Go(ARM):


上面完成Go1.4的编译之后,可以利用Go1.4来编译新版本的Go


我下载的最新的go源码是go1.11版本的。


下载链接:


https://dl.google.com/go/go1.11.src.tar.gz


为了使编译出来的最新的go支持arm,支持cgo,


CC_FOR_TARGET 和 CXX_FOR_TARGET这两个配置项也必须要配置


export CC_FOR_TARGET=/home/yang/b503/ctools/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf-gcc
export CXX_FOR_TARGET=/home/yang/b503/ctools/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf-g++
tar -zxvf go1.11.src.tar.gz
cd go1.11/src
# 开启CGO编译
CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 ./make.bash
# 关闭CGO编译
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 ./make.bash


最好开启CGO_ENABLED,因为嵌入式涉及和C的相互调用。我这里也选择了开启。


当选择开启CGO编译时必须配置CC_FOR_TARGET和CXX_FOR_TARGET两个环境变量


注意若遇到arm-...gcc不识别提示找不到文件,则可能是工具链是32位,而系统为64位的原因。需安装32位的兼容库,


//安装32位兼容
apt-get install lib32ncurses5
apt-get install lib32z1
apt install lib32stdc++6-4.8-dbg
sudo apt-get install lib32stdc++6


若这个下不到这个包,看下系统的镜像源是否是国内的,不是就换下Ubutu的镜像源.


无法找到libz.so.1,需安装   sudo apt-get install lib32z1


ubuntu更改镜像源


备份Ubuntu默认的源地址

sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup


//阿里源


deb http://mirrors.aliyun.com/ubuntu/ xenial main
deb-src http://mirrors.aliyun.com/ubuntu/ xenial main
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main
deb http://mirrors.aliyun.com/ubuntu/ xenial universe
deb-src http://mirrors.aliyun.com/ubuntu/ xenial universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-security main
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main
deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security universe


//网易源


deb http://mirrors.163.com/ubuntu/ wily main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ wily-security main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ wily-updates main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ wily-proposed main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ wily-backports main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ wily main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ wily-security main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ wily-updates main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ wily-proposed main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ wily-backports main restricted universe multiverse


//清华源


deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial-security main restricted universe multiverse


=====================



#阿里源


deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse


#网易源


deb http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse


更新源


sudo apt-get update


复损坏的软件包,尝试卸载出错的包,重新安装正确版本的。


sudo apt-get -f install


更新软件


sudo apt-get upgrade


go build bootstrap/cmd/compile/internal/ssa: /root/go1.4/pkg/tool/linux_amd64/6g: signal: killed
go tool dist: FAILED: /root/go1.4/bin/go install -gcflags=-l -tags=math_big_pure_go compiler_bootstrap bootstrap/cmd/...: exit status 1


则是因为系统内存不足,至少需要1G的内存类构建包


是虚拟机的内存不足,需要1G以上内存..


经过编译之后go1.11/go目录下会生成arm和amd64两个平台的Go命令和依赖包,所以这个版本编译的Go命令可以进行两个平台的Go应用程序开发。


先设置好环境变量:


export CC_FOR_TARGET=/home/yang/b503/ctools/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf-gcc
export CXX_FOR_TARGET=/home/yang/b503/ctools/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf-g++
export GOROOT=/home/yang/go1.11/go
export GOBIN=$GOROOT/bin
export GOPATH=/home/yang/gopath
export PATH=$PATH:$GOBIN:GOPATH/bin


source .bashrc后生效


测试下:


验证Go版本


go version


# 正常情况会输出如下内容


go version go1.11 linux/amd64


编译Helloworld程序


新建test.go


package main
import "fmt"
func main() {
    fmt.Println("Hello world")
}


编译电脑上的应用程序使用:


go build test.go


编译ARM版本应用程序使用:


GOOS=linux GOARCH=arm GOARM=7 go build test.go


可把编译好的test二进制文件放到开发板上验证


root@b503_lcd:/app/city_app/opt# chmod +x test2
root@b503_lcd:/app/city_app/opt# ./test2
Hello c...Go
DES test...
96d0028878d58c89
3132333435363738


至此,已完成了环境搭建和简单的helloworld.


//============================================================


如果你的终端机器环境跟我的不一样,同样都是ARM,但是,例如是arm核arm926ej-s,不支持硬浮点运算。


按照上述编译后到板子上运行,可能出现Illegal instruction的错误导致无法运行。


那么,下面一点是需要注意的:


参见链接:


https://blog.csdn.net/qq531456898/article/details/80095707


https://blog.csdn.net/qq531456898/article/details/80095707


https://holmesian.org/golang-cross-compile


$CGO_ENABLED:0表示关闭CGO


$GOOS:目标平台(编译后要运行的目标平台)的操作系统(darwin、freebsd、linux、windows)


$GOARCH:目标平台(编译后要运行的目标平台)的体系架构(386、amd64、arm)分别对应(32位、64位、ARM平台)的架构


例如树莓派属于ARM平台,对于编译给ARM使用的Go程序,需要根据实际情况配置$GOARM,这是用来控制CPU的浮点协处理器的参数。$GOARM默认是6,对于不支持VFP使用软件运算的老版本ARM平台要设置成5,支持VFPv1的设置成6,支持VFPv3的设置成7,详细说明如下:


GOARM=5: use software floating point; when CPU doesn't have VFP co-processor
GOARM=6: use VFPv1 only; default if cross compiling; usually ARM11 or better cores (VFPv2 or better is also supported)
GOARM=7: use VFPv3; usually Cortex-A cores


综上,给跑着linux的老版本树莓派编译Go程序的命令为:


    GOOS=linux GOARCH=arm GOARM=5 go build main.go


关于协处理器


协处理器是协助CPU完成其无法执行或执行效率、效果低下的处理工作而开发和应用的处理器。


这种CPU无法执行的专项工作有很多,比如设备间的信号传输、接入设备的管理等;执行效率、效果低下的有图形处理、声频处理等。为了进行这些专项处理,各种辅助处理器就诞生了。现在的计算机构架(x86、amd64)中,整数运算器与浮点运算器已经集成在一起,一般来讲因此浮点处理器内建于CPU中的协处理器,不算是辅助处理器,不过ARM架构因为低功耗的原因是个例外。


ARM架构中的VFP coprocessor是典型的协处理器,它提供浮点数基本运算(加、减、乘、除、开方、比较、取反)以及向量(vectors)功能,一般来讲,VFP可以同时支持最多8组单精度4组双精度浮点数的运算。


简单地说,使用协处理器可以提升某一方面的性能,可以粗暴地认为是一种硬件加速。


//=============================================================================


已测试验证成功的板子如:


周立功EasyARM imax283A,采用Freescale ARM9 i.MX28


周立功EPC-6G2C-L 采用 Freescale 的 PCIMX6G2C 处理器(基于 ARM Cortex-A7 内核)


新唐 NUC970 CPU,32bit ARM926EJ-S(这个就得指定GOARM=5,使用软浮点,交叉编译指令例子:GOOS=linux GOARCH=arm GOARM=5 go build main.go,若在电脑上执行,则可以直接go run main.go或者go build main.go

。同样的代码,这样既可以在电脑上仿真执行,又可以交叉编译到板子上跑,是不是很赞!)


以下展示一个小demo.


go语言访问银联签到demo:




package main
import (
  "flag"
  "fmt"
  log "github.com/jeanphorn/log4go"
  "github.com/larspensjo/config"
  "go8583/byteutil"
  "go8583/netutil"
  "go8583/up8583"
  "os"
  "strconv"
)
var (
  conFile        = flag.String("configfile", "/config.ini", "config file")
  Server  string = "127.0.0.1"
  Port    int    = 5050
  up *up8583.Up8583
  cardvailddata string
  cardholdsn    string
  cardbin       string
)
func checkErr(err error) {
  if err != nil {
    fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
  }
}
func configUP() {
  //获取当前路径
  file, _ := os.Getwd()
  cfg, err := config.ReadDefault(file + *conFile)
  checkErr(err)
  //获取配置文件中的配置项
  Server, err = cfg.String("SERVERCONFIG", "Server")
  Port, err = cfg.Int("SERVERCONFIG", "Port")
  log.Info("Server:%s\n", Server)
  log.Info("Port:%d\n", Port)
  up8583.ManNum, _ = cfg.String("UPCONFIG", "ManNum")
  up8583.PosNum, _ = cfg.String("UPCONFIG", "PosNum")
  up8583.MainKey, _ = cfg.String("UPCONFIG", "MainKey")
  up8583.TPDU, _ = cfg.String("UPCONFIG", "TPDU")
  up8583.RecSn, _ = cfg.Int("RECCONFIG", "RecSn") //记录流水
  up = up8583.NewUp8583()
}
/*
签到处理过程
*/
func QdProc() error {
  log.Info("connect:server=%s,port=%d\n", Server, Port)
  conn, err := netutil.Connect(Server, Port)
  if err == nil {
    log.Info("connect ok!")
  } else {
    log.Info("connect failed!")
    return err
  }
  defer netutil.DisConnect(conn)
  up.Frame8583QD()
  up.Ea.PrintFields(up.Ea.Field_S)
  _, err = netutil.TxData(conn, up.Ea.Txbuf)
  if err == nil {
    log.Info("send ok!")
  }
  rxbuf := make([]byte, 1024)
  rxlen := 0
  rxlen, err = netutil.RxData(conn, rxbuf)
  if err == nil {
    log.Info("recv ok!len=%d\n", rxlen)
    err = up.Ans8583QD(rxbuf, rxlen)
    if err == nil {
      log.Info("签到成功")
    } else {
      log.Info("签到失败")
      log.Info(err)
    }
  }
  return err
}
/*
银联二维码交易
*/
func QrcodeProc() error {
  log.Info("connect:server=%s,port=%d\n", Server, Port)
  conn, err := netutil.Connect(Server, Port)
  if err == nil {
    log.Info("connect ok!")
  } else {
    log.Info("connect failed!")
    return err
  }
  defer netutil.DisConnect(conn)
  up.Frame8583Qrcode("6220485073630469936", 1)
  up.Ea.PrintFields(up.Ea.Field_S)
  _, err = netutil.TxData(conn, up.Ea.Txbuf)
  if err == nil {
    log.Info("send ok!")
  }
  rxbuf := make([]byte, 1024)
  rxlen := 0
  rxlen, err = netutil.RxData(conn, rxbuf)
  if err == nil {
    log.Info("recv ok!len=%d\n", rxlen)
    up.Ea.Ans8583Fields(rxbuf, rxlen)
    up.Ea.PrintFields(up.Ea.Field_R)
  }
  return err
}
/*
银联电子现金交易
*/
//获取55域 IC卡数据域
/*
9F26 08
9F27 01
9F10
9F37 04
9F36 02
95 05
9A 03
9C 01
9F02 06
5F2A 02
82 02
9F1A 02
9F03 06
9F33 03
9F1E 08
84
9F09 02
9F41 04
9F34 03
9F35 01
9F63 10
9F74 06
8A 02
*/
func getField55() []byte {
  //st := "0000000049c6f6c135bbf05b250000000001900000000000000000000000015601560051406e677c00056013071e0103900000010a010000001580b69553a06013827504000384486d25032240e0e1c80f250300021030313034353530300000000000006000064543433030310a60138275040000"
  st := "000000005238a6937524c97df200000000019000000000000000000000000156015600263b4f5a7c0002d413071e0103900000010a010000006615bbd6d9706013827504000743301d260522408008c00f260500021030313034353530300000000000006000064543433030310a60138275040000"
  //money := "190" //1.9元
  //cardbin := "601382750400038"
  l := 0
  s := ""
  l += 5 * 2
  s += "9F2608"
  s += st[l : l+8*2]
  l += 8 * 2
  s += "9F0206"
  s += st[l : l+6*2]
  l += 6 * 2
  s += "9F0306"
  s += st[l : l+6*2]
  l += 6 * 2
  s += "9505"
  s += st[l : l+5*2]
  l += 5 * 2
  s += "9F1A02"
  s += st[l : l+2*2]
  l += 2 * 2
  s += "5F2A02"
  s += st[l : l+2*2]
  l += 2 * 2
  s += "9C01"
  s += st[l : l+1*2]
  l += 1 * 2
  s += "9F3704"
  s += st[l : l+4*2]
  l += 4 * 2
  s += "8202"
  s += st[l : l+2*2]
  l += 2 * 2
  s += "9F3602"
  s += st[l : l+2*2]
  l += 2 * 2
  s += "9F10"
  tmplen, _ := strconv.ParseInt(st[l:l+1*2], 16, 16)
  s += st[l : l+1*2]
  l += 1 * 2
  s += st[l : l+int(tmplen)*2]
  l += 32 * 2
  s += "9F2701"
  s += st[l : l+1*2]
  l += 1 * 2
  s += "9F3303"
  s += st[l : l+3*2]
  l += 3 * 2
  l += 1 * 2 //可选位元表
  //卡有效期
  cardvailddata = st[l : l+2*2]
  l += 2 * 2
  fmt.Printf("cardvailddata:%s\n", cardvailddata)
  //卡片序列号
  cardholdsn = st[l : l+2*2]
  l += 2 * 2
  fmt.Printf("cardholdsn:%s\n", cardholdsn)
  //卡产品标识
  s += "9F63"
  tmplen, _ = strconv.ParseInt(st[l:l+1*2], 16, 16)
  s += st[l : l+1*2]
  l += 1 * 2
  s += st[l : l+int(tmplen)*2]
  l += 16 * 2
  //电子现金发卡行授权码9F74
  s += "9F74"
  tmplen, _ = strconv.ParseInt(st[l:l+1*2], 16, 16)
  s += st[l : l+1*2]
  l += 1 * 2
  s += st[l : l+int(tmplen)*2]
  //fmt.Println(st)
  s += "9A03"
  s += "181206"
  s += "9F1E083030303030303030"
  s += "9f0902008c"
  s += "9f3403000000"
  s += "9f350136"
  s += "8A025931"
  s += "9F4104"
  s += fmt.Sprintf("%08d", up8583.RecSn)
  fmt.Println(s)
  return byteutil.HexStringToBytes(s)
}
func UpCashProc() error {
  fmt.Printf("connect:server=%s,port=%d\n", Server, Port)
  conn, err := netutil.Connect(Server, Port)
  if err == nil {
    fmt.Println("connect ok!")
  } else {
    fmt.Println("connect failed!")
    return err
  }
  defer netutil.DisConnect(conn)
  field55 := getField55()
  //cardbin = "601382750400038"
  cardbin = "601382750400074"
  up.Frame8583UpCash(cardbin, 190, cardvailddata, cardholdsn, field55)
  up.Ea.PrintFields(up.Ea.Field_S)
  log.Info(byteutil.BytesToHexString(up.Ea.Txbuf))
  _, err = netutil.TxData(conn, up.Ea.Txbuf)
  if err == nil {
    log.Info("send ok!")
  }
  rxbuf := make([]byte, 1024)
  rxlen := 0
  rxlen, err = netutil.RxData(conn, rxbuf)
  if err == nil {
    log.Info("recv ok!len=%d\n", rxlen)
    err = up.Ans8583UpCash(rxbuf, rxlen)
    if err == nil {
      log.Info("上送成功!")
    }
    up.Ea.PrintFields(up.Ea.Field_R)
  }
  return err
}
func main() {
  fmt.Println("test...")
  //获取当前路径
  //file, _ := os.Getwd()
  // load config file, it's optional
  // or log.LoadConfiguration("./example.json", "json")
  // config file could be json or xml
  //mylog := log.NewDefaultLogger(log.INFO)
  //mylog.Info("hahaha  test ...")
  //mylog.LoadConfiguration("./logconfig1.json")
  log.LoadConfiguration("./logconfig.json")
  up8583.Test()
  //log.LOGGER("").Info("category Test info test ...")
  log.LOGGER("Test").Info("category Test info test ...")
  log.LOGGER("Test").Info("category Test info test message: %s", "new test msg")
  log.LOGGER("Test").Debug("category Test debug test ...")
  log.LOGGER("Test1").Debug("category Test1 debug test ...")
  // Other category not exist, test
  log.LOGGER("Other").Debug("category Other debug test ...")
  // socket log test
  //log.LOGGER("TestSocket").Debug("category TestSocket debug test ...")
  // original log4go test
   log level: FINE, DEBUG, TRACE, INFO, WARNING,ERROR, CRITICAL
  //log.AddFilter("file", log.DEBUG, log.NewFileLogWriter("test.log", true, true)) // INFO级别+输出到文件,并开启rotate
  // original log4go test
  log.Info("nomal info test ...")
  log.Debug("nomal debug test ...")
  configUP()
  //up.Frame8583QD()
  //recvstr := "007960000001386131003111080810003800010AC0001450021122130107200800085500323231333031343931333239303039393939393930363030313433303137303131393939390011000005190030004046F161A743497B32EAC760DF5EA57DF5900ECCE3977731A7EA402DDF0000000000000000CFF1592A"
  //recv := byteutil.HexStringToBytes(recvstr)
  //ret := up.Ea.Ans8583Fields(recv, len(recv))
  //if ret == 0 {
  //  fmt.Println("解析成功")
  //  up.Ea.PrintFields(up.Ea.Field_R)
  // } else {
  //  fmt.Println("解析失败")
  // }
  err := QdProc()
  checkErr(err)
  if err == nil {
    err = QrcodeProc()
    //err = UpCashProc()
    checkErr(err)
  }
  //UpCashProc()
  //getField55()
}


相关文章
|
5天前
|
存储 JSON 监控
Viper,一个Go语言配置管理神器!
Viper 是一个功能强大的 Go 语言配置管理库,支持从多种来源读取配置,包括文件、环境变量、远程配置中心等。本文详细介绍了 Viper 的核心特性和使用方法,包括从本地 YAML 文件和 Consul 远程配置中心读取配置的示例。Viper 的多来源配置、动态配置和轻松集成特性使其成为管理复杂应用配置的理想选择。
23 2
|
3天前
|
Go 索引
go语言中的循环语句
【11月更文挑战第4天】
11 2
|
3天前
|
Go C++
go语言中的条件语句
【11月更文挑战第4天】
14 2
|
7天前
|
程序员 Go
go语言中的控制结构
【11月更文挑战第3天】
84 58
|
6天前
|
监控 Go API
Go语言在微服务架构中的应用实践
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出,成为构建微服务的理想选择。本文将探讨Go语言在微服务架构中的应用实践,包括Go语言的特性如何适应微服务架构的需求,以及在实际开发中如何利用Go语言的特性来提高服务的性能和可维护性。我们将通过一个具体的案例分析,展示Go语言在微服务开发中的优势,并讨论在实际应用中可能遇到的挑战和解决方案。
|
3天前
|
Go
go语言中的 跳转语句
【11月更文挑战第4天】
10 4
|
3天前
|
JSON 安全 Go
Go语言中使用JWT鉴权、Token刷新完整示例,拿去直接用!
本文介绍了如何在 Go 语言中使用 Gin 框架实现 JWT 用户认证和安全保护。JWT(JSON Web Token)是一种轻量、高效的认证与授权解决方案,特别适合微服务架构。文章详细讲解了 JWT 的基本概念、结构以及如何在 Gin 中生成、解析和刷新 JWT。通过示例代码,展示了如何在实际项目中应用 JWT,确保用户身份验证和数据安全。完整代码可在 GitHub 仓库中查看。
14 1
|
7天前
|
Go 数据处理 API
Go语言在微服务架构中的应用与优势
本文摘要采用问答形式,以期提供更直接的信息获取方式。 Q1: 为什么选择Go语言进行微服务开发? A1: Go语言的并发模型、简洁的语法和高效的编译速度使其成为微服务架构的理想选择。 Q2: Go语言在微服务架构中有哪些优势? A2: 主要优势包括高性能、高并发处理能力、简洁的代码和强大的标准库。 Q3: 文章将如何展示Go语言在微服务中的应用? A3: 通过对比其他语言和展示Go语言在实际项目中的应用案例,来说明其在微服务架构中的优势。
|
7天前
|
Go 数据处理 调度
探索Go语言的并发模型:Goroutines与Channels的协同工作
在现代编程语言中,Go语言以其独特的并发模型脱颖而出。本文将深入探讨Go语言中的Goroutines和Channels,这两种机制如何协同工作以实现高效的并发处理。我们将通过实际代码示例,展示如何在Go程序中创建和管理Goroutines,以及如何使用Channels进行Goroutines之间的通信。此外,本文还将讨论在使用这些并发工具时可能遇到的常见问题及其解决方案,旨在为Go语言开发者提供一个全面的并发编程指南。
|
5天前
|
Go 调度 开发者
探索Go语言中的并发模式:goroutine与channel
在本文中,我们将深入探讨Go语言中的核心并发特性——goroutine和channel。不同于传统的并发模型,Go语言的并发机制以其简洁性和高效性著称。本文将通过实际代码示例,展示如何利用goroutine实现轻量级的并发执行,以及如何通过channel安全地在goroutine之间传递数据。摘要部分将概述这些概念,并提示读者本文将提供哪些具体的技术洞见。