小白学k8s(8)-Bazel部署go应用
Bazel使用了解
Bazel产生的背景
1、开源成为当前软件开发的主旋律。哪怕你是商业软件,也逃离不了社区的包围。如何方便地获取依赖,并做到平滑升级很重要。如果构建工具能够很方便地获取源代码,那就太好了。
2、混合多语言编程成为一种选择。每种语言都有自己适用的场景,但是构建多语言的软件系统非常具有挑战性。例如,Python社区很喜欢搭配C/C++,高性能计算扔个C/C++,Python提供编程接口。如果构建工具能够无缝支持多语言构建,真的很方便。
3、代码复用。我只想复用第三方的一个头文件,而不是整个系统。拒绝拷贝是优秀程序员的基本素养,如果构建工具能帮我方便地获取到所依赖的组件,剔除不必要的依赖,那就太完美了。
4、增量构建。当只修改了一行代码,构建系统能够准确计算需要构建的依赖目标,而不是全构建;否则生命都浪费在编译上了。
5、云构建。大型软件公司,复用计算资源,可以带来巨大的收益。
什么是Bazel
Bazel
是一个支持多语言、跨平台的构建工具。Bazel
支持任意大小的构建目标,并支持跨多个仓库的构建,是Google
主推的一种构建工具。
bazel
优点很多,主要有
构建快。支持增量编译。对依赖关系进行了优化,从而支持并发执行。
可构建多种语言。bazel可用来构建Java C++ Android ios等很多语言和框架,并支持mac windows linux等不同平台
可伸缩。可处理任意大小的代码库,可处理多个库,也可以处理单个库
可扩展。使用bazel扩展语言可支持新语言和新平台。
快(Fast)
Bazel
的构建过程很快,它集合了之前构建系统的加速的一些常见做法。包括:
1、增量编译。只重新编译必须的部分,即通过依赖分析,只编译修改过的部分及其影响的路径。
2、并行编译。将没有依赖的部分进行并行执行,可以通过--jobs
来指定并行流的个数,一般可以是你机器CPU
的个数。遇到大项目马力全开时,Bazel
能把你机器的CPU
各个核都吃满。
3、分布式/本地缓存。Bazel
将构建过程视为函数式的,只要输入给定,那么输出就是一定的。而不会随着构建环境的不同而改变(当然这需要做一些限制),这样就可以分布式的缓存/复用不同模块,这点对于超大项目的速度提升极为明显。
可伸缩(scalable)
Bazel
号称无论什么量级的项目都可以应对,无论是超大型单体项目monorepo
、还是超多库的分布式项目multirepo
。Bazel
还可以很方便的集成CD/CI
,并在云端利用分布式环境进行构建。
它使用沙箱机制进行编译,即将所有编译依赖隔绝在一个沙箱中,比如编译golang
项目时,不会依赖你本机的GOPATH
,从而做到同样源码、跨环境编译、输出相同,即构建的确定性。
跨语言(multi-language)
如果一个项目不同模块使用不同的语言,利用Bazel
可以使用一致的风格来管理项目外部依赖和内部依赖。典型的项目如 Ray。该项目使用C++
构建Ray
的核心调度组件、通过Python/Java
来提供多语言的API
,并将上述所有模块用单个repo
进行管理。如此组织使其项目整合相当困难,但Bazel
在此处理的游刃有余,大家可以去该repo
一探究竟。
可扩展(extensible)
Bazel
使用的语法是基于Python
裁剪而成的一门语言:Startlark
。其表达能力强大,往小了说,可以使用户自定义一些rules
(类似一般语言中的函数)对构建逻辑进行复用;往大了说,可以支持第三方编写适配新的语言或平台的rules
集,比如rules go
。 Bazel
并不原生支持构建golang
工程,但通过引入rules go
,就能以比较一致的风格来管理golang
工程。
Bazel中的主要文件
使用Bazel
管理的项目一般包含以下几种Bazel
相关的文件:WORKSPACE,BUILD(.bazel),.bzl
和 .bazelrc
等。其中 WORKSPACE
和 .bazelrc
放置于项目的根目录下,BUILD.bazel
放项目中的每个文件夹中(包括根目录),.bzl
文件可以根据用户喜好自由放置,一般可放在项目根目录下的某个专用文件夹(比如 build)中。
WORKSPACE
1、定义项目根目录和项目名。
2、加载 Bazel 工具和 rules 集。
3、管理项目外部依赖库。
BUILD.bazel
存在于根目录以及源文件所在目录,用来标记源文件编译以及依赖情况,一般是自动生成。拿 go 来说,构建目标可以是 go_binary、go_test、go_library
等。
自定义 rule (*.bzl)
如果你的项目有一些复杂构造逻辑、或者一些需要复用的构造逻辑,那么可以将这些逻辑以函数形式保存在 .bzl
文件,供WORKSPACE
或者BUILD
文件调用。其语法跟Python
类似:
def third_party_http_deps():
http_archive(
name = "xxxx",
...
)
http_archive(
name = "yyyy",
...
)
配置项 .bazelrc
对于Bazel
来说,如果某些构建动作都需要某个参数,就可以将其写在此配置中,从而省去每次敲命令都重复输入该参数。举个 Go 的例子:由于国情在此,构建、测试和运行时可能都需要GOPROXY
,则可以配置如下:
# set GOPROXY
test --action_env=GOPROXY=https://goproxy.io
build --action_env=GOPROXY=https://goproxy.io
run --action_env=GOPROXY=https://goproxy.io
使用Bazel部署go应用
1、安装Bazel
mac中直接通过brew安装
$ brew install Bazel
centos中的安装可参考centos7安装bazel
2、安装gazelle
$ go get github.com/bazelbuild/bazel-gazelle/cmd/gazelle
手动通过Bazel部署go应用
创建go的运行文件
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
创建WORKSPACE
文件
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# download rules_go
http_archive(
name = "io_bazel_rules_go",
sha256 = "8663604808d2738dc615a2c3eb70eba54a9a982089dd09f6ffe5d0e75771bc4f",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.23.6/rules_go-v0.23.6.tar.gz",
"https://github.com/bazelbuild/rules_go/releases/download/v0.23.6/rules_go-v0.23.6.tar.gz",
],
)
# load rules_go
load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
go_register_toolchains()
# download gazelle
http_archive(
name = "bazel_gazelle",
sha256 = "cdb02a887a7187ea4d5a27452311a75ed8637379a1287d8eeb952138ea485f7d",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.1/bazel-gazelle-v0.21.1.tar.gz",
],
)
# load gazelle
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
gazelle_dependencies()
创建BUILD.bazel
文件
load("@io_bazel_rules_go//go:def.bzl", "go_binary")
go_binary(
name = "test",
srcs = ["main.go"],
importpath = "test",
visibility = ["//visibility:private"],
)
查看目录
test
├── BUILD.bazel
├── WORKSPACE
└── main.go
运行
$ bazel run //:test
DEBUG: /root/.cache/bazel/_bazel_root/1bc6a4d389355f502b77b0dd6dd1fdb4/external/bazel_tools/tools/cpp/lib_cc_configure.bzl:118:5:
Auto-Configuration Warning: CC with -fuse-ld=gold returned 0, but its -v output didn't contain 'gold', falling back to the default linker.
INFO: Analyzed target //:test (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //:test up-to-date:
bazel-bin/linux_amd64_stripped/test
INFO: Elapsed time: 0.254s, Critical Path: 0.00s
INFO: 0 processes.
INFO: Build completed successfully, 1 total action
INFO: Build completed successfully, 1 total action
hello world
成功输出hello world
使用gazelle自动生成BUILD.bazel文件
在实际的项目中,里面的BUILD.bazel
我们肯定是使用工具自动生成的,来看下如何自动生成的
创建t1和t2两个文件夹,写入两个文件
package main
import "fmt"
func main() {
fmt.Println("hello t1")
}
在项目的根目录的BUILD.bazel
中配置加载并配置Gazelle
load("@bazel_gazelle//:def.bzl", "gazelle")
# gazelle:prefix test
gazelle(name = "gazelle")
需要注意的是 # 后面的内容对于Bazel
而言是注释,对于Gazelle
来说却是一种语法,会被Gazelle
运行时所使用。当然Gazelle
除了可以通过bazel rule
运行,也可以单独在命令行中执行。
查看下目录
test
├── BUILD.bazel
├── WORKSPACE
├── main.go
├── t1
│ └── main.go
└── t2
└── main.go
在根目录下面执行bazel run //:gazelle
test
├── BUILD.bazel
├── main.go
├── t1
│ ├── BUILD.bazel
│ └── main.go
├── t2
│ ├── BUILD.bazel
│ └── main.go
└── WORKSPACE
发现对应的目录下面已经生成了我们需要的BUILD.bazel
文件
在根目录下,运行下
$ bazel run t1:t1
INFO: Analyzed target //t1:t1 (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //t1:t1 up-to-date:
bazel-bin/t1/t1_/t1
INFO: Elapsed time: 0.486s, Critical Path: 0.33s
INFO: 3 processes: 1 internal, 2 darwin-sandbox.
INFO: Build completed successfully, 3 total actions
INFO: Build completed successfully, 3 total actions
hello t1
参考
【带你深入AI(6)- 详解bazel】https://blog.csdn.net/u013510838/article/details/80102438
【bazel文档】https://docs.bazel.build/versions/4.1.0/skylark/concepts.html
【Bazel 构建 golang 项目】https://zhuanlan.zhihu.com/p/95998597
【如何评价 Google 开源的 Bazel ?】https://www.zhihu.com/question/29025960
【使用bazel编译go项目】https://juejin.cn/post/6844903892757528590
【Bazel学习笔记】https://blog.gmem.cc/bazel-study-note
小白学k8s(8)-Bazel部署go应用的更多相关文章
- 小白学k8s(9)-gitlab-runner实现go项目的自动化发布
gitlab构建CI/CD 准备 docker部署gitlab 使用二进制部署gitlab-runner gitlab-runner注册 配置Variables 简单先来个测试 开始构建 遇到的报错 ...
- 小白学k8s(7)helm[v3]使用了解
helm使用 什么是helm 安装helm Helm V2 & V3 架构设计 配置kube config helm使用 添加仓库 helm安装nginx helm的核心概念 Chart Co ...
- 小白学Docker之Compose
承接上篇文章:小白学Docker之基础篇,自学网站来源于https://docs.docker.com/get-started 概念 Compose是一个编排和运行多容器Docker应用的工具,主要是 ...
- 小白学Docker之Swarm
承接上篇文章:小白学Docker之Compose,自学网站来源于https://docs.docker.com/get-started 系列文章: 小白学Docker之基础篇 小白学Docker之Co ...
- 小白学 Python 爬虫(3):前置准备(二)Linux基础入门
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 Linux 基础 CentOS 官网: https: ...
- 小白学 Python 爬虫(4):前置准备(三)Docker基础入门
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(10):Session 和 Cookies
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(33):爬虫框架 Scrapy 入门基础(一)
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学Docker之基础篇
系列文章: 小白学Docker之基础篇 小白学Docker之Compose 小白学Docker之Swarm PS: 以下是个人作为新手小白学习docker的笔记总结 1. docker是什么 百科上的 ...
随机推荐
- 在局域网内知道计算机的名字查找计算机的IP
第一步 nbtstat -a 计算机名字 第二步 nbtstat -c 可以看到计算机地址
- 精选Hive高频面试题11道,附答案详细解析(好文收藏)
1. hive内部表和外部表的区别 未被external修饰的是内部表,被external修饰的为外部表. 区别: 内部表数据由Hive自身管理,外部表数据由HDFS管理: 内部表数据存储的位置是hi ...
- Mybatis学习之自定义持久层框架(二) 自定义持久层框架设计思路
前言 上一篇文章讲到了JDBC的基本用法及其问题所在,并提出了使用Mybatis的好处,那么今天这篇文章就来说一下该如何设计一个类似Mybatis这样的持久层框架(暂时只讲思路,具体的代码编写工作从下 ...
- 细数 C++ 那些比起 C语言 更爽的特性
结构体定义 C: typedef struct Vertex { int x, y, z; } Vertex; Vertex v1 = { 0 }; // or struct Vertex { int ...
- .NET 平台系列6 .NET Core 发展历程
系列目录 [已更新最新开发文章,点击查看详细] 在我的上一篇博客<.NET平台系列5 .NET Core 简介>中主要介绍了.NETCore的基本情况,主要包括.NET跨平台的缘由 ...
- Zoho Projects助力企业项目高效管理
挑选项目管理工具,就和人买衣服.买鞋子是一样的,除了看外观,最重要的是合适.随着项目管理工具的不断发展,市面上有很多工具都非常优秀,也能解决企业.团队的实际需求. 对于项目管理来说,最重要的在于人员协 ...
- not full 和 default
create table t16( id int, name char(6), sex enum('male','female') not null default 'male'); insert i ...
- .Net core Worker Service 扩展库
.Net core Worker Service 扩展库,目的为更易控制每一个worker 的运行. 提供根据配置文件对每一个Worker的停止.启动和自动解析注册Worker. 获取配置的方式不限于 ...
- make clean 清除之前编译的可执行文件及配置文件。 make distclean 清除所有生成的文件。
https://blog.csdn.net/bb807777/article/details/108302105 make clean 清除之前编译的可执行文件及配置文件.make distclean ...
- Linux_配置本地YUM源(RHEL8)
[RHEL8] Linux-RHEL8配置本地YUM 源,按照之前传统的配置本地YUM的方法肯定不行,在RHEL8版本的软件源发生了变化,在RHEL8版本的软件仓库分成了两部分:[AppStream] ...