【K3S】11 - 微服务拆分之Go转型
前言
在上文中,我成功从MySQL到MongDB的转型,接下来,我将尝试将SpringBoot转为go
Protocol
首先,我需要让protoc即生成java代码,也生成go代码。
只需要指定 go_package
即可:
1 | syntax = "proto3"; |
由于我还不是很了解生成的机制,所以这里的包路径全都一样的,你可以尝试对包路径分类。由于我这里有对别的proto文件有引用,导致go的引包错误了,所以才出此下策,当然,所有的名称在声名时也保证了一定不重复。
由于java的代码是通过maven插件生成的,这里我采用原本的protoc命令执行生成go代码,所以我写了这个脚本:
1 | protoc --go_out=./ --go-grpc_out=require_unimplemented_servers=false:./ --proto_path=src/main/proto src/main/proto/common/*.proto |
protoc
: Protocol Buffers 编译器的命令行工具。
--go_out=./
: 表示生成 Go 语言的 Protocol Buffers 代码,并将其输出到当前目录(生成的代码文件将与.proto
文件位于相同的目录中)。
--go-grpc_out=require_unimplemented_servers=false:./
: 表示同时生成 gRPC 代码,并将其输出到当前目录。参数 require_unimplemented_servers=false
意味着生成的 gRPC 代码不会强制实现所有服务接口,这在开发过程中很有用。
--proto_path=src/main/proto
: 指定了存放.proto
文件的路径,该路径为 src/main/proto
。
src/main/proto/common/*.proto
: 指定要编译的.proto
文件的位置和模式。例如,此处使用了通配符common/*.proto
表示编译 common
目录下的所有.proto
文件。
所以执行此脚本,生成代码,并上传至git仓库即可
Go项目创建
创建项目网上都有,这里建议从GitHub找一个crud练手一下,就基本了解go的语法了。此处我想记录的是,如何引入我们上一章节生成的go代码。
一般而言,我们引入一个项目是通过 go get github.com/xxxx/xxxx-proto
命令来拉取的,但是,假如我们的项目是私有GitLab的,如果不指定goproxy,它会把这个项目认为是公有项目,导致无法拉取,所以第一步是将这个地址仓库设为私有仓库,可以看这篇文章:Goland GitLab import 的步骤 | Leopold’s Blog (leofitz7.com)
当你成功 go get 后,就可以在项目中使用protoc生成的代码了。
接下来我们看一下主函数:
1 | package main |
对于服务端的实现,我们只需要实现 V0TestSpiderServiceImpl
即可:
1 | type V0testSpiderServiceImpl struct { |
对于客户端的使用,我们只需要创建连接,并执行方法即可:
1 | var kacp = keepalive.ClientParameters{ |
至此,我们的代码就写好了
Dockerfile
接下来我们打包镜像:
1 | FROM alpine:3.17 |
注意,这里我没有像网上那样,引入goland sdk,go build 编译,再copy二进制程序,因为我们的二进制也就20MB,没必要把整个编译SDK打包进去,我们提前打好即可,只需要拷贝二进制程序,并执行即可。但请注意:
对于 alpine 镜像,如果想执行二进制程序,需要指定
go build --tags netgo
,因为 alpine 太小了,缺少了很多包。netgo
标记告诉Go编译器只使用纯Go实现的网络库,而不依赖于操作系统提供的网络功能。它会禁用对cgo(C语言调用Go函数)的使用,以及对操作系统特定的网络库的依赖。这样可以确保生成的二进制文件在不同操作系统上都能够独立运行,而无需依赖外部动态链接库。通过使用--tags netgo
,可以确保构建的二进制文件不依赖于底层操作系统的网络库,从而增加了可移植性和可靠性。这在某些需要在不同平台上分发的应用程序或服务中非常有用。对于 alpine 镜像,有时候我们恰好需要gnu libc的依赖,这时候就需要慎重考虑是否一定需要使用Alpine镜像,因为Alpine镜像的小巧正是建立在busybox和musl libc基础之上的。因为我这个项目的爬虫程序需要chrome安装,需要gnu libc依赖,所以我是用了三方镜像
frolvlad/alpine-glibc:alpine-3.17_glibc-2.34
,所以对于不同的项目,镜像的选择也很重要。
测试内存占用
通过 kubectl top pods pod名称 -n 命名空间
来查看内存占用情况:
1 | root@m1:~# kubectl top pods -n test |
可以看到,go项目不需要加载jvm,内存非常的小,所以这个服务将分配更多的cpu,发挥协程的特性,爬虫性能大幅提升
其他
对于go爬虫而言,静态页面可使用colly,动态页面可使用chromedp,这里就不多叙述了,坑也不少。
接下来,我可能会学习一段go语言的使用,对于协程、锁的运用还得了解。在下个月中,我将尝试创建pulsar消息队列,并引入分布式锁,将所有服务按照领域事件驱动,这样我们的微服务就基本有了一个小的生态了,下个月见~~