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

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

以下是正确配置:

springboot依赖


        org.springframework.boot
        spring-boot-starter-parent
        2.6.6
        
    

dubbo依赖


            
                org.apache.dubbo
                dubbo-spring-boot-starter
                ${dubbo.version}
            
            
                org.apache.dubbo
                dubbo
                ${dubbo.version}
            
            

nacos依赖


        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
            2021.0.1.0
        
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-config
            2021.0.1.0
        

nacos-client依赖


                com.alibaba.nacos
                nacos-client
                2.0.4
            

升级到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  void customizeSpringfoxHandlerMappings(List mappings) {
                List copy = mappings.stream()
                        .filter(mapping -> mapping.getPatternParser() == null)
                        .collect(Collectors.toList());
                mappings.clear();
                mappings.addAll(copy);
            }

            @SuppressWarnings("unchecked")
            private List getHandlerMappings(Object bean) {
                try {
                    Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
                    field.setAccessible(true);
                    return (List) 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 commonParameters() {
        List 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  void customizeSpringfoxHandlerMappings(List mappings) {
                List copy = mappings.stream()
                        .filter(mapping -> mapping.getPatternParser() == null)
                        .collect(Collectors.toList());
                mappings.clear();
                mappings.addAll(copy);
            }

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

}

swagger依赖


        
            com.github.xiaoymin
            knife4j-spring
        
        
            com.github.xiaoymin
            knife4j-spring-ui
        
        
            io.springfox
            springfox-swagger2
        
        
            io.springfox
            springfox-swagger-ui
        
        

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

dubbo2.7.9升级到dubbo3.0.7+nacos1.4.3+springboot2.6.6成功实践笔记_第1张图片

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

dubbo2.7.9升级到dubbo3.0.7+nacos1.4.3+springboot2.6.6成功实践笔记_第2张图片

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

dubbo2.7.9升级到dubbo3.0.7+nacos1.4.3+springboot2.6.6成功实践笔记_第3张图片

最近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

    2.0.4
    
        com.alibaba.nacos
        nacos-client
        ${nacos-client.version}
    

你可能感兴趣的:(微服务,docker,微服务,nacos,dubbo3,springboot2.6.6)