slo*_*wko 6 java docker spring-boot kubernetes spring-boot-actuator
我们有一个Spring Boot(2.0.4)应用程序,它公开了许多端点,其中一个端点使客户端可以检索有时非常大的文件(约200 GB)。该应用程序通过配置了滚动更新策略的Kubernetes部署在Pod中公开。
当我们通过将映像设置为最新版本来更新部署时,吊舱会被破坏,新的吊舱会旋转。我们的服务可满足新要求。但是,当前的请求可能并且确实会被切断,这对于下载非常大文件的客户端来说可能会很烦人。
我们可以在部署规范中配置Container Lifecycle Pre-Stop挂钩,以在通过其PID发送关闭信号给应用之前注入暂停。这有助于防止任何新流量流向已设置为“终止”的Pod。有没有一种方法可以暂停应用程序关闭过程,直到所有当前请求都已完成(这可能需要数十分钟)?
这是我们在Spring Boot应用程序中尝试过的方法:
实现一个关闭侦听器ContextCloseEvents; 不幸的是,我们无法可靠地检索活动请求列表。在关机过程的此阶段,任何可能有用的执行器指标均不可用。
通过实施HttpSessionListener和覆盖sessionCreated/Destroy方法来更新计数器来对活动会话进行计数。失败是因为方法没有在单独的线程上调用,所以始终在关闭侦听器中报告相同的值。
我们应该尝试其他策略吗?从应用程序本身或容器中,还是直接通过Kubernetes资源描述符?建议/帮助/指针将不胜感激。
编辑:我们管理集群,因此我们仅尝试通过修改的Pod规范在对部署进行托管更新期间减轻当前连接的客户端的服务中断
我们结合了上述方法来解决我们的问题。
请注意,因为我们从监控脚本将 TERM 发送到 pid 1,所以 Pod 将在此时终止,并且 TerminationGracePeriodSeconds 永远不会被命中(它是作为预防措施而存在的)
这是脚本:
#!/bin/sh
while [ "$(/bin/netstat -ap 2>/dev/null | /bin/grep http-alt.*ESTABLISHED.*1/java | grep -c traefik-ingress-service)" -gt 0 ]
do
sleep 1
done
kill -TERM 1
Run Code Online (Sandbox Code Playgroud)
这是新的 pod 规格:
containers:
- env:
- name: spring_profiles_active
value: dev
image: container.registry.host/project/app:@@version@@
imagePullPolicy: Always
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- sleep 5 && /monitoring.sh
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 20
timeoutSeconds: 3
name: app
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
resources:
limits:
cpu: 2
memory: 2Gi
requests:
cpu: 2
memory: 2Gi
imagePullSecrets:
- name: app-secret
serviceAccountName: vault-auth
terminationGracePeriodSeconds: 86400
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
393 次 |
| 最近记录: |