Nacos1.X升级到2.0

188 阅读2分钟

由于漏洞扫描出来发现nacos1.x版本可以跳过登录获取信息,所以必须得升级到支持鉴权的2.0版本,考虑到涉及模块以及改动过多,因此记录一下

依赖升级

  1. spring-boot-starter-parent: 2.1.10.RELEASE-->2.3.12.RELEASE
  2. spring-cloud-release.version: Greenwich.SR4-->Hoxton.SR12
  3. spring.cloud.alibaba.version: 2.1.1.RELEASE-->2.2.7.RELEASE
  4. jackson-databind: 2.9.10.6-->2.10.0
  5. <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    

Nacos服务端配置

  1. 在nacos中创建新用户
  2. 创建新角色给与读写权限,并跟新用户做绑定(必须要给写权限,否则服务会注册不进来)
  3. 创建命名空间,不能将配置放到public中,否则会报错

微服务nacos客户端配置调整

  1. management.endpoints.web.exposure.include: /refresh-->refresh

    management:
      endpoints:
        web:
          exposure:
            include:
              - refresh
              - info
              - health
    
  2. spring.cloud.nacos.discovery.username: nacos_user

  3. spring.cloud.nacos.discovery.password: nacos_user@123

  4. spring.cloud.nacos.discovery.namespace:

    spring:
      cloud:
        nacos:
          discovery:
            username: ${ENV_NACOS_USERNAME:nacos_user}
            password: ${ENV_NACOS_PASSWORD:nacos_user@123}
            namespace: ${ENV_NACOS_NAMESPACE:nacos}
    
  5. spring.cloud.nacos.config.username: hotline

  6. spring.cloud.nacos.config.password: hotline@Yunli123

  7. spring.cloud.nacos.config.namespace:

    spring:
      cloud:
        nacos:
          config:
            username: ${ENV_NACOS_USERNAME:nacos_user}
            password: ${ENV_NACOS_PASSWORD:nacos_user@123}
            namespace: ${ENV_NACOS_NAMESPACE:nacos}
    
  8. server.use-forward-headers: true --> server.forward-headers-strategy: native

Nacos参考版本对照

FQ

  1. 出现org.reflections.ReflectionsException: could not create Vfs.Dir from url, no matching UrlType was found [file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/libatk-wrapper.so]的错误

    • 需要升级tomcat到8_5_81版本
  2. 出现java.lang.NoSuchMethodError: feign.Request.requestBody()Lfeign/Request$Body

    • feign调用问题,需要升级io.github.openfeign:feign-httpclient版本(可以不指定版本,自动跟随当前依赖的版本)

      <dependency>
          <groupId>io.github.openfeign</groupId>
          <artifactId>feign-httpclient</artifactId>
          <version>10.10.1</version>
      </dependency>
      
  1. 会出现登录用户相关的redis缓存反序列异常

    • 需要手动清理用户缓存,重新登录

      #== 批量删除用户会话相关key        
      #!/bin/bash
      redis_comm=/usr/local/redis-5.0.13/src/redis-cli
      for del_key in 'access:' 'auth_to_access:' 'auth:' 'refresh_auth:' 'access_to_refresh:' 'refresh:' 'refresh_to_access:' 'client_id_to_access:' 'uname_to_access:' 'spring:session:'; do
        t_host=127.0.0.1
        t_port=6001
        t_pass=123456
        echo "Search KEY prefix: $del_key..." && \
        $redis_comm --no-auth-warning -a $t_pass \
          -c --cluster call $t_host:$t_port \
          keys $del_key* | \
            grep -v Calling | grep -v ': ' | sort -d | \
            while read line; do
              echo "redis-cli --no-auth-warning -a $t_pass -c --cluster call $t_host:$t_port del $line"
              redis-cli --no-auth-warning -a $t_pass -c --cluster call $t_host:$t_port del $line
            done
        echo "End delete $del_key."
      done
      
    1. Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present]文件上传报错

      • 原因:MultiPartInputStreamParser已经被标记为过时,RequestWrapperFilter过滤器将原有的请求头过滤掉了

        • 通过对比调用方的文件流和接收方的文件流,接收方文件流开头位置明显要比调用方的文件要大
      • 参考资料

        1. MissingServletRequestPartException类解析
        2. Spring Boot升级后之文件上传坑
        3. [upload file springboot Required request part 'file' is not present](stackoverflow.com/questions/4…)
      • 解决方案

        // RequestWrapperFilter添加文件上传识别
        @Autowired
        private MultipartResolver multipartResolver;
            
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException , IOException {
            ServletRequest requestWrapper = null;
            String contentType = request.getContentType();
            if (contentType != null && contentType.contains(MediaType.MULTIPART_FORM_DATA_VALUE)) {
                requestWrapper = multipartResolver
                    .resolveMultipart((HttpServletRequest) request);
            } else if (request instanceof HttpServletRequest) {
                requestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) request);
            }
            if (null == requestWrapper) {
                log.error("过滤器包装request失败!将返回原来的request");
                chain.doFilter(request, response);
            } else {
                // log.info("过滤器包装request成功");
                chain.doFilter(requestWrapper, response);
            }
        }