apollo config C++(20) client
apollo or nacos
- 两个最小化部署简单试用了一下
- 最终选择 apollo 主要有是:
- 权限隔离:修改、提交的权限可以隔离开,实际应用中这点还挺重要的(nacos可能也有类似功能,暂时没有使用到)
- 页面配置方式更简洁
- 灰度的支持
- 之前用过更熟悉
client 实现
核心功能
- 配置拉取与缓存
- 线程安全配置访问
- HTTP 长轮询(long poll)监听变更
- 多命名空间隔离管理
- IP 感知路由支持(灰度)
其他
- 熔断器(circuit breaker)
callback thread pool
TODO: 线程池已经实现,但是总觉得这里放一个线程池有点重,期望是做成切片的方式,由外部决定 callback 怎么处理,但是又会涉及另一个问题如果外部是阻塞的,那么代码里的那个锁会很长。- 而且这里涉及一次数据拷贝,暂时还没太想好怎么做才最好 (
trigger_callbacks
函数调用cb(key, value);
的地方)
过程中的问题记录
apollo
服务端 status = 304 时没有 body,cpp-httplib
不设置response function
的情况下会取不到304
这个 status code,考虑了下还是需要就加上了apollo
的返回 header 里没有content-length
…. 不太友好response_body
的reserve
没有意义了(还是保留在这里了,之后看下 apollo 实现看能不能改掉)cpp-httplib
里的encode_url
结果对apollo
是不够的,所以有了这个函数:strict_url_encode
apollo
有更新再拉取的时候也是全量的,一度考虑做个比较器,比较后只 callback 增量给应用方….(暂时还没有实现,namespace_data
结构里保留了 notification_id、messages 信息,应该可以用这两个信息先对比下再看是否要遍历区分这个namespace里是否有更新)process_config_response
的实现是直接替换了整个namespace_data
, 主要是省事,后面process_notifications
会再把notificationId
,messages
信息更新掉,再次fetch_config
时没有变更也会只得到304
的 status code
依赖要求
- C++20 编译器
- cpp-httplib (v0.12.1+)
- nlohmann/json (v3.11.2+)
基础使用
1 | void apollo_test() { |
其他
update message
- 2025-04-08 把 nlohmann json 替换成了 simdjson。最开始理解错误了 simdjson 的 iterate_many 接口,以为是增量解析的;issue 里看到了一些关于增量解析的讨论,期望后续有相关实现
熔断器
- 这个熔断器比较简单,失败超过一定次数就以幂值延长等待时间
1 | util::circuit_breaker::config cb_cfg{ |
线程池
- 相比传统线程池,增加了按照 hash_key 固定任务到某个线程
- 主要也是想给游戏服务端的存储DB使用,玩家ID作为 hash_key,这样单个玩家的数据库操作是在一个线程有序执行的
- (也可能是这个线程池设计如此的关系,觉得直接用在 apollo client 里有点重度
1 | util::thread_pool pool(8); |
TODO:
- callback 的线程问题,最简单的方式是丢到
std::async
里,目前是在网络线程同步调用的,后面根据实际使用修改 - apollo fetch 到的内容是完整的,也就是整个
namespace
下的东西都会被fetch
下来,这个最终到底是封装到 client 里合适还是丢到外面处理合适暂时还不确定 - 如果遇到配置依赖:
shop
配置检查item
配置里是否有对应的item_id
,那么遇到shop
配置更新回调先于item
配置更新传递到外部,应该如何处理