首页 > 其他分享 >【Solon 框架】使用国产化框架 Solon Cloud Gateway 替换 Spring Gateway

【Solon 框架】使用国产化框架 Solon Cloud Gateway 替换 Spring Gateway

时间:2025-01-16 15:22:18浏览次数:1  
标签:CommonResult 框架 Mapping return Solon solon Gateway 路由

# 国产化框架 Solon

说明

在「使用国产化框架 Solon 的一些开发经验」中提到,我们只是在平台的一个应用开始使用 Solon 框架,并非一次性的完全替换。但随着 solon cloud gateway 官方版本发布,替换Spring Gateway 也成为可能,于是开始相关的替换工作。

我们的网关主要提供了统计授权和鉴权的功能,及最基础的服务路由能力。另外系统中个问卷功能是对外提供服务的,当时为了提供对外服务和减少Gateway的路由判断逻辑,增加一个api-gateway。

此次使用 solon gateway 进行替换需要完整的实现旧有Spring Gateway的功能,同时想利用 solon 的本地 gateway 的路由分组功能合并api-gateway。

一样的,在开发前,需要完整阅读,Solon Gateway 的官网文档 (https://solon.noear.org/article/804)。一样的文档说明简单,集成也不难。

Solon 版本:3.0.5

实现过程

引入依赖包

dependencies {
    implementation platform(project(":ficus-parent"))

    implementation("org.noear:solon-web")
    implementation("org.noear:nacos2-solon-cloud-plugin")
    implementation("org.noear:solon.cloud.gateway")
}

注意:为了简单起见,已经省去其他依赖;使用ficus-parent进行统一的版本管理,如果没有使用版本管理,添加对应依赖时需要设置版本号。

通用Web授权

1、管理端授权

提供用户密码授权和基于Token的切换租户。

@Api("管理端授权服务")
@Component(tag = "adminApi")
@Mapping("/auth")
publicclassAdminAuthController {
@Injectprivate AdminAuthService service;

@Post
@Mapping("login")
@ApiOperation("login")
public CommonResult<UserLoginRes> login(@Body LoginReq loginReq) {
    return CommonResult.success(service.login(loginReq));
  }

@Post
@Mapping("changeLoginOrg")
@ApiOperation("changeLoginOrg")
public CommonResult<UserLoginRes> changeLoginOrg(@Body ChangeOrgReq changeOrgReq) {
    returnnull;
  }
}

2、应用端授权

提供基于域名的租户识别,用户密码授权及手机授权和用户注册等功能。

@Api("应用端授权服务")
@Component(tag = "appApi")
@Mapping("/auth")
publicclassAppAuthController {
@Injectprivate AppAuthService authService;

@Post
@Mapping("/getOrgByDomain")
@ApiOperation("getOrgByDomain")
public CommonResult<SimpleOrgRes> getOrgByDomain(@Body GetOrgReq getOrgReq) {
    return CommonResult.success(authService.getOrgByDomain(getOrgReq));
  }

@Post
@Mapping("/login")
@ApiOperation("login")
public CommonResult<MemberLoginRes> login(Context context, @Body LoginReq loginReq) {
    Retret= checkLoginReq(loginReq);
    if (ret.isFail()) {
      ErrorCodeerror= ret.getAs("error");
      return CommonResult.error(error);
    }

    return authService.login(context, loginReq);
  }

@Post
@Mapping("/smsLogin")
@ApiOperation("smsLogin")
public CommonResult<MemberLoginRes> smsLogin(Context context, @Body SmsLoginReq smsLoginReq) {
    Retret= checkSmsLoginReq(smsLoginReq);
    if (ret.isFail()) {
      ErrorCodeerror= ret.getAs("error");
      return CommonResult.error(error);
    }

    return authService.smsLogin(context, smsLoginReq);
  }

@Post
@Mapping("/register")
@ApiOperation("register")
public CommonResult<MemberLoginRes> register(Context context, @Body RegisterReq registerReq) {
    return authService.register(context, registerReq);
  }

@Post
@Mapping("/sendSms")
@ApiOperation("sendSms")
public CommonResult<Boolean> sendSms(Context context, @Body SendSmsReq sendSmsReq) {
    return authService.sendSms(context, sendSmsReq);
  }
}

3、路由分组

管理端路由分组

/**
 * @author airhead
 */
@Mapping("/**")
@Component
publicclassAdminGatewayextendsGateway {
@Override
protectedvoidregister() {
    // admin的异常抛出,可能包含SQL,起码更详细
    filter(-1, newAdminExceptionFilter());
    filter(0, newTenantFilter());

    addBeans(bw -> "adminApi".equals(bw.tag()));
  }
}

应用端路由分组

@Mapping("/app-api/**")
@Component
publicclassAppGatewayextendsGateway {
@Override
protectedvoidregister() {
    // app的异常抛出不应该暴露SQL等
    filter(-1, newAppExceptionFilter());
    filter(0, newTenantFilter());

    addBeans(bw -> "appApi".equals(bw.tag()));
  }
}

响应式路由

1、实现

通过RouteFilterFactory定制路由过滤规则,实现不同类型的接口过滤。

@Component
@Slf4j
publicclassAuthFilterFactoryimplementsRouteFilterFactory {
publicstaticfinalStringADMIN="admin";
publicstaticfinalStringAPP="app";
publicstaticfinalStringOPEN="open";

@Injectprivate JwtConfig jwtConfig;
@Injectprivate AdminAuthConfig adminAuthConfig;
@Injectprivate AdminAuthService adminAuthService;

@Injectprivate AppAuthConfig appAuthConfig;
@Injectprivate AppAuthService appAuthService;

@Injectprivate OpenAuthConfig openAuthConfig;
@Injectprivate OpenAuthService openAuthService;

publicstatic Completable error(ExContext ctx, ErrorCode errorCode) {
    StringresultStr= ONode.stringify(CommonResult.error(errorCode));
    ctx.newResponse().header("Content-Type", "application/json;charset=UTF-8");
    ctx.newResponse().body(Buffer.buffer(resultStr));
    if (errorCode.getCode() < HTTP_STATUS_MAX) {
      // http status的正常范围的错误
      ctx.newResponse().status(errorCode.getCode());
    } else {
      ctx.newResponse().status(HTTP_INTERNAL_SERVER_ERROR);
    }

    return Completable.complete();
  }

@Override
public String prefix() {
    return"Auth";
  }

@Override
public ExFilter create(String config) {
    if (ADMIN.equals(config)) {
      returnnewAdminAuthFilter(jwtConfig, adminAuthConfig, adminAuthService);
    } elseif (APP.equals(config)) {
      returnnewAppAuthFilter(jwtConfig, appAuthConfig, appAuthService);
    } elseif (OPEN.equals(config)) {
      returnnewOpenAuthFilter(jwtConfig, openAuthConfig, openAuthService);
    } else {
      returnnewEmptyAuthFilter();
    }
  }

/** 默认的空鉴权 */
publicstaticclassEmptyAuthFilterimplementsExFilter {
    publicEmptyAuthFilter() {}

    @Override
    public Completable doFilter(ExContext ctx, ExFilterChain chain) {
      log.info("empty filter");
      return error(
          ctx,
          ErrorCode.builder()
              .code(HTTP_NOT_FOUND)
              .error(NOT_FOUND_ERROR)
              .msg(NOT_FOUND_ERROR)
              .build());
    }
  }
}

注意:这里AdminAuthFilter、AppAuthFilter和OpenAuthFilter未提供实现,可参考EmptyAuthFilter实现具体业务逻辑,或者参考官网例子。
2、配置

solon.cloud:
  nacos:
    server:${NACOS_SERVER:127.0.0.1:8848}
gateway:
    httpClient:
      responseTimeout:180#单位:秒
    routes:
      # app-api 用index=-1
      -id:topcloud-oa-api
        target:lb://topcloud-oa
        index:-1
        predicates:
          -Path=/OA/app-api/**
        filters:
          -Auth=app

      # open-api 用index=-1
      -id:topcloud-uac-open
        target:lb://topcloud-uac
        index:-1
        predicates:
          -Path=/UAC/open-api/**
        filters:
          -Auth=open

      # admin-api 用index=0
      -id:topcloud-uac-admin
        target:lb://topcloud-uac
        index:0
        predicates:
          -Path=/UAC/**
        filters:
          - Auth=admin

注意:3.0.5 版本如果路由存在包含关系,必须指定index,越具体的地址优先级要越高优先级(也就是index越小)。

可能碰到的问题

1、端口冲突

如果使用较低版本的 solon 时,提示端口冲突时,注意排除 solon-boot-xxx。

implementation("org.noear:solon-web") {
            exclude group: "org.noear", module: "solon-boot-smarthttp"
        }

2、路由匹配未按预期

3.0.5 版本如果路由存在包含关系,必须指定index,越具体的地址优先级要越高优先级(也就是index越小)。
配置多个 predicates 的 Path导致路由无法匹配

3.0.5 版本不支持配置多个路由的匹配,3.0.6版本将支持,需要匹配多个Path时,配置多个路由。
效果

新版的 Solon Gateway 已经在开发线稳定运行一个多月,另外内存使用方面比Spring Gateway 少了五百兆左右。

• Spring-gateway

• Solon-gateway

原创 CrazyAirhead 发强CrazyAirhead

标签:CommonResult,框架,Mapping,return,Solon,solon,Gateway,路由
From: https://www.cnblogs.com/o-O-oO/p/18675031

相关文章

  • 探秘AutoGen框架:从入门到实践的全攻略(25/30)
    一、引言在人工智能技术日新月异的当下,多智能体协作与大型语言模型(LLM)的应用日益广泛。微软推出的AutoGen框架,犹如一颗璀璨的新星,为开发者们提供了一个强大的工具,以实现高效的多智能体对话和复杂任务的自动化处理。AutoGen框架致力于简化多智能体系统的开发过程,使开发者能......
  • 【OAuth2框架】理解和实战 OAuth2 认证授权
    你知道互联网大厂最怕的是什么吗?但凡有点这样的风吹草动,我们就要花费大量的时间进行修复和上线。一点都不敢耽误,对于紧急类型的,基本当天发现,当天就要升级上线。那是什么问题呢?......
  • 计算机毕业设计Springboot毕业学员志愿填报系统设计与实现 基于SpringBoot的毕业生志
    计算机毕业设计Springboot毕业学员志愿填报系统设计与实现f710g1r7(配套有源码程序mysql数据库论文)本套源码可以先看具体功能演示视频领取,文末有联xi可分享随着互联网技术的飞速发展,传统的毕业学员志愿填报方式已逐渐无法满足现代社会的需求。纸质填报不仅效率低下,而且容......
  • 【产品经理修炼之道】-需求太复杂?试试FDD框架管理流程
    面对需求相对复杂以及合作方众多的情况下,产品经理该如何处理这些需求?作者结合行业资料及其自身经验,与大家探讨如何利用FDD框架,管理我们的需求管理和研发构建的流程。2022年,我司承接了两个车厂的软件项目,中国与欧洲团队深度合作,旨在做好项目交付的同时,打造公司级的产品平台。......
  • 【开源】基于SpringBoot框架电商平台(计算机毕业设计)+万字毕业论文 T192
    系统合集跳转源码获取链接点击主页更能获取海量源码10年计算机开发经验,主营业务:源码获取、项目二开、语音辅导、远程调试、毕业设计、课程设计、毕业论文、BUG修改一、系统环境运行环境:最好是javajdk1.8,我们在这个平台上运行的。其他版本理论上也可以。IDE环境......
  • 【开源】基于SpringBoot框架毕业设计系统(计算机毕业设计)+万字毕业论文 T200
    系统合集跳转源码获取链接点击主页更能获取海量源码10年计算机开发经验,主营业务:源码获取、项目二开、语音辅导、远程调试、毕业设计、课程设计、毕业论文、BUG修改一、系统环境运行环境:最好是javajdk1.8,我们在这个平台上运行的。其他版本理论上也可以。IDE环境......
  • 【开源】基于SpringBoot框架在线考试系统(计算机毕业设计)+万字毕业论文 T207
    系统合集跳转源码获取链接点击主页更能获取海量源码10年计算机开发经验,主营业务:源码获取、项目二开、语音辅导、远程调试、毕业设计、课程设计、毕业论文、BUG修改一、系统环境运行环境:最好是javajdk1.8,我们在这个平台上运行的。其他版本理论上也可以。IDE环境......
  • Peewee:Python 简洁强大的 ORM 框架
    在Python的开发世界中,数据库操作是至关重要的一环。今天介绍的Peewee作为一款简洁且功能强大的ORM(对象关系映射)框架,为开发者提供了高效便捷的数据库交互方式。1.Peewee概述Peewee是一个简单小巧的ORM,它的概念简洁明了,易于学习和使用。能够与SQLite、MySQL、MariaDB、......
  • 计算机毕业设计Springboot4S店管理系统设计与实现 基于Spring Boot的4S店综合管理系统
    计算机毕业设计Springboot4S店管理系统设计与实现gn093018(配套有源码程序mysql数据库论文)本套源码可以先看具体功能演示视频领取,文末有联xi可分享随着汽车行业的蓬勃发展,4S店作为汽车销售与服务的重要场所,其管理效率和质量直接关系到客户满意度和市场竞争力。传统的手工......
  • 计算机毕业设计Springboot4S店管理系统 基于Spring Boot的汽车4S店综合管理系统设计与
    计算机毕业设计Springboot4S店管理系统w6vb2gip(配套有源码程序mysql数据库论文)本套源码可以先看具体功能演示视频领取,文末有联xi可分享随着汽车行业的蓬勃发展,4S店作为汽车销售与服务的重要场所,面临着日益复杂的运营管理挑战。传统的管理方式已经难以满足现代4S店对效率......