工具库
1 - Golang Common Library 工具库
Common Library 是 一个编程工具包
,用于在 Golang
中构建微服务
(或单体
)。解决分布式系统
和应用程序架构
中的常见问题,可以让业务更加专注于交付业务价值
。
此工具包兼容
目前市场上绝大部分的服务框架: Kite、ServiceComb、go-kit、CloudWeGo/KiteX、gin、beego
并将Common Library 发布到golang生态:
动机
Golang
已成为服务器语言,在 Facebook
、Uber
、Netflix
和 国内ByteDance
、DIDI
等所谓的“现代企业”公司中的使用度很高。但还有许多这些企业都是基于 JVM 的堆栈来处理他们的业务逻辑,这在很大程度上归功于直接支持他们的
微服务架构的Library库
和生态系统
。
为了达到更高的成功水平,需要一个全面
的工具包,以实现大规模的连贯分布式编程
。Golang Common Library
就是是一组包package
和最佳实践
,它为任何规模的组织构建服务提供了一种全面
、健壮
和可信赖
支持
目标
构建相当完整
、开箱即用
的Package集合
- 各package相互对立,可按需使用
- 减少外部版本依赖,自形生态
- 无业务逻辑,全开放基础能力实现
- 没有特定工具或技术的强制要求
依赖管理
基于go mod
支持多golang语言版本编译: 最小golang
版本支持 1.12
Package集合说明
Cache 内存缓存
- 支持
lru
、lfu
和随机
淘汰算法,同时也支持时间过期淘汰; - 支持
event
回调: load加载回调、加载成功回调、对象淘汰回调; - 支持全局内存最大值设置(全局内存) 或 全局最大block(对象数)对象设置;
- 支持 metircs 统计 key 的命中率情况分析;
- 支持 Cache 内部数据 匹配查询(hash), 也支持近似值匹配查询(多阶二分查找);
- 支持 内存无GC 高性能模式;
Config 配置管理
- 支持
json
、ini
和 环境变量 配置 - 支持 默认值 设置与限制
- 支持 内存使用 配置
cli
输出
Connect obejct Pool 连接池管理
- 支持
连接对象 Connect Obeject
、全局公用对象 Global Obeject
、数据对象 Data Objetc
管理 - 支持 对象
保活
、最小可用
、最小空闲
管理 - 支持
event
回调: connect前、clear前、销毁前 回调; - 支持单机百万TPS管理
Discovery 注册中心 和 配置中心
- 支持etcd注册、healthcheck、configure下载、心跳保活
errno 通用错误库集合
- 支持 多个 errors 压栈传递
- 支持 errors 全局统一管理 和 标准序列号
- 支持 自定义Error 管理
logger 日志库(基于 uber zap on logrus)
- 完全兼容golang标准库日志模块,拥有六种日志级别
- 支持扩展的Hook机制
- 支持日志输出格式:JSONFormatter和TextFormatter
- 支持日志轮转:按log大小 和 按日期
- 支持日志清理:按log总大小 和 按日期
- 支持最高性能
metrics 收集
- 支持
prometheus
数据接口 - 支持
opentelemetry
数据接口 - 支持 atomic 内存态 统计
queue 队列
- 支持
RingQueue
、PriorityQueue
内存队列管理 - 支持无锁高性能队列使用
ratelimiter 限流包
- 支持 令牌桶、滑动时间窗口 限流模式
- 支持对对象限流: 可用于全局 和 部分sub对象限流 的 生成、处理 和 销毁
temporary 大文件IO交互库
- 支持超过一定大小、将临时缓冲转成临时文件
- 支持异步写源信息:io.Reader转换成io.ReadSeeker
- 支持异步读取源信息后关闭
workpool 任务池
- 支持 任务
保活
、最小可用
、最小空闲
管理 - 支持
event
回调: 执行前、执行完成后、销毁前回调; - 支持
goroutine
链方式管理;整个栈内存支持全局设置 - 支持 异常处理
failover
处理
Util 通用库
- 支持
Map、Strings、Time
等基础数据转换 - 支持
version
版本号比较 - 支持
数据diff
2 - 基于bclinux构建多语言基础镜像
容器 基础镜像 Base Image 规范
将应用Application
打包到镜像Image
中形成业务镜像Application Image
,往往需要一个基础镜像Base Image
作为我们应用服务的外部环境.
那么问题来了,基础镜像从何而来?
官方推荐: 直接从官网仓库pull一个,但由于官网被墙的比较厉害,所以这里介绍一些官方提供以及个人方法。
1. 基础镜像分类
基础镜像(base image)规范两大类:
-
build base image
: 将代码 通过外挂Volume
挂载到 基础镜像(build base image
)进行编译 -
runtime base image
:将编译产物 外挂Volume
放入 基础镜像(runtime base image
) 或者 基于标准容器(runtime base image
)构建业务容器
1.1 外挂Volume
挂载到 基础镜像
apiVersion: v1
kind: Pod
metadata:
name: ext-volume
spec:
containers:
- image: centos:7 #base image
name: ext-volume
command: [ "/test-data/bin/application", "-m", "release" ]
volumeMounts:
- mountPath: /test-data
name: bin-volume
volumes:
- name: bin-volume
hostPath:
path: /data/bin
type: Directory
将外部
的二进制文件,通过volume
的方式挂载到base image
中,执行pod
优势: 1.基础镜像可随时替换,不需要重新制作新镜像(比如:image中出现安全问题、更换国产化OS等) 2.业务部署方式统一, 机器上的镜像数量少,占用空间少,不会因为image的大小导致磁盘不可用 劣势: 1.yaml设计规范统一问题(一般需要云平台统一支持) 2.加大管理复杂性,业务application二进制多版本管理的问题
1.2 基于基础镜像
构建 业务镜像
FROM scratch # 基础镜像
ADD application /
CMD ["/application", "-m", "release"]
apiVersion: v1
kind: Pod
metadata:
name: inner-docker
spec:
containers:
- image: application:latest # application image
name: inner-docker
基于基础镜像 base image
构建 业务镜像 application image
优势: 1.yaml设计灵活 2.application image 可以通过 register hub 进行版本离 劣势: 1.基础镜像可随时替换,需要重新制作新镜像(比如:image中出现安全问题、更换国产化OS等) 2.业务部署方式不统一, 机器上的镜像数量多,占用空间多,因为image的对导致磁盘空间满
2. 限制 alpine
使用; scratch
不推荐使用
alpine
避免长期使用,本身基础镜像有安全漏洞,减少维护成本,限制业务使用
scratch
是空镜像,特殊的一种说明,推进不使用(除非是基础C语言软件)
3. 基础镜像构建方式
3.1 build base image
以golang
为例:
FROM centos:7
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
apt-get install --yes \
gcc curl strace \
ca-certificates netbase \
procps lsof psmisc \
openssh-server
RUN mkdir /usr/local/go-bootstrap && \
curl --silent https://storage.googleapis.com/go-builder-data/gobootstrap-linux-arm64.tar.gz | \
tar -C /usr/local/go-bootstrap -zxv
ENV GOROOT_BOOTSTRAP /usr/local/go-bootstrap
RUN curl -o /usr/local/bin/stage0 https://storage.googleapis.com/go-builder-data/buildlet-stage0.linux-arm64 && \
chmod +x /usr/local/bin/stage0
ENV GO_BUILD_KEY_DELETE_AFTER_READ true
ENV GO_BUILD_KEY_PATH /buildkey/gobuildkey
编译为基础的 golang:1.x.x-centos-7
编译基础镜像
业务可以通过的Dockerfile 使用此镜像进行代码镜像内编译
# Build the manager binary
FROM golang:1.x.x-centos-7 as builder
RUN apk add --no-cache gcc musl-dev libc6-compat
WORKDIR /workspace
COPY go.mod go.mod
COPY go.sum go.sum
# Copy the go source
COPY cmd/ cmd/
COPY pkg/ pkg/
COPY vendor/ vendor/
# Build
RUN CGO_ENABLED=0 go build -ldflags "-linkmode external -extldflags -static" -o /application./cmd/main.go
3.2 runtime base image
统一的runtime base image
需要对基础的os添加必要的lib包.
举个例子: 添加基础的lib包
FROM centos:7
RUN \
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup && \
curl -Lo /etc/yum.repos.d/CentOS-Base.repo http://mirrors.cloud.tencent.com/repo/centos7_base.repo && \
curl -Lo /etc/yum.repos.d/epel-7.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo && \
yum clean all && \
yum makecache && \
yum update -y && \
yum install -y automake autoconf readline libtool make which gcc-c++ cmake3 ccache python-devel cargo glibc-static gperf man flex bison autoconf-archive git patch libstdc++ libstdc++-devel libstdc++-static yasm
ENV \
TZ=Asia/Shanghai \
LANG=en_US.utf8 \
LC_ALL=en_US.utf8 \
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:$PKG_CONFIG_PATH \
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
WORKDIR $GOPATH
CMD ["/bin/bash"]