Go Engineering - Design Pattern
设计模式 创建型模式 提供了一种在创建对象的同时隐藏创建逻辑的方式 单例模式饿汉方式 在包被加载时创建 12345678910package singletontype Singleton struct {}var instance *Singleton = &Singleton{}func GetInstance() *Singleton { return instance} 懒汉方式 在第一次使用时创建 - 使用最多,但非并发安全,需要加锁 不加锁1234567891011121314package singletontype Singleton struct {}var instance *Singleton// GetInstance is not thread-safefunc GetInstance() *Singleton { if instance == nil { instance = &Singleton{} ...
Go Engineering - Elegant Project
优雅项目 Go 应用 代码结构 按功能拆分 - Kubernetes / Docker / Helm / Prometheus 代码规范 编码规范 - https://github.com/xxjwxc/uber_go_guide_cn 静态代码检查 - https://github.com/golangci/golangci-lint 最佳实践 https://go.dev/doc/effective_go https://go.dev/wiki/CodeReviewComments https://rakyll.org/style-packages/ 代码质量 单元测试 可测试 将依赖的数据库等抽象成接口,在被测代码中调用接口的方法,在测试时传入 Mock 类型 尽量减少 function 中的依赖 + 依赖是容易 Mock 的 高覆盖率 Code Review Mock 工具 https://github.com/golang/mock 官方 Mock 框架,与 Golang 内置的 testing 包集成,最常用 实现基于 interface...
Go Concurrency - Mutex Basic
基本概念临界区 临界区 - 共享资源 使用互斥锁,限定临界区只能同时由一个线程持有 当临界区被一个线程持有时,其它线程想进入,只能失败或者等待 直到持有的线程退出临界区后,其它等待的线程才有机会去竞争该临界区 在 Go 标准库中,使用 Mutex 来实现互斥锁 - 使用最为广泛的同步原语 同步原语:解决并发问题的基础数据结构 同步原语适用场景 共享资源 - Mutex / RWMutex 任务编排 - WaitGroup / Channel 消息传递 - Channel 基本用法Locker Locker 接口定义了锁同步原语的方法集 1234567package sync// A Locker represents an object that can be locked and unlocked.type Locker interface { Lock() Unlock()} Mutex12func (m *Mutex) Lock()func (m *Mutex) Unlock() 当一个 goroutine 通过 Lock...
FaaS - WebIDE
架构 组成 蓝色部分 WebIDE 客户端的核心 Run VS Code on any machine anywhere and access it in the browser 绿色部分 将 WebIDE 与 FaaS 结合的核心 橘色部分 Serverless 形态下的必备支撑服务 过程 用户在 VS Code 的前端页面向后端发出函数在线编辑的请求 服务端,即 FaaS 的 Controller 在接收到请求并验证权限后,再转给 VS Code Server 容器实例 VS Code Server 容器实例会获取用户代码,然后再加载 FaaS 的资源调度系统 根据目前 Container Pool 中的资源现状,动态扩缩容 WebIDE Pod 资源 VS Code Server 根据用户请求,会调用 Serverless Extension BE 基于此时语言的环境,执行操作,并将执行结果返回给 Client 端 注意 可以将 Serverless Extension 插件提前集成在 VS Code Server 的镜像中 FaaS Runtime 依据原来函数计...
FaaS - Function Invoke
函数拆分 成本 云函数的收费:调用次数、公网流量、占用资源时间(最贵) 复用 组件化 性能 对于非串行的功能,拆分成多个函数可以提高并发性 调用方式 同步、异步、编排(具有调度和管理的语义) 同步 需要注意调用延迟和超时带来的费用成本 直接调用 使用云厂商提供的 SDK,调用指定的函数,实现直接调用 12345678import fc2client = fc2.Client( endpoint='<Your Endpoint>', accessKeyID='<Your AccessKeyID>', accessKeySecret='<Your AccessKeySecret>')// 同步调用client.invoke_function('service_name', 'function_name') 网关调用 通过 API 网关调用函数,借助 API 网关来...
FaaS - Runtime
概述 一般的编程语言都有自身的运行时,运行时的主要职责是可以让代码和机器交互,进而实现业务逻辑 函数计算运行时 能够让函数在机器或者容器中执行起来,实现业务逻辑的执行环境 通常由特定语言构建的框架构成 函数计算运行时依赖于语言运行时 函数计算运行时的本质:让函数在容器中执行起来的代码框架 在函数实例初始化时,函数计算运行时一般会由一个初始化进程加载起来 然后函数计算运行时就可以准备接收请求 当请求到达后,业务代码会被对应的语言运行时中加载进来处理请求 Runtime 是一个特定语言环境下的服务框架环境 该服务将以一个进程的形态运行在用户容器中,并与用户代码相关联 该服务启动后,会一直等待请求的到来,一旦请求到达后,Runtime 会关联业务代码去执行(并发) 原理语言类型编译型语言 C/C++/Go,在编译时将所有用到的静态依赖、源码一起打包,编译完后可以直接运行 Java,经过编译产生的字节码需要 JVM 再次将其转换为机器码,同时具有编译型和解释型的特性 通常需要将所有依赖包打包成一个 jar 包或者 war 包,符合编译型语言的风格 在开发函数时,需...
APISIX - Doc
Feature Apache APISIX 基于 Radixtree Route 和 etcd 提供路由极速匹配与配置快速同步的能力 Apache APISIX 提供了自定义插件的能力 可以在 Balancer 阶段使用自定义负载均衡算法,并使用自定义路由算法对路由进行精细化控制 Apache APISIX 提供了配置热更新、插件热加载能力,在不重新启动实例的情况下可快速更新配置 Quick Start路由 Apache APISIX 使用 routes 来提供灵活的网关管理功能,在一个请求中,routes 包含了访问路径和上游目标等信息 Route Route 是访问上游目标的路径 过程 通过预定的规则来匹配客户端请求 然后加载和执行相应的插件 最后将请求转发至特定的 Upstream 一个最简单的 Route 仅由匹配路径和 Upstream 地址两个信息组成 Upstream Upstream 是一组具备相同功能的节点集合,它是对虚拟主机的抽象 Upstream 可以通过预先配置的规则对多个服务节点进行负载均衡 Examples 创建路由 = Uri + Upstr...
FaaS - Scaling
概述 Serverless 的弹性扩缩容可以将实例缩容为 0,并根据请求量级自动扩缩容,从而有效地提升资源利用率 极致动态扩缩容是 FaaS 的核心内涵,是与 PaaS 平台的核心差异 - 降本增效 调度形态 开源的 Serverless 函数计算引擎核心,一般是基于 Kubernetes HPA 云厂商一般有封装好的各种底座服务,可以基于底座服务来做封装 云厂商容器调度服务,通常有两种调度形态 基于 Node 调度 基于容器实例的调度 - Serverless 云厂商的函数计算通常是基于容器服务的底座 Node 维度 组件 Scheduler 负责将请求打到指定的函数实例(Pod)上,同时负责为集群中的 Node 标记状态,记录到 etcd Local-Controller Node 上的本地控制器,负责管理 Node 上所有函数实例的生命周期,以 DeamonSet 形式存在 AutoScaler 定期检测集群中 Node 和 Pod 的使用情况,并根据策略进行扩缩容 在扩容时,向底层的 PaaS 平台申请资源 Pod Cold 表示该 Pod 未被使用 Warm 表示...
FaaS - Cold Start
触发时机 类似于 LoadingCache 首次请求 容器实例在服务请求后被回收 启动过程 容器创建 当所有容器实例都在处理请求时,需要向集群申请创建新的容器 函数计算平台会支持多种语言的运行时 这些运行时一般来说会打包成一个镜像,然后以 DeamonSet 的方式运行在 Kubernetes 中 在冷启动时,会根据不同的参数请求,动态挂载所需的运行时到对应的运行路径 代码包 / 层依赖 是整个冷启动耗时比较长的过程 函数计算本身不具备持久化的能力,代码包和层依赖通常都是从其它存储服务端拉取 代码包通常是压缩包的形式,下载到本地后,再解压 环境变量 / 参数文件 耗时相对较短 主流的函数计算平台往往提供了环境变量注入的能力,发生在冷启动阶段 运行时以及容器本身还需要准备一些参数配置文件 VPC 打通 / 资源准备 如果用户还为函数接入了私有网络,还需要为容器进行一些 VPC 网络打通的初始化工作 如果用户使用了类似分布式文件系统等功能,还需要进行挂载 运行时初始化 通常指的是云厂商标准的 Runtime 环境的启动过程 受编程语言类型的影响比较大(JV...















