覆盖修改spring cloud的默认健康检查规则
Posted 学无止境
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了覆盖修改spring cloud的默认健康检查规则相关的知识,希望对你有一定的参考价值。
支付项目中,调用银行的支付接口时,协议不同时:
出口网关:与外围银行对接的模块(出口网关)是socket长连接与支付公司对接,该网关需要提供http接口给内部系统调用,当socket没有建立连接时(网关服务的高可用是haProxy搭建的,有些服务的socket可能未连上支付公司),此时网关的http服务不让内部其它调用系统发现。(因为,出口网关没有存储和缓存,而且交易事件必须实时的完成,返回给trade等业务系统)
gradle构建的spring cloud项目
build.gradle中增加:
compile \'org.springframework.retry:spring-retry:1.1.2.RELEASE\'
compile \'org.springframework.boot:spring-boot-actuator:1.4.5.RELEASE\'
工程结构:
将spring-cloud-consul-core中的有关健康检查的两个java文件按如下修改后,再拷贝到自己的工程中如上图。
/* * Copyright 2013-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.cloud.consul; import org.aspectj.lang.annotation.Aspect; import org.springframework.boot.actuate.autoconfigure.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.retry.annotation.EnableRetry; import org.springframework.retry.annotation.Retryable; import org.springframework.retry.interceptor.RetryInterceptorBuilder; import org.springframework.retry.interceptor.RetryOperationsInterceptor; import com.ecwid.consul.v1.ConsulClient; /** * @author Spencer Gibb */ @Configuration @EnableConfigurationProperties @ConditionalOnConsulEnabled public class ConsulAutoConfiguration { @Bean @ConditionalOnMissingBean public ConsulProperties consulProperties() { return new ConsulProperties(); } @Bean @ConditionalOnMissingBean public ConsulClient consulClient(ConsulProperties consulProperties) { return new ConsulClient(consulProperties.getHost(), consulProperties.getPort()); } @Configuration @ConditionalOnClass(Endpoint.class) protected static class ConsulHealthConfig { @Bean @ConditionalOnMissingBean @ConditionalOnEnabledEndpoint("consul") public ConsulEndpoint consulEndpoint(ConsulClient consulClient) { return new ConsulEndpoint(consulClient); } @Bean @ConditionalOnMissingBean @ConditionalOnEnabledHealthIndicator("consul") public PosConsulHealthIndicator consulHealthIndicator(ConsulClient consulClient) { return new PosConsulHealthIndicator(consulClient); } } @ConditionalOnClass({ Retryable.class, Aspect.class, AopAutoConfiguration.class }) @Configuration @EnableRetry(proxyTargetClass = true) @Import(AopAutoConfiguration.class) @EnableConfigurationProperties(RetryProperties.class) protected static class RetryConfiguration { @Bean(name = "consulRetryInterceptor") @ConditionalOnMissingBean(name = "consulRetryInterceptor") public RetryOperationsInterceptor consulRetryInterceptor( RetryProperties properties) { return RetryInterceptorBuilder .stateless() .backOffOptions(properties.getInitialInterval(), properties.getMultiplier(), properties.getMaxInterval()) .maxAttempts(properties.getMaxAttempts()).build(); } } }
/* * Copyright 2013-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.cloud.consul; import java.util.List; import java.util.Map; import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.health.Health; import com.ecwid.consul.v1.ConsulClient; import com.ecwid.consul.v1.QueryParams; import com.ecwid.consul.v1.Response; import com.ecwid.consul.v1.agent.model.Self; import com.ecwid.consul.v1.agent.model.Self.Config; import com.dxz.iosessionHelper; import com.dxz.utils.SpringUtil; /** * @author Spencer Gibb */ public class PosConsulHealthIndicator extends AbstractHealthIndicator { private ConsulClient consul; private IoSessionHelper ioSessionHelper; public PosConsulHealthIndicator(ConsulClient consul) { this.consul = consul; } private IoSessionHelper getIoSessionHelper() { if(null == ioSessionHelper) { ioSessionHelper = SpringUtil.getBean("ioSessionHelper", IoSessionHelper.class); } return ioSessionHelper; } private boolean ioSessionCheck() { return getIoSessionHelper().ioSessionCheck(); } @Override protected void doHealthCheck(Health.Builder builder) throws Exception { try { Response<Self> self = consul.getAgentSelf(); Config config = self.getValue().getConfig(); Response<Map<String, List<String>>> services = consul .getCatalogServices(QueryParams.DEFAULT); builder .withDetail("services", services.getValue()) .withDetail("advertiseAddress", config.getAdvertiseAddress()) .withDetail("datacenter", config.getDatacenter()) .withDetail("domain", config.getDomain()) .withDetail("nodeName", config.getNodeName()) .withDetail("bindAddress", config.getBindAddress()) .withDetail("clientAddress", config.getClientAddress()); if(ioSessionCheck()) { builder.up(); } else { builder.outOfService() .withDetail("description", "ioSession not available"); } } catch (Exception e) { builder.down(e); } } }
覆盖doHealthCheck()方法,增加socket连接校验返回健康检查结果给consul,其它微服务客户端感知到哪个网关服务是可用的。
以上是关于覆盖修改spring cloud的默认健康检查规则的主要内容,如果未能解决你的问题,请参考以下文章
Spring Cloud Stream 和 RabbitMQ 健康检查
spring-cloud-consul:无法覆盖 ConsulProperties 中的默认值
如何覆盖 Spring Cloud Ribbon 中的ribbon.serverListRefreshInterval 默认值?