springboot升級到2.6.x和2.7.x 相容hystrix

可可西里發表於2024-01-22

一、pom.xml需要引入的依賴
二、專案開啟熔斷器開關
  2.1 註解方式
  2.2 xml方式
三、依賴類缺失問題
四、版本匹配安全檢查問題
五、測試驗證
六、結論

一、pom.xml需要引入的依賴

pom.xml

 <!-- springboot升級到2.6.7,同樣適用於2.7.0,2.7.18等 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.7</version><relativePath/> <!-- lookup parent from repository --></parent>  <!-- hystrix需要升級到2.x以上版本 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId><version>2.2.10.RELEASE</version></dependency><!-- 升級後執行時缺失依賴 --><dependency><groupId>org.hdrhistogram</groupId><artifactId>HdrHistogram</artifactId><version>2.1.12</version></dependency>

二、專案開啟熔斷器開關

2.1 註解方式

@EnableHystrix

@EnableCircuitBreaker

注:專案啟動類中加上以上註解,以上兩者取其一即可;

2.2 xml方式

以上註解方式底層就是例項化此類:

三、依賴類缺失問題

此時執行專案將報以下錯誤:

errpr.log

報錯原因是缺失特定路徑下的類org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata,如下所示:

需要解決此問題,自定義此類即可,注意一定要定義成框架所需的包路徑(package org.springframework.boot.context.properties;):

ConfigurationBeanFactoryMetadata.java

 package org.springframework.boot.context.properties;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanDefinition;import org.springframework.beans.factory.config.BeanFactoryPostProcessor;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.beans.factory.support.GenericBeanDefinition;import org.springframework.beans.factory.support.RootBeanDefinition;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.core.annotation.AnnotationUtils;import org.springframework.util.ClassUtils;import org.springframework.util.ReflectionUtils;import java.lang.annotation.Annotation;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;import java.util.concurrent.atomic.AtomicReference;/** * @Author: mingming.chen * @Date: 2024/1/15 14 26 * @Description: **/public class ConfigurationBeanFactoryMetadata implements BeanFactoryPostProcessor {private ConfigurableListableBeanFactory beanFactory;private Map<String, MetaData> beans = new HashMap<String, MetaData>();@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)throws BeansException {this.beanFactory = beanFactory;for (String name : beanFactory.getBeanDefinitionNames()) {BeanDefinition definition = beanFactory.getBeanDefinition(name);String method = definition.getFactoryMethodName();String bean = definition.getFactoryBeanName();if (method != null && bean != null) {this.beans.put(name, new MetaData(bean, method));}}}public <A extends Annotation> Map<String, Object> getBeansWithFactoryAnnotation(            Class<A> type) {Map<String, Object> result = new HashMap<String, Object>();for (String name : this.beans.keySet()) {if (findFactoryAnnotation(name, type) != null) {result.put(name, this.beanFactory.getBean(name));}}return result;}public <A extends Annotation> A findFactoryAnnotation(String beanName,                                                          Class<A> type) {Method method = findFactoryMethod(beanName);return (method == null ? null : AnnotationUtils.findAnnotation(method, type));}private Method findFactoryMethod(String beanName) {if (!this.beans.containsKey(beanName)) {return null;}final AtomicReference<Method> found = new AtomicReference<Method>(null);MetaData meta = this.beans.get(beanName);final String factory = meta.getMethod();Class<?> type = this.beanFactory.getType(meta.getBean());ReflectionUtils.doWithMethods(type, new ReflectionUtils.MethodCallback() {@Overridepublic void doWith(Method method)throws IllegalArgumentException, IllegalAccessException {if (method.getName().equals(factory)) {found.compareAndSet(null, method);}}});return found.get();}private static class MetaData {private String bean;private String method;MetaData(String bean, String method) {this.bean = bean;this.method = method;}public String getBean() {return this.bean;}public String getMethod() {return this.method;}}}

四、版本匹配安全檢查問題

此時,同樣啟動專案,報以下錯誤,並中斷程式:

 

 

如上所示,由於spring-cloud-starter-netflix-hystrix 2021年後不更新,此依賴包對應的springCloud版本和springboot版本不匹配,會報版本不匹配異常,需要禁用安全檢查功能,如下配置在application.yml檔案中:

spring:
  cloud:
    compatibility-verifier:
       enabled: false

檢查配置說明:

相容性驗證器是Spring Cloud框架中的一個功能,用於確保所使用的Spring Boot版本與Spring Cloud版本相容。當Spring Boot版本與Spring Cloud版本不相容時,可能會導致應用程式在執行時出現問題。

在上述程式碼中, cloud.compatibility-verifier.enabled屬性被設定為 false,意味著禁用了相容性驗證器。這意味著應用程式將不再執行Spring Boot與Spring Cloud版本的相容性檢查。

禁用相容性驗證器可能會導致以下問題:

  1. 不相容的Spring Boot和Spring Cloud版本可能導致應用程式在執行時出現錯誤或異常。
  2. 可能會錯過一些Spring Cloud提供的新功能或修復的問題。

因此,在禁用相容性驗證器之前,應該確保所使用的Spring Boot版本與Spring Cloud版本相容,並且瞭解可能的風險和影響。

五、測試驗證

  1. 熔斷;
  2. 降級;
  3. 執行緒池隔離:併發數超過設定執行緒池個數請求進行降級;

六、結論

完成以上前四步即可在springboot2.6.x和2.7.x使用hystrix元件。


來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70036623/viewspace-3004684/,如需轉載,請註明出處,否則將追究法律責任。

相關文章