首页 / 资讯中心 / 文章详情

Fn Server 源码贡献指南:核心范围界定、本地构建运行与扩展开发全解析

Fn Server 源码贡献指南:核心范围界定、本地构建运行与扩展开发全解析 ★ FEATURED ARTICLE
云原生后端微服务【免费下载链接】fnThe container native, cloud agnostic serverless platform.项目地址https://gitcode.com/gh_mirrors/fn/fn点击查看免费下载本篇指南以 Fn Project 官方仓库的CONTRIBUTING.md为骨架面向有意向 Fn Server即本仓库fnproject/fn提交代码的开发者系统讲解三层核心内容Fn Server 的贡献范围边界什么该进核心、什么必须做成扩展、如何从源码构建/运行/测试 Fn Server含 Docker 方式以及如何利用官方扩展点listeners、middleware、API 端点以正确姿势贡献功能。读完本文你将具备在本地完整拉起一个可调试的 fnserver、跑通全链路测试并写出符合官方规范扩展代码的实战能力。一、Fn Server 的贡献边界先想清楚该不该进核心1.1 核心职责属于本仓库的部分本仓库的CONTRIBUTING.md开宗明义Fn Server 只承载整个 Fn 生态中最本质的部分具体包括核心 APIapps应用、routes路由、calls调用、logs日志四大资源的管理接口函数执行同步即同步调用sync invoke路径本地拉起容器执行函数扩展点回调callbacks、中间件middleware、API 追加API additions三类可插拔机制。从源码看这一定位与仓库结构完全吻合核心 API 的 handler 集中注册在 api/server/server.go 的bindHandlers中/v2下的 apps、fns、triggers 的增删改查而函数执行由api/agent包承担扩展点则独立成fnext包与api/server中的AddXxx系列方法。1.2 明确不属于核心的部分原文档特别强调以下内容不在Fn Server 核心范围内认证authentication统计/指标stats/metrics特殊或可选特性triggers触发器、FDK函数开发工具包、workflows工作流、event sources事件源等可以论证的是超出基础支持范围之外的额外 I/O 格式也应作为插件plugin构建。从仓库证据看统计/指标并非完全缺席但大多以可选方式接入例如 cmd/fnserver/main.go 中的registerViews只负责注册 OpenCensus 视图与 Prometheus 导出器属于运行时观测能力而非 API 核心资源而 triggers 虽然在本仓库api/server中有 CRUD 端点但原文档将其定位为生态可选特性贡献者应以扩展思路对待。1.3 贡献铁律能做成扩展就绝不要塞进核心原文档给出了一条最重要的取舍准则Rule of thumb: If it could be built as an extension, then build it as an extension.经验法则如果某个功能能做成扩展就把它做成扩展。同时官方承诺两点扩展点优先接纳为了支撑扩展开发Fn Server愿意接受任何合理的扩展点新增We WILL accept any reasonable additions to extension points尽力降低扩展成本官方会尽一切可能让用户方便地添加扩展简化构建或支持 Go plugins 方式。1.4 晋升机制Graduation原文档还定义了扩展毕业机制当某个扩展在社区中变得普遍即大多数用户都在使用时它可以晋升graduate进入核心。这意味着贡献者可以先以扩展形式验证需求与使用量再申请并入核心降低核心代码的膨胀风险。二、构建依赖与仓库获取2.1 依赖清单按原文档构建 Fn Server 的唯一硬依赖是Go需要Go 1.11.0才能使用 Go Modules对照当前仓库 go.mod 可以看到模块声明为github.com/fnproject/fngo指令版本已演进到go 1.24.6并大量依赖gin-gonic/gin、fsouza/go-dockerclient、go-sqlite3、go.opencensus.io等库。因此实际编译请以本地 Go 版本满足 go.mod 要求为准。2.2 获取仓库原文档给出的克隆命令$ git clone https://github.com/fnproject/fn.git特别提醒必须克隆fnproject/fn官方仓库而不是你自己的 fork否则构建无法正常工作。日常贡献流程是以官方仓库为构建基准在自己的 fork 上做修改后提交 PR。# 进入仓库目录如尚未进入 $ cd path/to/fnproject/fn三、本地构建与运行 Fn Server3.1 只编译make build对应 Makefile 中的目标build: go build -o fnserver ./cmd/fnserver注意产物是fnserver可执行文件并非名为fn编译入口为 cmd/fnserver/main.go。3.2 编译并运行原文档推荐每次修改代码后都执行make runmake run对应 Makefilerun: build GIN_MODEdebug ./fnservermake run会先构建再用 debug 模式Gin 框架的GIN_MODEdebug启动服务。按原文档说明启动后的 Fn Server使用内嵌的 sqlite3 数据库默认连接串为sqlite3://当前目录/data/fn.db见 api/server/server.go 的NewFromEnv实现监听8080端口默认值DefaultPort 8080见 api/server/server.go。3.3 入口代码与启动流程启动逻辑非常简洁cmd/fnserver/main.gofunc main() { ctx : context.Background() registerViews() funcServer : server.NewFromEnv(ctx) funcServer.Start(ctx) }server.NewFromEnv从环境变量装配全部配置数据库、端口、节点类型、日志、Agent 等并完成各类中间件与路由绑定server.Start监听信号os.Interrupt、SIGTERM启动 Web/Admin/gRPC 服务并阻塞运行见 api/server/server.go。此外 cmd/fnserver/main.go 通过 blank import 引入了api/server/defaultexts包该包见 api/server/defaultexts/defaultexts.go以扩展形式自动加载了 docker 驱动、sql 数据存储及其 mysql/postgres/sqlite 子模块——这就是默认二进制自带全部存储后端的机制。3.4 常用运行环境变量源码级佐证从 api/server/server.go 的常量定义与NewFromEnv实现可确认以下最常用的环境变量环境变量默认值说明FN_DB_URLsqlite3://cwd/data/fn.db数据存储 URL支持sqlite3、mysql、postgres三种 schemeFN_PORT8080Web/API 服务监听端口FN_GRPC_PORT9190gRPC 服务端口pure-runner 节点用FN_LOG_LEVELinfo日志级别如debugFN_LOG_FORMATtext日志格式text/jsonFN_LOG_DESTstderr日志输出目标支持udp、tcp、fileschemeFN_NODE_TYPEfull节点类型full/api/lb/pure-runnerFN_MAX_REQUEST_SIZE0API 请求体大小上限字节FN_ZIPKIN_URL/FN_JAEGER_URL空链路追踪导出地址FN_RUNNER_ADDRESSES/FN_RUNNER_API_URL空LB 节点模式下 runner 地址/API URLFN_NODE_TYPE的四种取值对应ServerTypeFull / ServerTypeAPI / ServerTypeLB / ServerTypePureRunner四种模式api/server/server.go其中full同时承载 API 与任务执行pure-runner仅运行 gRPC 执行服务。这些变量在本地调试与后续部署如 LB runner 分离架构时非常关键。四、测试体系make test全链路拆解原文档给出的测试命令make test对应 Makefiletest: checkfmt pull-images test-basic test-middleware test-extensions test-systemmake test是一个完整的质量门禁流水线下面逐段拆解。4.1 checkfmt代码格式门禁checkfmt: ./go-fmt.shgo-fmt.sh 会遍历除vendor/、.git外的全部*.go文件执行gofmt -l任何未格式化文件都会导致退出码非 0。提交 PR 前请务必先gofmt。4.2 pull-images拉取测试用镜像pull-images: img-mysql img-postgres img-busybox由 helpers.sh 驱动分别拉取mysql:9.5.0-oraclelinux9、postgres:16.2与busybox可通过REMOTE_DOCKER_REPO覆盖 registry默认docker.io供测试中的数据库与函数容器使用。4.3 test-basic基础单元/集成测试test-basic: checkfmt pull-images fn-test-utils fn-status-checker fn-test-volume ./test.shtest.sh 会设置GOFLAGS-modvendor与 Makefile 的mod目标一致使用 vendor 目录编译通过 helpers.sh 的spawn_postgres/spawn_mysql在 Docker 中拉起测试数据库并把连接串注入POSTGRES_URL、MYSQL_URL环境变量对排除 vendor、examples、test 目录后的所有包执行go test超时 360s最后执行go vet做静态检查。4.4 test-middleware / test-extensions示例工程编译验证test-middleware: cd examples/middleware go build test-extensions: cd examples/extensions go build这两个目标确保 examples/middleware/main.go 与 examples/extensions/main.go 两个扩展示例始终可编译是扩展点必须好用承诺的直接验证。4.5 test-system系统级端到端测试test-system: ./system_test.sh sqlite3 ./system_test.sh mysql ./system_test.sh postgressystem_test.sh 针对三种数据库后端各跑一遍test/fn-system-tests下的端到端测试如 test/fn-system-tests/exec_fn_test.go并会输出 Prometheus 指标到prometheus.db.txt文件供核对。这解释了为什么make test需要 Docker系统测试会真实拉起函数容器并执行。4.6 其他相关测试目标make test-datastore仅对api/datastore包运行go test ./...make test-build-arm分别以GOARCHarm(5/6/7)、GOARCHarm64交叉编译验证多架构构建可用性见 Makefile。五、在 Docker 中运行与测试 Fn Server5.1 一键在容器中启动make docker-run对应 Makefiledocker-run: docker-build docker run --rm --privileged -it -e NO_PROXY -e HTTP_PROXY -e FN_LOG_LEVELdebug -e FN_DB_URLsqlite3:///app/data/fn.db -v ${CURDIR}/data:/app/data -p 8080:8080 fnproject/fnserver要点--privileged函数执行依赖 Docker-in-Docker 能力需要特权模式FN_DB_URLsqlite3:///app/data/fn.db并挂载./data目录使数据库文件持久化到宿主映射8080:8080本地可直接访问 APIFN_LOG_LEVELdebug便于调试。5.2 先构建镜像再用 fn CLI 指定版本启动原文档还给出了另一种组合用法make docker-build fn start --version latestmake docker-build构建镜像fnproject/fnserver:latest见 Makefilefn start --version latest是fn CLI的命令前提本机已安装fnCLI它会让本地 Fn Server 使用刚构建的latest版本镜像启动。5.3 在 Docker 中跑测试make docker-test对应 Makefile挂载 Docker socket 与仓库目录在fnproject/go:dev容器内对排除 vendor/examples/系统测试后的全部包执行go test -v。适用于不想污染本机 Go 环境的贡献者。六、扩展点贡献功能的正确姿势原文档反复强调能扩展就扩展本节把官方提供的扩展机制结合源码逐一讲透。扩展相关接口集中在fnext包与api/server的注册方法中。6.1 扩展的统一抽象Extension接口所有扩展必须实现 fnext/setup.go 定义的接口type Extension interface { Name() string Setup(s ExtServer) error }ExtServer接口fnext/setup.go限定了扩展能触碰的范围可注册监听器、中间件、API 端点并可读取当前 Datastoretype ExtServer interface { AddAppListener(listener AppListener) AddCallListener(listener CallListener) AddAPIMiddleware(m Middleware) AddAPIMiddlewareFunc(m MiddlewareFunc) AddRootMiddleware(m Middleware) AddRootMiddlewareFunc(m MiddlewareFunc) AddEndpoint(method, path string, handler APIHandler) AddEndpointFunc(method, path string, handler func(w http.ResponseWriter, r *http.Request)) Datastore() models.Datastore }6.2 注册机制RegisterExtension与AddExtensionapi/server/extensions.go 提供了两套注册方式RegisterExtension(ext)仅登记到全局extensions映射不初始化——适合在第三方扩展的init()中调用AddExtensionByName(name)按名字完成Setup(s)供fn build-server这类 CLI 使用AddExtension(ext)先注册再添加适合扩展开发期或自定义 server 时直接调用。6.3 Listeners资源生命周期的回调针对 App、Fn、Trigger、Call 四类资源fnext/listeners.go定义了四组监听器接口均采用Before/After成对钩子模式。例如AppListenerBeforeAppCreate/AfterAppCreate、BeforeAppUpdate/AfterAppUpdate、BeforeAppDelete/AfterAppDelete、BeforeAppGet/AfterAppGet、BeforeAppsList/AfterAppsListFnListenerFn 的增删改 Before/After 钩子TriggerListenerTrigger 的增删改 Before/After 钩子CallListenerBeforeCall函数执行前与AfterCall函数完成后。从实现看这些监听器通过 fnext/datastore.go 的NewDatastore包装层嵌入数据存储调用链每次InsertApp、UpdateApp、RemoveTrigger等都会先触发 Before 钩子、再调用底层 Datastore、最后触发 After 钩子任一 Before 返回错误都会中断操作。而api/server侧的appListeners/fnListeners/triggerListeners见 api/server/app_listeners.go、api/server/fn_listeners.go、api/server/trigger_listeners.go会把多个监听器串联成链按注册顺序依次执行。典型场景在AfterAppCreate中为新建应用自动创建配套资源或在BeforeAppDelete中做资源回收校验。6.4 Middleware拦截 API 与用户请求fnext/middleware.go定义了标准中间件抽象type Middleware interface { Handle(next http.Handler) http.Handler } type MiddlewareFunc func(next http.Handler) http.Handler配套的注册方法AddAPIMiddleware/AddRootMiddleware等在 api/server/server.go 中被应用到 Gin 引擎rootMiddlewareWrapper作用于所有路由apiMiddlewareWrapper仅作用于/v2API 分组。仓库自带的 examples/middleware/main.go 是一个完整可运行的认证中间件示例它校验Authorization: Bearer token头示例 token 为KlaatuBaradaNikto不合法则返回 401 JSON合法则向 context 注入用户信息并放行——这正是认证不进核心、以中间件扩展实现的官方示范。6.5 追加 API 端点AddEndpoint/AddEndpointFuncapi/server/extension_points.go实现了在/v2下追加自定义端点func (s *Server) AddEndpoint(method, path string, handler fnext.APIHandler) func (s *Server) AddEndpointFunc(method, path string, handler func(w http.ResponseWriter, r *http.Request))examples/extensions/main.go 演示了两种写法实现APIHandler接口的结构体custom1Handler以及直接传入函数custom2HandlerfuncServer.AddEndpoint(GET, /custom1, custom1Handler{}) funcServer.AddEndpointFunc(GET, /custom2, func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, Hello func, %q, html.EscapeString(r.URL.Path)) })6.6 贡献建议总结对照原文档与源码贡献非核心功能时的推荐路径是优先以扩展实现使用fnext的 listeners / middleware / endpoint 三件套需要绕过既有端点的行为时可考虑WithoutHTTPTriggerEndpoints()、WithoutFnInvokeEndpoints()等 Option见 api/server/server.go关闭默认端点再替换为自己的实现若确实需要新增扩展点基础设施官方明确愿意接受合理的新增当功能在社区普遍使用后可申请**晋升Graduation**进入核心。七、贡献流程速览综合原文档与仓库工程实践一次完整的贡献闭环大致如下克隆官方仓库git clonefnproject/fnfork 用于开发构建基准必须是官方仓库环境准备安装满足 go.mod 要求的 Go原文档基线为 1.11 以支持 go mod并确保本机有 Dockermake test/docker-run均依赖 Docker编码与自测每次改动后运行make run本地验证涉及格式问题先跑gofmtmake checkfmt跑通测试make test含格式门禁、基础测试、示例编译、三种数据库的系统测试不想污染本机环境可改用make docker-test遵守边界功能优先做成扩展扩展点不够时再提扩展点新增 PR提交 PR说明改动动机、测试结果与扩展/核心归属判断。遵循以上流程既能保证提交质量也能与 Fn Server 内核精简、扩展繁荣的架构哲学保持一致。参考资源仓库内构建目标与测试编排Makefile、go-fmt.sh服务入口与装配cmd/fnserver/main.go、api/server/defaultexts/defaultexts.go环境变量与节点模式api/server/server.go扩展接口定义fnext/、api/server/extensions.go、api/server/extension_points.go官方示例examples/extensions/main.go、examples/middleware/main.go测试脚本test.sh、system_test.sh、helpers.sh、test/fn-system-tests/赞分享云原生后端微服务【免费下载链接】fnThe container native, cloud agnostic serverless platform.项目地址https://gitcode.com/gh_mirrors/fn/fn点击查看免费下载相关推荐RabbitMQ Server 源码贡献实战指南从构建、测试到本地多节点运行RabbitMQ Server 源码贡献实战指南从构建、测试到本地多节点运行 本指南以 deps/amqp10_client/CONTRIBUTING.md后端消息队列消息路由Plunk 贡献开发指南Turborepo 架构、本地环境搭建与代码规范全解析Plunk 贡献开发指南Turborepo 架构、本地环境搭建与代码规范全解析 Plunk 是一个开源的邮件平台The Open Source Email后端前端Sigma File Manager 源码开发与贡献指南从环境搭建、本地运行到构建验证Sigma File Manager 源码开发与贡献指南从环境搭建、本地运行到构建验证 本文基于仓库根目录 CONTRIBUTING.md https://l桌面应用上一篇如何实现微信网页版完整功能访问wechat-need-web跨平台解决方案深度解析下一篇如何高效采集微博数据专业Python爬虫工具实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站