SpringCloud 微服务集群升级记录(1.5.x-2.7.18)

news2024/11/28 16:53:35

前言

前段时间,因项目被扫出大量漏洞,全是因为依赖版本过低,存在高中危漏洞需要升级。正好本来也有规划集群升级,因为工作量大迟迟落实不了,正好有这次修漏洞的机会,升级微服务集群。这篇文章主要记录了本人的升级记录,遇到的问题解决方法,仅供参考。

项目背景

项目微服务技术栈: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

@Bean
public LoadBalancerClient blockingLoadBalancerClient(LoadBalancerClientFactory loadBalancerClientFactory) {
   return new BlockingLoadBalancerClient(loadBalancerClientFactory);
}

14、调用接口报NoSuchMethodError: org.springframework.boot.web.servlet.error.ErrorController.getErrorPath

增加如下类


@Configuration
public 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>

基于Spring Boot 3.1.0 系列文章

  1. Spring Boot 源码阅读初始化环境搭建
  2. Spring Boot 框架整体启动流程详解
  3. Spring Boot 系统初始化器详解
  4. Spring Boot 监听器详解
  5. Spring Boot banner详解
  6. Spring Boot 属性配置解析
  7. Spring Boot 属性加载原理解析
  8. Spring Boot 异常报告器解析
  9. Spring Boot 3.x 自动配置详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1295700.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

案例053:基于微信小程序的乐室预约系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

如何快速完成企业私有云部署

快解析赋能企业私有云部署 ​ 很多企业形成了以总部为中心的多点生产体系结构&#xff0c;并借助网络化办公工具搭建跨区域协同办公系统&#xff0c;满足总部与分支机构间的信息互通&#xff0c;进而促进异地业务的信息共享&#xff0c;提高办公处理效率和综合管理水平。 北…

redis-学习笔记(string)

redis 中的字符串, 是按照二进制的方式存储和读取的, 即存啥取啥, 所以一般不会出现乱码问题 (乱码问题是因为存储和读取时使用的编码方式不一样, 但是 redis 没有编码转换) redis 限制了 string 的大小 : 512M, 因为 单线程模型 希望进行的操作能够比较快速, 越大越慢 set key…

基于Java技术的选课管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

uniapp实战 —— 弹出层 uni-popup (含vue3子组件调父组件的方法)

效果预览 弹出的内容 src\pages\goods\components\ServicePanel.vue <script setup lang"ts"> // 子组件调父组件的方法 const emit defineEmits<{(event: close): void }>() </script><template><view class"service-panel"…

uniapp-实现一级二级职位选择,完整页面!!!

一、需求 该页面实现的功能有&#xff1a; 该页面是左侧为一级&#xff0c;右侧为二级&#xff1b;可以搜索职位进行选择&#xff1b;底部显示已选的岗位&#xff0c;点击每一项会删除&#xff1b;右侧的二级岗位&#xff0c;点击时会选中&#xff0c;再次点击会取消&#xf…

Qt 5.15.2 三维显示功能

Qt 5.15.2 三维显示功能 三维显示效果&#xff1a; .pro项目文件 QT core gui opengl 3dcore 3drender 3dinput 3dextrasgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c17# You can make your code fail to compile if it uses deprecated APIs. # In ord…

“我要报名”参观双十二外贸电商节,报名方式都在这!

双十二外贸电商节深圳进出口贸易博览会 2023年12月11-12日 深圳福田会展中心 近1万方展览面积 30000专业观众 跨境选品 外贸采购 行业趋势 人才对接 ▼▼▼▼ 展会时间 2023年12月11日-12日 展会地点 深圳福田会展中心 双十二外贸电商节暨2023深圳进出口贸易博览会选…

更多内窥镜维修技能学习与交流可关注西安彩虹

内窥镜结构及光学成像原理 众多品牌的硬镜其内部结构基本相似&#xff08;如下图&#xff09;&#xff0c;最关键的在于不同用途的硬镜在其结构上发生变化&#xff0c;包括光学成像系统和机械结构。光学成像系统由物镜系统、转像系统、目镜系统三大系统组成。 工作原理 被观察…

