ECS 跨语言内网服务发现
0x01 前言
最近接手 Manta-Data-Service 项目,调用方反馈偶尔出现 timeout。分析发现问题如下
1、Staging 容器配置较低(0.25C 0.5M)
服务主要通过聚合查询来实现,复杂计算和操作都在 clickhouse 中 临时或提前 计算。因此业务代码本身并不会消耗太多资源。然而 Java SpringBoot 通常会占用较多的内存可能会存在 Cpu / Mem 压力;根据监控图的观察发现在超时时间点附近发生了任务停止和重启的情况。
值得注意的是,在生产环境中配置稍微大一些的情况,并没有出现启问题。所以我们尝试将配置稍微增加至 0.5C 1M,并观一段时间是否还会出现重启情况。
2、服务之间使用外网域名方式请求
服务都在 ecs 中应该是可以优化成内网互相访问,但 Manta-Data-Service 只是一个普通的 SpringBoot 项目并未引入微服务相关组件通过 Consul 互相发现内网地址,所以尝试着使用AWS的内网互相访问方案;
0x01 方案介绍
AWS提供两种自带的服务发现方式,可以实现跨语言互相服务发现内网地址。
- ECS Service Connect 免费,专注于容器之间的本地通信,类似云原生中的 SideCar,特别适用于在容器化环境下部署的微服务架构,以提供更快速和安全的通信。
- Service Discovery 收费,适用于更广泛的场景,包括容器服务、Lambda 函数、EC2 实例等,提供了一种统一的方式来发现并连接到这些服务。
本次选择 ECS Service Connect 方案,目前服务都在 ECS 内,仅仅需要创建一个 namespace 即可。而 ServiceDiscovery 需要单独的计费。
ALB 虽然也支持创建内网的地址,但是ALB更多的是负载均衡的应用场景,而且 ALB 的访问流程【容器 → ALB → 容器】会多转发一次。而服务发现只是 【容器 → 容器】
0x02 流程
1、在 AWS Cloud Map 中 创建一个新的 Namespace,Instance discovery 选择 API calls and DNS queries in VPCs,并选择对应环境的 VPC
2、找到已存在并需要提供内网地址的服务(Provider) manta-data-service 点击 update service,在 Service Connect tab中勾选 Turn on Service Connect 并选择 Client And Service,Namespace 中选择刚才建立的 namespace,并在 configuration 中输入 endpoint、dns、port 等,最后 update service;
Client side only 只需要需要访问其他服务,并不需要暴露自己的服务
Client and server 暴露自己服务的 endpoints 并且可以 connect 其他服务
若 Client and server 是 Disabled 状态无法勾选,则说明对应 Service 的 Task Definition 中 Port Mapping 配置有误,比如没有选择协议。需要把 App protocol 设置为 HTTP 等,不能用 None
3、在更新的 Service 中打开 Configuration Tab 中可以看到我们的内网 endpoint 并复制下来。
4、更新调用端的 Service,同样在 Service Connect tab中选择 Client side only,并选择相同的 Namespace 即可。
5、更新调用端代码中的请求地址为 内网 endpoint,发布并请求测试。