前言
前段时间,因项目被扫出大量漏洞,全是因为依赖版本过低,存在高中危漏洞需要升级。正好本来也有规划集群升级,因为工作量大迟迟落实不了,正好有这次修漏洞的机会,升级微服务集群。这篇文章主要记录了本人的升级记录,遇到的问题解决方法,仅供参考。
项目背景
项目微服务技术栈:Spring Boot 1.5.x 、Spring Cloud、Kafka、RabbitMq、Mysql、Eureka、Apollo、Nacos。Spring Boot 是1.5.x 版本非常老旧,Spring Cloud 版本也早就停更。根据Nacos的兼容情况,Spring Boot 的版本为2.6.13,但目前最新版是2.7.18,由于3.x跟2.x区别较大,因此决定使用2.7.18试试,Spring Cloud 版本为2021.0.5.0。
升级记录
在xml中加入依赖,过期的配置会提示:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-properties-migrator</artifactId> <scope>runtime</scope></dependency>
1、Loading class com.mysql.jdbc.Driver'. This is deprecated. The new driver class is
com.mysql.cj.jdbc.Driver’
-
需要更新Mysql驱动
2、Caused by: java.lang.IllegalStateException: Could not resolve element type of Iterable type @。。。。。web.bind.annotation.RequestParam java.util.List. Not declared?
-
@RequestParam(value = "Long[]") List projectIds
此类的代码不能再使用
3、spring.rabbitmq.publisher-confirms 过期
4、Canonical names should be kebab-case (‘-’ separated)
-
不能使用驼峰形式,用
-
隔开
5、import org.springframework.cloud.netflix.feign
修改为 import org.springframework.cloud.openfeign
6、2.6以后不允许循环依赖
spring: main: # Spring Boot 2.6以后 默认不允许循环依赖 allow-circular-references: true #允许bean覆盖 allow-bean-definition-overriding: true
7、spring.cloud.client.ipAddress 都修改为 spring.cloud.client.ip-address
8、跨域头修改
由原来的修改为
corsConfiguration.setAllowCredentials(true);corsConfiguration.addAllowedOriginPattern("*");
9、gateway 升级要注意去掉重复跨域头
spring.cloud.gateway.default-filters[0] = DedupeResponseHeader=Access-Control-Allow-Origin Access-Control-Allow-Credentials, RETAIN_FIRST
10、database配置过期
The use of configuration keys that have been renamed was found in the environment: Property source 'ApolloBootstrapPropertySources': Key: spring.datasource.data Replacement: spring.sql.init.data-locations Key: spring.datasource.platform Replacement: spring.sql.init.platform Key: spring.datasource.schema Replacement: spring.sql.init.schema-locations
修改:
sql: init: platform: mysql #执行的sql语句 data-locations: classpath:data.sql #执行的建表语句 schema-locations: classpath:schema.sql
11、Eureka 配置的修改
instance-id: ${spring.cloud.client.ip-address}:${server.port} metadata-map: user-name: ${spring.security.user.name} user-password: ${spring.security.user.password}
12、上传配置的修改
spring: servlet: #最大上传大小,MB multipart: max-file-size: 1000MB max-request-size: 1000MB
13、原有zuul适配
org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.choose(Ljava/lang/String;Lorg/springframework/cloud/client/loadbalancer/Request;)Lorg/springframework/cloud/client/ServiceInstance
增加如下Bean
@Beanpublic LoadBalancerClient blockingLoadBalancerClient(LoadBalancerClientFactory loadBalancerClientFactory) { return new BlockingLoadBalancerClient(loadBalancerClientFactory);}
14、调用接口报NoSuchMethodError: org.springframework.boot.web.servlet.error.ErrorController.getErrorPath
增加如下类
@Configurationpublic class ZuulConfiguration { /** * The path returned by ErrorController.getErrorPath() with Spring Boot < 2.5 * (and no longer available on Spring Boot >= 2.5). */ private static final String ERROR_PATH = "/error"; private static final String METHOD = "lookupHandler"; /** * Constructs a new bean post-processor for Zuul. * * @param routeLocator the route locator. * @param zuulController the Zuul controller. * @param errorController the error controller. * @return the new bean post-processor. */ @Bean public ZuulPostProcessor zuulPostProcessor(@Autowired RouteLocator routeLocator, @Autowired ZuulController zuulController, @Autowired(required = false) ErrorController errorController) { return new ZuulPostProcessor(routeLocator, zuulController, errorController); } private enum LookupHandlerCallbackFilter implements CallbackFilter { INSTANCE; @Override public int accept(Method method) { if (METHOD.equals(method.getName())) { return 0; } return 1; } } private enum LookupHandlerMethodInterceptor implements MethodInterceptor { INSTANCE; @Override public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { if (ERROR_PATH.equals(args[0])) { // by entering this branch we avoid the ZuulHandlerMapping.lookupHandler method to trigger the // NoSuchMethodError return null; } return methodProxy.invokeSuper(target, args); } } private static final class ZuulPostProcessor implements BeanPostProcessor { private final RouteLocator routeLocator; private final ZuulController zuulController; private final boolean hasErrorController; ZuulPostProcessor(RouteLocator routeLocator, ZuulController zuulController, ErrorController errorController) { this.routeLocator = routeLocator; this.zuulController = zuulController; this.hasErrorController = (errorController != null); } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (hasErrorController && (bean instanceof ZuulHandlerMapping)) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(ZuulHandlerMapping.class); enhancer.setCallbackFilter(LookupHandlerCallbackFilter.INSTANCE); // only for lookupHandler enhancer.setCallbacks(new Callback[] {LookupHandlerMethodInterceptor.INSTANCE, NoOp.INSTANCE}); Constructor<?> ctor = ZuulHandlerMapping.class.getConstructors()[0]; return enhancer.create(ctor.getParameterTypes(), new Object[] {routeLocator, zuulController}); } return bean; } }}
15、负责均衡找不到下游服务的问题
增加如下类:
public class RibbonEurekaClientConfig { @Autowired private DiscoveryClient discoveryClient; @Bean @Lazy public IPing ribbonPing() { return new DummyPing(); } @Bean @Lazy public IRule ribbonRule(IClientConfig clientConfig) { AvailabilityFilteringRule rule = new AvailabilityFilteringRule(); rule.initWithNiwsConfig(clientConfig); return rule; } @Bean @Lazy public ServerList<?> ribbonServerList(IClientConfig clientConfig) { return new ServerList<Server>() { @Override public List<Server> getInitialListOfServers() { return new ArrayList<>(); } @Override public List<Server> getUpdatedListOfServers() { List<Server> serverList = new ArrayList<>(); List<ServiceInstance> instances = discoveryClient.getInstances(clientConfig.getClientName()); if (instances != null && instances.size() == 0) { return serverList; } for (ServiceInstance instance : instances) { if (instance.isSecure()) { serverList.add(new Server("https", instance.getHost(), instance.getPort())); } else { serverList.add(new Server("http", instance.getHost(), instance.getPort())); } } return serverList; } }; }}
在Spring Boot 启动类上配置
@RibbonClients(defaultConfiguration = RibbonEurekaClientConfig.class)
16、java.lang.NoSuchMethodError: com.netflix.servo.monitor.Monitors.isObjectRegistered(Ljava/lang/String;Ljava/lang/Object;)Z
zuul里的版本太久,需要排除
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> <version>2.2.10.RELEASE</version> <!--zuul里的版本太久,要排除,否则报 java.lang.NoSuchMethodError: com.netflix.servo.monitor.Monitors.isObjectRegistered(Ljava/lang/String;Ljava/lang/Object;)Z --> <exclusions> <exclusion> <groupId>com.netflix.servo</groupId> <artifactId>servo-core</artifactId> </exclusion> </exclusions> </dependency>
转自:
https://blog.csdn.net/weixin_40972073/article/details/134730145