Springboot监控之一:SpringBoot四大神器之Actuator之2--覆盖修改spring cloud的默认的consul健康检查规则

支付项目中,调用银行的支付接口时,协议不同时:

Springboot监控之一:SpringBoot四大神器之Actuator之2--覆盖修改spring cloud的默认的consul健康检查规则

出口网关:与外围银行对接的模块(出口网关)是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'

工程结构:

Springboot监控之一:SpringBoot四大神器之Actuator之2--覆盖修改spring cloud的默认的consul健康检查规则

将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,其它微服务客户端感知到哪个网关服务是可用的。

上一篇:Springboot监控之一:SpringBoot四大神器之Actuator之2--springboot健康检查


下一篇:SpringBoot四大神器之auto-configuration