发布“最强”AI大模型,股价大涨,吊打GPT4的谷歌股票值得投资吗?

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 谷歌在AI领域的最新进展&#xff0c;引发投资者关注 在谷歌-C(GOOGL)谷歌-A&#xff08;GOOG&#xff09;昨日发布了最新的AI大模型Gemini后&#xff0c;其股价就出现了大幅上涨&#xff0c;更是引发了投资者的密切关注&a…

将输入的字符串反向输出(c语言)

#include<stdio.h> #include<string.h> int main() {int i, j, k;char s[50], temp;gets(s);//输入k strlen(s);//计算字符的长度//反向输出for (i 0, j k - 1;i < k / 2;i, j--){temp s[i];s[i] s[j];s[j] temp;}puts(s);//输出 }

Ubuntu22.04安装和卸载软件的命令行

一、安装 sudo apt install xxx 二、卸载 sudo apt remove xxx 三、卸载依赖包(可选) 第二步软件卸载之后&#xff0c;有一些依赖包没有被卸载。可以使用sudo apt autoremove xxx来卸载。如果不卸载应该也没什么影响

数据结构线性表-栈和队列的实现

1. 栈(Stack) 1.1 概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 …

周星驰 互联网3.0 团队下个月将上线独立 App

2023年12月7日&#xff0c;新浪科技报道指出&#xff0c;周星驰旗下的互联网3.0团队透露&#xff0c;Moonbox&#xff0c;这家周星驰创立的互联网3.0初创公司&#xff0c;计划在明年1月份完成Moonbox App的上线&#xff0c;届时该应用将免费向用户提供服务。 目前&#xff0c;…

进制 + 原码,反码,补码

进制转换 整数部分 小数部分 原码 反码 补码 原码转补码&#xff1a; 左边和右边第一个1不变&#xff0c;中间取反。-0 除外。 计算机系统中数值一律用补码来存储的原因 其他 术语 进制表 进制数的表示 详细教程可转 爱编程的大丙

GEE:不同方向的线性检测算子

作者:CSDN @ _养乐多_ 本文将介绍在 Google Earth Engine(GEE)平台上,使用不同方向的线性检测算子进行卷积操作的代码框架、核心函数和多种卷积核,比如 E-W、NE-SW、N-S、NW-SE 方向检测算子等。 结果如下图所示, 文章目录 一、定向检测算子二、完整代码三、代码链接一…

机器人纯阻抗控制接触刚性环境

问题描述 在机器人学中&#xff0c;阻抗控制是一种常用的控制策略&#xff0c;用于管理机器人在与环境交互时的运动和力。阻抗控制背后的关键概念是将环境视为导纳&#xff0c;而将机器人视为阻抗。 纯阻抗控制接触刚性环境时&#xff0c;机器人的行为方式主要受其阻抗参数的…

MeteoInfo-Java解析与绘图教程

MeteoInfo-Java解析与绘图教程(四) 上文我们说到,将地图叠加在色斑图上,但大部分都是卫星绘图,现在开始讲解micaps数据绘图,同样也是更多自定义 配置 首先我们解析micaps数据,将之前学到的东西拿过来绘图 MeteoDataInfo meteoDataInfo new MeteoDataInfo(); meteoDataInfo.o…

机器学习---集成学习的初步理解

1. 集成学习 集成学习(ensemble learning)是现在非常火爆的机器学习方法。它本身不是一个单独的机器学 习算法&#xff0c;而是通过构建并结合多个机器学习器来完成学习任务。也就是我们常说的“博采众长”。集 成学习可以用于分类问题集成&#xff0c;回归问题集成&#xff…

luceda ipkiss教程 43:画渐变圆弧型波导

案例分享&#xff1a; from si_fab import all as pdk import ipkiss3.all as i3 from ipcore.properties.restrictions import RestrictTuple from ipkiss.geometry.shapes.modifiers import __ShapePathBase__ import numpy as np from math import atan2class ShapePathTa…