我们在库伯内特斯运行了Spring Boot服务,并且正在使用Spring Cloud库伯内特斯负载均衡器功能和RestTemboard来调用其他Spring Boot服务。我们这样做的主要原因之一是历史上的——因为之前我们使用Eureka在EC2中运行我们的服务进行服务发现,迁移后我们保持了Spring发现客户端/客户端负载平衡(更新依赖项等,以便它与Spring Cloud库伯内特斯项目一起工作)
我们有一个问题,当其中一个目标POD宕机时,java在一段时间内会多次请求失败。网noroutetohestexception(即spring负载平衡器仍在尝试发送到该pod)。
所以我有几个问题:
>
或者如果没有,我们需要添加一些其他配置来处理这个-例如重试/断路器等?
一个更普遍的问题是,Spring的客户端负载平衡为Kubernetes带来了什么好处?如果没有它,我们的服务仍然可以使用Kubernetes内置的服务/负载平衡功能调用其他服务,这应该可以解决POD自动下降的问题。Spring文档还讨论了如何从POD模式切换到SERVICE模式(https://docs.spring.io/spring-cloud-kubernetes/docs/current/reference/html/index.html#loadbalancer-对于kubernetes)。但这种服务模式不正是Kubernetes自动完成的吗?我想知道这里最简单的解决方案是否不是完全移除Spring负载平衡器?那么我们会失去什么呢?
这方面的更新:我们有了spring retry依赖项,但retry不起作用,因为默认情况下它只对get起作用,我们的大多数调用都是POST(但可以再次调用)。添加配置Spring。云负载平衡器。重试。RetryonLoperations:true修复了这一问题,因此,在第二次尝试时,应使用替代实例重试,以避免大多数失败。
我们还添加了一个RetryListener,用于在某些连接异常情况下清除服务的负载平衡器缓存:
@Configuration
public class RetryConfig {
private static final Logger logger = LoggerFactory.getLogger(RetryConfig.class);
// Need to use bean factory here as can't autowire LoadBalancerCacheManager -
// - it's set to 'autowireCandidate = false' in LoadBalancerCacheAutoConfiguration
@Autowired
private BeanFactory beanFactory;
@Bean
public CacheClearingLoadBalancedRetryFactory cacheClearingLoadBalancedRetryFactory(ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerFactory) {
return new CacheClearingLoadBalancedRetryFactory(loadBalancerFactory);
}
// Extension of the default bean that defines a retry listener
public class CacheClearingLoadBalancedRetryFactory extends BlockingLoadBalancedRetryFactory {
public CacheClearingLoadBalancedRetryFactory(ReactiveLoadBalancer.Factory<ServiceInstance> loadBalancerFactory) {
super(loadBalancerFactory);
}
@Override
public RetryListener[] createRetryListeners(String service) {
RetryListener cacheClearingRetryListener = new RetryListener() {
@Override
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) { return true; }
@Override
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {}
@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
logger.warn("Retry for service {} picked up exception: context {}, throwable class {}", service, context, throwable.getClass());
if (throwable instanceof ConnectTimeoutException || throwable instanceof NoRouteToHostException) {
try {
LoadBalancerCacheManager loadBalancerCacheManager = beanFactory.getBean(LoadBalancerCacheManager.class);
Cache loadBalancerCache = loadBalancerCacheManager.getCache(CachingServiceInstanceListSupplier.SERVICE_INSTANCE_CACHE_NAME);
if (loadBalancerCache != null) {
boolean result = loadBalancerCache.evictIfPresent(service);
logger.warn("Load Balancer Cache evictIfPresent result for service {} is {}", service, result);
}
} catch(Exception e) {
logger.error("Failed to clear load balancer cache", e);
}
}
}
};
return new RetryListener[] { cacheClearingRetryListener };
}
}
}
这种方法有什么问题吗?可以将这样的东西添加到内置功能中吗?
发生这种情况时,目标实例不应该自动删除吗?所以它可能会发生一次,但之后目标吊舱列表将被修复?
要解决这个问题,你必须使用库伯内特斯的准备和活力探测。
准备就绪将在间隔期间检查应用程序拥有的endpoint的运行状况。如果应用程序失败,它会将您的播客标记为未准备好接受流量。因此,不会有任何流量流向该POD(副本)。
如果应用程序失败,活跃度将重新启动您的应用程序,因此您的容器或我们可以说POD将再次出现,一旦我们从应用程序K8s收到200个响应,您的POD将标记为准备好接受流量。
您可以在应用程序中创建简单endpoint,根据需要提供200或204的响应。
阅读更多:https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
确保您的应用程序使用Kubernetes服务相互通信。
Application 1 > Kubernetes service of App 2 > Application 2 PODs
要启用基于库伯内特斯服务名称的负载平衡,请使用以下属性。然后负载均衡器将尝试使用地址调用应用程序,例如service-a.default.svc.cluster.local
spring.cloud.kubernetes.loadbalancer.mode=SERVICE
在Kubernetes上使用Spring云负载平衡器最典型的方法是服务发现。如果类路径上有任何DiscoveryClient,默认的Spring云负载平衡器配置将使用它来检查服务实例。因此,它只能从正在启动和运行的实例中进行选择。只需使用@EnableDiscoveryClients为Spring Boot应用程序添加注释,即可启用K8s本机服务发现。
参考:https://stackoverflow.com/a/68536834/5525824
我最近开始研究Kubernetes集群。在我们的集群中,对给定Kubernetes服务的网络调用流如下所示: 外部非K8S负载均衡器- 对于给定的服务,有两个副本。通过查看副本中容器的日志,我可以看到调用被路由到不同的pod。据我所知,我们还没有为Kubernetes中的服务明确设置任何负载平衡策略。 我有几个问题: 1)K8S是否有默认的负载平衡策略?我读过库贝-proxy和随机路由。它看起来绝
什么是负载均衡器? 负载平衡改进了跨多个计算资源(如计算机、计算机群集、网络链路、中央处理器或磁盘驱动器)的工作负载分布 NodePort不是负载平衡器。(我知道一旦流量在集群内,kube proxy就会在pod之间进行负载平衡)我的意思是,最终用户点击http://NODEIP:30111(例如)访问应用程序的URL。即使POD之间的流量是负载平衡的,用户仍然会点击一个节点,即“节点”,它是K8
我有一个包含 3 个节点的 Kubernetes 集群。 示例部署 我没有入口,但我有外部负载均衡器,可以轮询 80.11.12.10、80.11.12.11、 的流量。 所以我这样设置我的服务。 问题在于,由于现有的 kubernetes 服务负载均衡器,流量会获得两次负载均衡。除此之外,这是不必要的,它会破坏连接持久性。有没有办法强制 Kubernetes 在每个节点的本地机器 Pod 上转发
我在两个节点上运行 Kubernetes,并在两个节点上部署一个应用程序(两个 pod,每个节点一个)。 这是一个Spring Boot应用程序。它使用OpenFygnd来实现服务可发现性。在应用程序中,我定义了一个一来控制程序,它有几个API和一个从API内部调用的@Autow的@Service。 每当我对其中一个API进行请求时,Kubernetes都会使用某种负载平衡来将流量路由到其中一个p
我在pod中运行了高视频编码任务。这些任务在接收用户请求时运行,并且CPU密集型非常高。我想确保CPU使用率最低的pod应该在传入请求中接收。库伯内特斯有没有办法根据CPU使用率的百分比来平衡我的负载?
在使用Google容器引擎时,人们会推荐GCP的本机负载平衡器还是Kubernetes服务type=负载平衡器选项? 人们推荐哪一种?