dubbo2.7.9升级到dubbo3.0.7+nacos1.4.3+springboot2.6.6成功实践笔记

升级过程中遇到一堆的坑,不过都一一解决了,主要是版本冲突,启动失败

以下是正确配置:

springboot依赖

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.6</version>
        <relativePath/>
    </parent>

dubbo依赖

<!-- Apache Dubbo start -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>${dubbo.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo.version}</version>
            </dependency>
            <!-- Apache Dubbo end -->

nacos依赖

<!--注册中心客户端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2021.0.1.0</version>
        </dependency>
        <!--配置中心客户端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2021.0.1.0</version>
        </dependency>

nacos-client依赖

<dependency>
                <groupId>com.alibaba.nacos</groupId>
                <artifactId>nacos-client</artifactId>
                <version>2.0.4</version>
            </dependency>

升级到springboot2.6.6后,swagger2会出问题,所以需要在SwaggerConfig类中添加以下代码

@Bean
    public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
        return new BeanPostProcessor() {

            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
                if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
                    customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
                }
                return bean;
            }

            private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
                List<T> copy = mappings.stream()
                        .filter(mapping -> mapping.getPatternParser() == null)
                        .collect(Collectors.toList());
                mappings.clear();
                mappings.addAll(copy);
            }

            @SuppressWarnings("unchecked")
            private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
                try {
                    Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
                    field.setAccessible(true);
                    return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    throw new IllegalStateException(e);
                }
            }
        };
    }
SwaggerConfig完整代码
package com.dengfeng.framework.common.config;

import com.google.common.collect.Sets;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * Swagger2配置
 */
@Configuration
@EnableSwagger2
@Profile({"local", "dev", "test"})
public class SwaggerConfig {

    @Value("${spring.application.name:校园在线}")
    private String applicationName;

    @Value("${dadaodata.app.description:用于开发环境的 RestFul Api 文档}")
    private String dadaodata_app_description;

    @Value("${dadaodata.app.termsOfServiceUrl:https://www.zgxyzx.net}")
    private String dadaodata_app_termsOfServiceUrl;

    @Value("${dadaodata.app.version:v1}")
    private String dadaodata_app_version;

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .protocols(Sets.newHashSet("http"))
                .select()
                .paths(PathSelectors.any())
                .build()
                .globalOperationParameters(commonParameters())
                .apiInfo(apiInfo());
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(applicationName)
                .version(dadaodata_app_version)
                .description(dadaodata_app_description)
                .build();
    }

    /**
     * 全局默认参数配置
     */
    private List<Parameter> commonParameters() {
        List<Parameter> parameters = new ArrayList<>();
        parameters.add(new ParameterBuilder()
                .name("version")
                .description("全局默认版本号")
                .modelRef(new ModelRef("String"))
                .parameterType("path")
                .defaultValue(dadaodata_app_version)
                .required(true)
                .build());

        return parameters;
    }

    /**
     * Spring Boot 2.6.x版本引入依赖 springfox-boot-starter (Swagger 3.0) 后,启动容器会报错:
     *
     * Failed to start bean ‘ documentationPluginsBootstrapper ‘ ; nested exception…
     *
     * 原因
     * Springfox 假设 Spring MVC 的路径匹配策略是 ant-path-matcher,而 Spring Boot 2.6.x版本的默认匹配策略是 path-pattern-matcher,这就造成了上面的报错。
     * @return
     */
    @Bean
    public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
        return new BeanPostProcessor() {

            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
                if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
                    customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
                }
                return bean;
            }

            private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
                List<T> copy = mappings.stream()
                        .filter(mapping -> mapping.getPatternParser() == null)
                        .collect(Collectors.toList());
                mappings.clear();
                mappings.addAll(copy);
            }

            @SuppressWarnings("unchecked")
            private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
                try {
                    Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
                    field.setAccessible(true);
                    return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    throw new IllegalStateException(e);
                }
            }
        };
    }

}

swagger依赖

<!-- swagger2 start -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-ui</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
        </dependency>
        <!-- swagger2 end -->

上面加上了knife4j依赖,API界面更漂亮

Dobbo3服务启动后注册到nacos中,效果

Nacos Docker

还有一点非常重要,nacos启动的时候要暴露几个端口,nacos新版本用到grpc,当nacos客户端升级为2.x版本后,新增了gRPC的通信方式,新增了两个端口。这两个端口在nacos原先的端口上(默认8848),进行一定偏移量自动生成.。

比如我用docker安装暴露了4个端口,如果只暴露了8848端口,启动会报以下错误:

Nacos Server check fail, please check server 101.200.84.241 ,port 9848 is available

参考文档地址:https://nacos.io/zh-cn/docs/quick-start-docker.html

用docker镜像启动nacos2,镜像下载:Docker Hub

docker run --name nacos2 -e MODE=standalone -p 8848:8848 -p 8849:8849 -p 9848:9848 -p 9849:9849-d nacos/nacos-server

最近spring重大漏洞CVE-2022-22968会在springboot2.6.7版本中解决,下次记得升级

 漏洞说明:Spring Framework RCE, Early Announcement

异常处理

java.lang.NoSuchMethodError: com.alibaba.nacos.api.config.ConfigService.publishConfigCas(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
    


***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.apache.dubbo.metadata.store.nacos.NacosConfigServiceWrapper.publishConfigCas(NacosConfigServiceWrapper.java:65)

The following method did not exist:

    com.alibaba.nacos.api.config.ConfigService.publishConfigCas(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z

The calling method's class, org.apache.dubbo.metadata.store.nacos.NacosConfigServiceWrapper, was loaded from the following location:

    jar:file:/Users/liujunguang1/.m2/repository/org/apache/dubbo/dubbo/3.0.6/dubbo-3.0.6.jar!/org/apache/dubbo/metadata/store/nacos/NacosConfigServiceWrapper.class

The called method's class, com.alibaba.nacos.api.config.ConfigService, is available from the following locations:

    jar:file:/Users/liujunguang1/.m2/repository/com/alibaba/nacos/nacos-api/1.4.2/nacos-api-1.4.2.jar!/com/alibaba/nacos/api/config/ConfigService.class

The called method's class hierarchy was loaded from the following locations:

    com.alibaba.nacos.api.config.ConfigService: file:/Users/liujunguang1/.m2/repository/com/alibaba/nacos/nacos-api/1.4.2/nacos-api-1.4.2.jar


Action:

Correct the classpath of your application so that it contains compatible versions of the classes org.apache.dubbo.metadata.store.nacos.NacosConfigServiceWrapper and com.alibaba.nacos.api.config.ConfigService

上面的异常需要升级nacos-client

    <nacos-client.version>2.0.4</nacos-client.version>
    <dependency>
        <groupId>com.alibaba.nacos</groupId>
        <artifactId>nacos-client</artifactId>
        <version>${nacos-client.version}</version>
    </dependency>

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值