我正在开发一个基于微服务的新项目。它是一个内部应用程序,只有大约 10 个微服务。我们将使用网关 API 进行身份验证,并可能使用一些微服务聚合。(可能是 Netflix zuul with Spring Boot(
我不清楚的是我们如何进行A/B测试和金丝雀测试的路由。假设我有 100 个客户端,我们想要对新版本的微服务进行 A/B 测试。客户端应用不需要更改,只需对微服务提供的功能进行内部更改。
我知道我们会建立一个(比如(v2 的新微服务。我感到困惑的是如何将(说(客户端 1-10 定向到新版本。我们需要能够集中配置它,而不是更改客户端上的任何内容。
我们知道他们的 mac 地址(以及其他识别属性(,并且可以插入我们想要识别其消息的任何类型的标头。
那么,如何将这些定向到 A/B 测试或 Canary 部署的 API v2 呢?
如果描述高级的通用方法,您可以执行以下操作:
- 您的客户需要有一些参数来唯一地标识它们。看起来你已经有了这个。
- 实现其他 API 服务(我们称之为实验 API(。此服务应至少有一个终结点,该终结点接收客户端标识属性,并说明客户端是否参与 A/B 测试。
- 在每个传入请求上,网关 API 需要使用该实验 API 终结点来确定哪个微服务版本(v1 或 v2(用于重定向/调用。
- 为了避免每次调用实验 API,您可能会在网关 API 中引入一些缓存层。作为另一种选择,您可以使用一些自定义 cookie(其中包含"实验"下的客户端(,仅在未指定该 cookie 时才调用实验 API,并将 cookie 与响应一起返回给客户端。
我在Github上发布了一个原型,展示了如何使用Zuul Gateway
实现路由。此原型仅显示如何基于 Cookie 将流量路由到同一应用程序的不同实例。您可以根据任何其他条件执行路由。 您还应该看看Spring Cloud Gateway
作为Zuul
的替代品。似乎很有前途。 https://github.com/adiesner/spring-boot-sample-ci-gateway
更简单的设置是将nginx添加到服务前面并使用split_clients方法。
http {
# ...
# application version 1a
upstream version_1a {
server 10.0.0.100:3001;
server 10.0.0.101:3001;
}
# application version 1b
upstream version_1b {
server 10.0.0.104:6002;
server 10.0.0.105:6002;
}
split_clients "${arg_token}" $appversion {
95% version_1a;
* version_1b;
}
server {
# ...
listen 80;
location / {
proxy_set_header Host $host;
proxy_pass http://$appversion;
}
}
}
https://www.nginx.com/blog/performing-a-b-testing-nginx-plus/
稍微阐述一下@Set的答案。需要在网关 API 中引入一些检测代码,以决定调用哪个下游终结点。如果且仅当分布式后端中唯一与此相关的组件是网关 API,则上述解决方案被过度设计:您只需一个库即可完成。但您可能很快就会发现您的一个或多个其他服务需要了解实验,在这种情况下,您确实需要一个独立的服务。
一般来说,构建一个健壮的实验框架是一项艰巨的任务。您很快就会遇到意想不到的问题,例如体验稳定性(如何保证回访者获得相同的体验(或如何更改分配比例(或者可能完全关闭新代码(,而无需重新启动主机应用程序。你应该研究那里的开源框架,甚至是商业服务器端的工具。(我们在变体中有一个(。