CHEN Feng 362e00a180 docs(readme): update for C++20 + macOS support, retranslate zh/en (#172)
* docs(readme): update for C++20 + macOS support, retranslate zh/en

Bring both READMEs in line with the project's current state:

* C++ badge upgraded from a generic ``C++`` to ``C++20`` to match the
  actual standard the project compiles with (``-std=gnu++2a``).
* Platform badge upgraded from ``linux`` to ``linux | macOS`` --
  macOS port landed in #158, CI matrix in #167 onwards.
* Features section: drop the historical ``C++11/14/17/2a`` mix in
  favor of just ``C++20`` (the standard is committed; the staged
  adoption is no longer informative for a new reader).
* System Requirements section split into ``Linux`` and ``macOS``
  subsections, each listing the supported kernel/OS and the minimum
  toolchain that ships ``std::atomic<T>::wait`` / ``notify_*``:
  - Linux: GCC 11+ (libstdc++ added the operations in 11.1, per
    P1135 -- exposed locally on flare/fiber/detail/scheduling_group
    after the futex path went away in #158).
  - macOS: 13 (Ventura) or later with Apple Clang from Xcode 14+
    (its libc++ has the matching runtime symbols).
  Also calls out aarch64 / arm64 / x86_64 explicitly.
* Retranslated the zh README to read more like native Chinese -- the
  previous version had several literal-translation-isms ("吸收先前服务
  框架"... etc.). Cross-checked the en against the zh and rewrote
  several en sentences that drifted out of step over the years
  (badge alt text, "out of the box" phrasing, the third-party tarball
  blurb, etc.). Both files now describe the same project in the same
  shape.
* Added a back-link from the en README to the zh one (was one-way
  before).
* Updated the blade-build link from chen3feng/blade-build to
  blade-build/blade-build (org moved).
* Fixed bazel/support/README.md link typo (was REAMD.md).

No code changes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs: fix two markdown-link-check failures surfaced by the README PR

* Rename `bazel/support/REAMD.md` -> `bazel/support/README.md`.
  The file has carried the swapped-letter spelling since 2023; the
  previous README link pointed at the typo'd name, so it was working
  by accident. The README rewrite in this PR pointed at the canonical
  spelling and surfaced that the file on disk was wrong.

* Add `.github/markdown-link-check-config.json` to suppress the
  spurious "Status: 0" failure for `https://bazel.build`. The site
  returns a valid 200 to a normal browser and to `curl`, but
  apparently UA-filters the markdown-link-check action -- the action
  reads Status 0 and counts it as broken. Listed it in
  `ignorePatterns`; wired the config into the existing
  `gaurav-nelson/github-action-markdown-link-check@v1` invocation
  via the documented `config-file` input. Also bumps `retryOn429`
  (small reliability win when the action hits rate limits) and pins
  the success set to 200/206.

Both surfaced by CI on this PR; no other changes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 23:21:29 +08:00
2023-07-28 00:26:49 +08:00
2023-07-26 01:34:04 +08:00

Flare 后台服务开发框架

Flare Backend Service Framework

English Document

license NewBSD C++ Code Style Platform

腾讯广告 是腾讯公司最重要的业务之一,其后台大量采用 C++ 开发。

Flare 是我们在汲取自研服务框架经验、参考业界开源项目和最新研究成果的基础上,开发的现代化后台服务开发框架。目标是在当今主流软硬件环境下,提供易用、高性能、平稳的服务开发能力。

Flare 项目始于 2019 年,目前广泛应用于腾讯广告的各类后台服务,拥有数以万计的运行实例,在生产系统上经受了充分的考验。

2021 年 5 月,我们本着回馈社区、技术共享的精神正式将 Flare 开源。

特点

  • 现代 C++ 设计风格,全面采用 C++20 的语法特性和标准库
  • 提供 M:N 线程模型 的用户态微线程实现 Fiber,让开发者用同步调用的写法获得异步调用的性能
  • 支持基于消息的流式 RPC
  • 除 RPC 外,还提供了一系列便利的基础库:字符串、时间日期、编码、压缩、加解密、配置、HTTP 客户端等等,方便快速上手开发业务代码
  • 提供了灵活的扩展机制,方便支持多种协议、服务发现、负载均衡、监控告警、调用追踪等
  • 针对现代体系结构做了大量优化:NUMA 感知的调度组、对象池、零拷贝缓冲区等
  • 高质量的代码。严格遵守 Google C++ 代码规范,测试覆盖率达 80%
  • 完善的文档、示例以及调试支持,方便快速上手

系统要求

Linux

  • Linux 3.10 或以上内核
  • GCC 11 或以上版本的编译器(最早支持 std::atomic<T>::wait / notify_* 的 libstdc++ 版本,参见 P1135)
  • x86-64 处理器;aarch64 和 ppc64le 也支持,但未在生产环境实际投入使用

macOS

  • macOS 13 (Ventura) 或以上
  • Apple Clang(Xcode 14 及以上自带的 libc++ 已包含 std::atomic<T>::wait / notify_* 运行期符号)
  • Apple Silicon (arm64) 与 Intel (x86_64) 均可

开始使用

Flare 是开箱即用的,已经自带了所需的第三方库,通常不需要额外安装依赖。

thirdparty/ 下的源码包通过 Git LFS 存储,因此拉取代码前请确保 git-lfs 已正确安装。

构建

我们使用 blade 进行日常开发:

  • 编译:./blade build ...
  • 测试:./blade test ...

Flare 也支持 bazel 作为构建系统,参见 bazel support。

之后可以参考入门导引,搭建一个简单的 RPC 服务。

调试

我们认为调试体验是开发维护过程中很重要的一环,为此提供了:

测试

为改善编写单测的体验,我们提供了一些测试工具,包括但不限于:

示例

我们提供了一些使用示例,下面是一个简单的转发服务(同时演示了 RPC 客户端与服务端的使用):

#include "gflags/gflags.h"

#include "flare/example/rpc/echo_service.flare.pb.h"
#include "flare/example/rpc/relay_service.flare.pb.h"
#include "flare/fiber/this_fiber.h"
#include "flare/init.h"
#include "flare/rpc/rpc_channel.h"
#include "flare/rpc/rpc_client_controller.h"
#include "flare/rpc/rpc_server_controller.h"
#include "flare/rpc/server.h"

using namespace std::literals;

DEFINE_string(ip, "127.0.0.1", "IP address to listen on.");
DEFINE_int32(port, 5569, "Port to listen on.");
DEFINE_string(forward_to, "flare://127.0.0.1:5567",
              "Target IP to forward requests to.");

namespace example {

class RelayServiceImpl : public SyncRelayService {
 public:
  void Relay(const RelayRequest& request, RelayResponse* response,
             flare::RpcServerController* ctlr) override {
    flare::RpcClientController our_ctlr;
    EchoRequest echo_req;
    echo_req.set_body(request.body());
    if (auto result = stub_.Echo(echo_req, &our_ctlr)) {
      response->set_body(result->body());
    } else {
      ctlr->SetFailed(result.error().code(), result.error().message());
    }
  }

 private:
  EchoService_SyncStub stub_{FLAGS_forward_to};
};

int Entry(int argc, char** argv) {
  flare::Server server{flare::Server::Options{.service_name = "relay_server"}};

  server.AddProtocol("flare");
  server.AddService(std::make_unique<RelayServiceImpl>());
  server.ListenOn(flare::EndpointFromIpv4(FLAGS_ip, FLAGS_port));
  FLARE_CHECK(server.Start());

  flare::WaitForQuitSignal();
  return 0;
}

}  // namespace example

int main(int argc, char** argv) {
  return flare::Start(argc, argv, example::Entry);
}

Flare 内部基于 M:N 用户态线程实现,因此通过 Flare 同步请求外部服务、调用 Flare 内置的各种客户端 的同步接口都不会带来性能问题。如有更复杂的并发或异步需求,可参考 Fiber 文档。

另外,示例中的 *.flare.pb.h 通过 Flare 的 Protocol Buffers 插件 生成。相对于 Protocol Buffers 原生的 cc_generic_services,这种方式生成的接口更易用。

更复杂的示例

实际使用中往往需要并发请求多种后端,下面的示例展示了如何在 Flare 中实现这种模式:

// For illustration purpose only. Normally you wouldn't want to declare them as
// global variables.
flare::HttpClient http_client;
flare::CosClient cos_client;
EchoService_SyncStub echo_stub(FLAGS_echo_server_addr);

void FancyServiceImpl::FancyJob(const FancyJobRequest& request,
                                FancyJobResponse* response,
                                flare::RpcServerController* ctlr) {
  // Calling different services concurrently.
  auto async_http_body = http_client.AsyncGet(request.uri());
  auto async_cos_data =
      cos_client.AsyncExecute(flare::CosGetObjectRequest{.key = request.key()});
  EchoRequest echo_req;
  flare::RpcClientController echo_ctlr;
  echo_req.set_body(request.echo());
  auto async_rpc_resp = echo_stub.AsyncEcho(EchoRequest(), &echo_ctlr);

  // Now wait for all of them to complete.
  auto&& [http, cos, rpc] = flare::fiber::BlockingGet(
      flare::WhenAll(&async_http_body, &async_cos_data, &async_rpc_resp));

  if (!http || !cos || !rpc) {
    FLARE_LOG_WARNING("Failed.");
  } else {
    // All succeeded.
    FLARE_LOG_INFO("Got: {}, {}, {}", *http->body(),
                   flare::FlattenSlow(cos->bytes), rpc->body());
  }

  // Now fill `response` accordingly.
  response->set_body("Great success.");
}

这个示例中,我们:

  • 通过三种不同的客户端(HTTP、腾讯云 COS、RPC)发起了三个异步请求
  • 通过 flare::fiber::BlockingGet 同步等待所有请求完成——这里只会阻塞用户态线程,不会有性能问题
  • 输出日志展示各个服务的响应

出于展示目的,这里请求的是三个异构服务。如有需要,也可以用同样的方式请求同构服务、或同构异构混合的服务。

参与开发

我们非常欢迎共建。希望了解 Flare 更多内部设计的开发者、或需要对 Flare 进行二次开发的开发者,可参考 flare/doc/ 下的技术文档。

详情请参考 CONTRIBUTING.md。

性能

由于业务需求的特点,我们在设计中更倾向于优化延迟及其平稳性,而非吞吐;但在这一前提下也尽力兼顾性能。

简单的对比数据可见初步性能数据。

致谢

  • 我们的底层实现大量参考了 brpc 的设计
  • RPC 部分,grpc 给了我们很多启发
  • 我们依赖了不少来自开源社区的第三方库,正是站在巨人的肩膀上让我们得以更快更好地开发本项目,也因此我们也乐于回馈社区

在此向上述项目一并致以谢意。

S
Description
Flare是广泛投产于腾讯广告后台的现代化C++开发框架,包含了基础库、RPC、各种客户端等。主要特点为易用性强、长尾延迟低。
Readme Multiple Licenses 34 MiB
Languages
C++ 72.8%
CSS 15.1%
Starlark 8.7%
C 1.6%
JavaScript 0.7%
Other 1%