HZERO微服务平台10: 代码分析之admin服务刷新路由、权限、swagger的过程 .md


目录
  • 整体流程
  • 权限刷新
    • 自动刷新权限
    • 手动刷新权限
    • 权限刷新报错: parse_permission_data.failure
  • 路由刷新
    • 路由配置
    • 如果开启了context-path, 路由配置需注意
    • 业务服务路由的name或path重复
    • Using JHipster in production

      路由刷新

      路由配置

      ChoerodonRouteData choerodonRouteData = new ChoerodonRouteData();
      choerodonRouteData.setName(environment.getProperty("hzero.service.current.name", "demo"));
      choerodonRouteData.setPath(environment.getProperty("hzero.service.current.path", "/demo/**"));
      choerodonRouteData.setServiceId(environment.getProperty("hzero.service.current.service-name", "demo"));
      
      • choerodonRouteData.name: 路由名称, gatewayRoute的标识,对应gatewayRoute的id字段
      • choerodonRouteData.path: 路由的路径;
      • choerodonRouteData.serviceId: 通过实测、查看代码, 业务服务的这个配置无效; 虽然无效, 但是也不能不设置, 否则程序启动报错, bean实例化失败;
      admin刷新路由的时候, 会把路由配置里的serviceId设置为serviceName: 
      ParseRouteServiceImpl#executeRefreshRoute
      data.setServiceId(serviceName);
      

      如果开启了context-path, 路由配置需注意

      //如果开启了context-path, 这里的路径必须和context-path保持一致
      choerodonRouteData.setPath(environment.getProperty("hzero.service.current.path", "/demo-qxx/**"));
      //这里设置为false
      choerodonRouteData.setStripPrefix(false);
      

      业务服务路由的name或path重复

      新服务注册的路由如果和已有服务重复, 新服务会注册不上路由, 业务服务的日志里没有任何提示; admin服务里会info:

      ParseRouteServiceImpl#executeRefreshRoute
      LOGGER.info("route conflict, try to modify it on the interface, cause: {}", cause.toString());
      

      路由被占用, 服务路由注册失败, swagger里会看不到服务, 普通开发者很难排查问题;
      最终采用的解决办法: 服务启动时路由注册成功才能启动(hzero原版检查健康状态为up就能启动)

      手动刷新路由报错: http transport failed, ExceptionResponse: For input string: "80,80"

      dev环境正常, prod环境访问服务时报错error.permission.routeNotFound, 路由管理能看到路由, 手动刷新路由报错:

      refresh service route error, serviceName=hw-platform, ex=fetch failed, instance: hw-platform, ex=http transport failed, ExceptionResponse: For input string: "80,80"
      

      admin报错代码位置:

      StringHttpTransporter#transport
      ExceptionResponse response = objectMapper.readValue(body, ExceptionResponse.class);
      if (response != null && response.getFailed()) {
          throw new RestClientException("http transport failed, ExceptionResponse: " + response.getMessage());
      }
      

      服务报错:

      java.lang.NumberFormatException: For input string: "80,80"
          at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) ~[na:1.8.0_272]
          at java.lang.Integer.parseInt(Integer.java:580) ~[na:1.8.0_272]
          at java.lang.Integer.parseInt(Integer.java:615) ~[na:1.8.0_272]
          at ....swagger.controller.CustomController.componentsFrom(CustomController.java:145) ~[starter-core-2.0.0.RELEASE.jar!/:2.0.0.RELEASE]
      

      代码位置:

      ...swagger.controller.CustomController#componentsFrom
      String port = request.getHeader("X-Forwarded-Port");
      
      if (hasText(port)) {
          builder.port(Integer.parseInt(port));
      }
      

      报错原因: X-Forwarded-Port=80,80;
      修复方法: 加try..catch, 重置为-1;