给会所做网站,做有关兼职网站的需求分析,网站开发流程图工具,wordpress响应式模板需求 实现URL web资源整合#xff0c;实现使用一个web地址访问多个web资源
方案 本方案使用SpringCloud Gateway实现#xff0c;不需要在hosts文件加添加域名映射#xff08;也不需要定义一系列域名#xff09;#xff0c;通过url路径来将请求转发到不同的Web资源 如实现使用一个web地址访问多个web资源
方案 本方案使用SpringCloud Gateway实现不需要在hosts文件加添加域名映射也不需要定义一系列域名通过url路径来将请求转发到不同的Web资源 如http://${proxyIP}:${proxyPORT}/nacos1 转发到 http://${nacos1IP}:${nacos1PORT} 1、优点
不需要用户端修改hosts文件或是域名服务支持
2、缺点
session信息可能会生产覆盖存在session失效和横向越权风险
小知识 浏览器的session是按ip端口或域名端口作为唯一key存的 环境
spring-cloud 2024.0.0
spring-cloud gateway 4.2.0 实现代码
pom
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactId!-- 3.4.0 3.3.6 3.1.5 3.0.12 --version3.4.0/version!-- lookup parent from repository --relativePath//parentgroupIdperson.daizd/groupIdartifactIdgwproxy/artifactIdversion1.0-SNAPSHOT/version!-- 统一管理jar包版本 --propertiesjava.version17/java.versionproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.compiler.source17/maven.compiler.sourcemaven.compiler.target17/maven.compiler.target!-- 3.4.0 3.3.6 --spring-boot.version3.4.0/spring-boot.version!-- 2024.0.0 2023.0.4 --spring-cloud.version2024.0.0/spring-cloud.version!-- 2023.0.3.2 2023.0.1.3 2022.0.0.0 2021.1 2021.0.6.1 2021.0.5.0 --spring-cloud-alibaba.version2023.0.3.2/spring-cloud-alibaba.version!-- springcloud 2020.02 以后需要单独引入 4.1.4 4.0.5 3.1.9 3.0.6 --spring-cloud-starter-bootstrap.version4.1.4/spring-cloud-starter-bootstrap.version!-- 0.3.0-RC 适配springboot3 0.2.12 适配springboot2 0.1.10 适配springboot1 --nacos-config-spring-boot-starter.version0.3.0-RC/nacos-config-spring-boot-starter.version!-- junit.version5.8.2/junit.version--log4j.version1.2.17/log4j.versionlombok.version1.18.28/lombok.versioncommons-lang3.version3.14.0/commons-lang3.versionio.micrometer.version1.9.17/io.micrometer.version!-- pmd-core 7.0.0: 3.25.0 3.24.0 3.23.0 3.22.0pmd-core 6.55.0: 3.21.2 3.13.0 3.11.0 copote --maven-pmd-plugin.version3.26.0/maven-pmd-plugin.versionmaven-clean-plugin.version3.26.0/maven-clean-plugin.versionfastjson2.version2.0.53/fastjson2.version/propertiesdependencies!--gateway的依赖 springcloud开发--dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-gateway/artifactId/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-bootstrap/artifactIdversion${spring-cloud-starter-bootstrap.version}/version/dependency!-- 之前工程即没有引入 SpringCloud也没有引入 SpringCloudAlibaba --dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-config/artifactIdversion${spring-cloud-alibaba.version}/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdscopecompile/scope/dependencydependencygroupIdcom.alibaba.fastjson2/groupIdartifactIdfastjson2/artifactIdversion${fastjson2.version}/version/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactIdversion${commons-lang3.version}/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependencydependencygroupIdio.micrometer/groupIdartifactIdmicrometer-registry-prometheus/artifactId/dependencydependencygroupIdio.netty/groupIdartifactIdnetty-resolver-dns-native-macos/artifactIdversion4.1.115.Final/versionclassifierosx-aarch_64/classifier/dependencydependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion5.8.22/version
!-- scopetest/scope--/dependency!-- 测试相关 这个包含junit5 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency/dependenciesdependencyManagementdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-dependencies/artifactIdversion${spring-boot.version}/versiontypepom/typescopeimport/scope/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-dependencies/artifactIdversion${spring-cloud.version}/versiontypepom/typescopeimport/scope/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-alibaba-dependencies/artifactIdversion${spring-cloud-alibaba.version}/versiontypepom/typescopeimport/scope/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion${lombok.version}/versionoptionaltrue/optional/dependencydependencygroupIdio.micrometer/groupIdartifactIdmicrometer-registry-prometheus/artifactIdversion${io.micrometer.version}/versionscopecompile/scope/dependency/dependencies/dependencyManagementbuildplugins!-- 用于支持热部署 --plugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfiguration!-- 表示它将创建fork一个新的JVM来运行编译器。 spring boot plugin 3.0.0没有这个属性了forktrue/fork --addResourcestrue/addResources/configuration/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-resources-plugin/artifactIdversion3.3.1/versionexecutionsexecutionidcopy-resource/idphasecompile/phasegoalsgoalcopy-resources/goal/goalsconfigurationoutputDirectory${basedir}/target/outputDirectoryresourcesresource!-- 文件地址 --directory${basedir}/src/main/resources/directoryincludesincludeconfig.ini/include/includes/resourceresource!-- 文件地址 --directory${basedir}/src/main/resources/directoryincludesincludecookie.png/include/includes/resource/resources/configuration/execution/executions/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdconfigurationtarget${maven.compiler.target}/targetsource${maven.compiler.source}/sourceencodingUTF-8/encoding/configuration/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-source-plugin/artifactIdversion3.3.1/versionexecutionsexecutionphaseverify/phasegoalsgoaljar-no-fork/goal/goals/execution/executions/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-clean-plugin/artifactIdversion3.3.2/version/plugin!-- PMD toolkit --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-pmd-plugin/artifactIdversion3.26.0/version/plugin!--- 支持单元测试 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-surefire-plugin/artifactIdversion3.5.2/version/plugin!--- 代码覆盖率工具 --plugingroupIdorg.jacoco/groupIdartifactIdjacoco-maven-plugin/artifactIdversion0.8.12/version/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-dependency-plugin/artifactIdversion3.7.1/versionexecutionsexecutionidcopy-dependencies/idphasepackage/phasegoalsgoalcopy-dependencies/goal/goalsconfigurationoutputDirectory${project.build.directory}/lib/outputDirectory/configuration/execution/executions/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-jar-plugin/artifactIdversion3.4.2/versionconfigurationarchivemanifestaddClasspathtrue/addClasspathclasspathPrefixlib//classpathPrefixmainClassperson.daizd.GatewayApplication/mainClass/manifest/archive/configuration/plugin/plugins/build/project
配置
# 这里有很多组件eureka、apollo、nacos、skywalking等且每一类组件都有多套如有的各省一套
# id与uri的映射
gwproxy.routes.cteureka_localhttp://eureka:eureka127.0.0.1:8200
gwproxy.routes.cmdb_localhttp://127.0.0.1:8071# eureka
gwproxy.routes.cteureka_sh_testhttp://eureka:eureka10.130.***.157:8200
gwproxy.routes.sxeureka_sh_testhttp://eureka:eureka10.130.***.157:8206
gwproxy.routes.fjeureka_sh_testhttp://eureka:eureka10.130.***.157:8207gwproxy.routes.zjeureka_gcgz_nmb3_prodhttp://10.141.***.240:20222# apollo
gwproxy.routes.apollo_sh_testhttp://10.130.***.157:28003
gwproxy.routes.apollo_sh_sithttp://10.130.***.112:30001gwproxy.routes.ctapollo__nmb3_prodhttp://10.141.***.240:20400
gwproxy.routes.lnapollo_idc01_nmb3_prodhttp://10.141.***.240:20403# sentinel
gwproxy.routes.lnsentinel_idc01_nmb3_prodhttp://10.141.***.240:23903
gwproxy.routes.jssentinel_idc01_nmb3_prodhttp://10.141.***.240:23915
gwproxy.routes.ahsentinel_idc01_nmb3_prodhttp://10.141.***.240:23923# apisix
# http://${gwproxy.root_uri}/apisix/index.html?appapisix_sh_test
gwproxy.routes.apisix_sh_testhttp://10.130.***.157:9000gwproxy.routes.ctapisix_gz_gzb1_prodhttp://10.***.5.131:32065gwproxy.routes.ctapisix_idc01_nmb3_prodhttp://10.141.***.240:31600
gwproxy.routes.lnapisix_idc01_nmb3_prodhttp://10.141.***.240:31603# prometheus
# http://${gwproxy.root_uri}/prometheus_sh_test/graph
gwproxy.routes.prometheus_sh_testhttp://10.130.***.136:9090
gwproxy.routes.prometheus_idc01_gzb1c1_prodhttp://10.***.32.245:30006
gwproxy.routes.prometheus_idc01_gzb1c2_prodhttp://10.***.32.246:30006
gwproxy.routes.prometheus_idc01_gzb1c3_prodhttp://10.***.32.247:30006gwproxy.routes.prometheus_idc01_nmb3c1_prodhttp://10.141.***.240:30006
gwproxy.routes.prometheus_idc01_nmb3c2_prodhttp://10.141.***.241:30006
gwproxy.routes.prometheus_idc01_nmb3c3_prodhttp://10.141.***.242:30006gwproxy.routes.prometheus_sh_crm120http://10.130.***.120:9090
gwproxy.routes.prometheus_sh_crm121http://10.130.***.121:9090
gwproxy.routes.prometheus_gz_saas190http://10.***.31.190:30900# nacos
# http://${gwproxy.root_uri}/nacos_sh_test/nacos/#/login
gwproxy.routes.nacos_sh_testhttp://10.130.***.92:18848# gateway
gwproxy.routes.ahgateway_idc01_nmb3_prodhttp://10.141.***.242:23266
gwproxy.routes.jsgateway_idc01_nmb3_prodhttp://10.141.***.216:32015
gwproxy.routes.bjgateway_idc01_nmb3_prodhttp://10.141.***.209:32008
gwproxy.routes.lngateway_idc01_nmb3_prodhttp://10.141.***.204:30003# elasticsearch
gwproxy.routes.elasticsearch_gz_247http://10.***.6.247:9200# kibana 待优化KibanaRoute1 用于同时支持kibana 直接访问和代理访问不过官方说只能2选一优化难度大
# /kibana_local/login?next/kibana_local/
gwproxy.routes.kibana_localhttp://esserver:5601# /kibana_sh_test/login?next/kibana_sh_test/
gwproxy.routes.kibana_sh_cs134_testhttp://10.130.***.134:15601
gwproxy.routes.kibana_sh_jg92_testhttp://10.130.***.92:5602# /gzkibana_5601/login?next/gzkibana_5601/
# /gzkibana_5601/login?msgLOGGED_OUT
gwproxy.routes.kibana_gz_5601_prodhttp://10.***.6.247:5601
gwproxy.routes.kibana_gz_5602_prodhttp://10.***.6.247:5602
gwproxy.routes.kibana_gz_5603_prodhttp://10.***.6.247:5603# /nmkibana_5601/login?next%2F
gwproxy.routes.kibana_nm_5601_prodhttp://10.141.137.***:5601
gwproxy.routes.kibana_nm_5602_prodhttp://10.141.137.***:5601
gwproxy.routes.kibana_nm_5603_prodhttp://10.141.137.***:5601# timetask 当前可参考kibana 通过改根路径解决这里直接改应用包名
# http://${gwproxy.root_uri}/timetask/toLogin
# http://${gwproxy.root_uri}/cttimetask_idc01_nmb3_prod/timetask/toLogin
# 因静态资源命名冲突所以两种改工程名与直接支持配置不能同时存在
#
gwproxy.routes.timetaskhttp://10.141.***.240:22400
#gwproxy.routes.timetask-xxl-jobhttp://10.141.***.240:22400
gwproxy.routes.cttimetask_idc01_nmb3_prodhttp://10.141.***.240:22400
gwproxy.routes.cttimetask_idc01_gzb1_prodhttp://10.***.5.131:22400# Grafana
# http://${gwproxy.root_uri}/grafana_sh_prod/login
gwproxy.routes.grafana_sh_prodhttp://10.130.***.121:50001# Ambari (Hadoop - Hbase )
# http://${gwproxy.root_uri}/ambari_sh_prod/#/login
gwproxy.routes.ambari_sh_prodhttp://10.***.6.231:8080# kafka-map
gwproxy.routes.kafkamap_sh_jg92_testhttp://10.130.***.92:8083
gwproxy.routes.kafkamap_sh_prodhttp://10.130.***.121:8093# cmak
# /cmak_sh_jg93_test
gwproxy.routes.cmak_sh_jg93_testhttp://10.130.***.93:8094
# 没启或没安装
gwproxy.routes.cmak_sh_prodhttp://10.130.***.121:8094# skywalking
gwproxy.routes.skywalking_sh_jg131_testhttp://10.130.***.131:30198
#
gwproxy.routes.skywalking_xw_nm_prodhttp://10.141.***.41:31051
gwproxy.routes.skywalking_xw_gz_prodhhttp://10.***.6.204:31051
gwproxy.routes.skywalking_idc01_nmb3_prodhhttp://10.141.***.240:31051# pinpoint
gwproxy.routes.pinpoint_idc01_gzb1_prodhttp://10.***.5.131:20900
gwproxy.routes.pinpoint_idc01_nmb3_prodhttp://10.141.***.95:20900# redmine
gwproxy.routes.redmine_idc01_nmb3_prodhttp://10.142.***.247:8080# harbor
gwproxy.routes.harbor_idc01_gzb1_prodhttp://10.***.100.18:8021# jenkins
gwproxy.routes.jenkins_sh_cs124_prodhttp://10.130.***.124:1906# nexus
gwproxy.routes.nexus_sh_jg122_prodhttp://10.130.***.122:18081# gitlab
gwproxy.routes.gitlab_sh_jg122_prodhttp://10.130.***.122:8082# kubesphere
gwproxy.routes.kubesphere_sh_cs131_prodhttp://10.130.***.131:30880# nightingale
# nightingale_sh_test/login
# nightingale_sh_test/metric/explorer
# 10.130.***.120 nightingale.sh.test
# 10.130.***.120 nightingale.sh.prod
gwproxy.routes.nightingale_sh_testhttp://10.130.***.136:17000
gwproxy.routes.nightingale_sh_prodhttp://10.130.***.121:17000# 业务应用 begin
# http://${gwproxy.root_uri}/portal1_sh_prod/login
gwproxy.routes.portal1_sh_prodhttp://10.130.***.121:8082gwproxy.routes.web2_sh_testhttp://10.130.***.124:8201
# http://${gwproxy.root_uri}/web2_idc01_nmb3_prod/web2/
gwproxy.routes.web2_idc01_nmb3_prodhttp://10.***.228.140:32100配置类
/*** Description: 从nacos获取配置* Author: dand* CreateDate: 2024/12/14 5:43 PM* Version: 1.0*/import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;import java.util.Map;Component
ConfigurationProperties(prefix gwproxy)
Getter
Setter
RefreshScope
public class NacosMappingConfig {private MapString, String routes;}
动态路由实现【重点】
# 这里涉及很多组件本文先上eureka的代码其他组件支持代码读者可自行注释掉后续更新文章其他组件相关动态路由实现代码会陆续上架
package person.daizd.config;import com.alibaba.nacos.api.exception.NacosException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import person.daizd.config.route.*;
import person.daizd.filters.factory.*;import java.util.Iterator;
import java.util.Map;
import java.util.Set;/**** Author dand QQ:413881461* Slogan 致敬大师致敬未来的你*/
Slf4j
Configuration
public class GatewayConfig {Value(${gwproxy.root_uri})private String rootUri;Autowiredprivate NacosMappingConfig nacosMappingConfig;Autowiredprivate CmdbFilterFactory1 cmdbFilterFactory1;Autowiredprivate CmdbFilterFactory2 cmdbFilterFactory2;Autowiredprivate ApisixFilterFactory1 apisixFilterFactory1;Autowiredprivate ApisixFilterFactory2 apisixFilterFactory2;Autowiredprivate EurekaFilterFactory1 eurekaFilterFactory1;Autowiredprivate EurekaFilterFactory2 eurekaFilterFactory2;Autowiredprivate N9eFilterFactory1 n9eFilterFactory1;Autowiredprivate N9eFilterFactory2 n9eFilterFactory2;// Autowired
// private KibanaFilterFactory1 kibanaFilterFactory1;
// Autowired
// private KibanaFilterFactory2 kibanaFilterFactory2;Autowiredprivate TimeTaskFilterFactory1 timeTaskFilterFactory1;Autowiredprivate TimeTaskFilterFactory2 timeTaskFilterFactory2;Bean
// RefreshScopepublic RouteLocator customRouteLocator(RouteLocatorBuilder builder) throws NacosException {log.debug(nacosMappingConfig:{},nacosMappingConfig.getRoutes());// 需要换成配置中取
// MapString,String map new HashMapString,String();MapString,String map nacosMappingConfig.getRoutes();
// map.put(cteureka_local,http://eureka:eureka127.0.0.1:8200);
// map.put(cmdb_local,http://127.0.0.1:8071);RouteLocatorBuilder.Builder innerBuilder builder.routes();SetMap.EntryString, String set map.entrySet();IteratorMap.EntryString, String it set.iterator();/*** 特别注意* 1、路径名称不能与已有资源名重命* 2、相互之间不能是包含子集关系***/// 先统一处理所有eurekawhile (it.hasNext()) {Map.EntryString, String entry it.next();if(entry.getKey().contains(eureka)){innerBuilder EurekaRoute.route(eurekaFilterFactory1, eurekaFilterFactory2,innerBuilder, entry, rootUri);}// 防止不重复处理 用 else ifelse if(entry.getKey().contains(cmdb)){innerBuilder CmdbRoute.route(cmdbFilterFactory1, cmdbFilterFactory2,innerBuilder, entry, rootUri);}else if(entry.getKey().contains(sentinel)){innerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}else if(entry.getKey().contains(apisix)){innerBuilder ApisixRoute2.route(apisixFilterFactory1,apisixFilterFactory2,innerBuilder, entry, rootUri);}else if(entry.getKey().contains(ddal)){innerBuilder CmdbRoute.route(cmdbFilterFactory1, cmdbFilterFactory2,innerBuilder, entry, rootUri);}/* 待优化KibanaRoute1 用于同时支持kibana 直接访问和代理访问不过官方说只能2选一优化难度大另外也可开通SSO能力后研究其他方案前端使用了react采用nodejs部署*/else if(entry.getKey().contains(kibana)){innerBuilder KibanaRoute2.route(innerBuilder, entry, rootUri);}else if(entry.getKey().contains(elasticsearch)){innerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}else if(entry.getKey().contains(nacos)){innerBuilder CmdbRoute.route(cmdbFilterFactory1, cmdbFilterFactory2,innerBuilder, entry, rootUri);}else if(entry.getKey().contains(prometheus)){innerBuilder CmdbRoute.route( cmdbFilterFactory1, cmdbFilterFactory2,innerBuilder, entry, rootUri);}// todo n9e 前端使用了React和D3.js, 等官方支持修改根路径改为与配置名一致或 二次n9e前端工程https://github.com/n9e/feelse if(entry.getKey().contains(nightingale)){innerBuilder N9eRoute.route( n9eFilterFactory1, n9eFilterFactory2,innerBuilder, entry, rootUri);}/** 方案一 改timetask 上下文应用名/根路径-- 推荐kibana 方案* 方案二 直接支持不调整应用 -- 目前与n9e一样存在类似菜单路径问题*/else if(entry.getKey().contains(timetask)){innerBuilder KibanaRoute2.route(innerBuilder, entry, rootUri);// innerBuilder TimeTaskRoute.route( timeTaskFilterFactory1, timeTaskFilterFactory2,
// innerBuilder, entry, rootUri);}// todoelse if(entry.getKey().contains(grafana)){ // /grafana_sh_prod/logininnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}else if(entry.getKey().contains(ambari)){ // /ambari_sh_prod/#/logininnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}// eureka √else if(entry.getKey().contains(kafkamap)){ // /kafkamap_sh_jg92_test/#/logininnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}// cmak 存在类似n9e的菜单路径问题else if(entry.getKey().contains(cmak)){ // /cmak_sh_jg93_testinnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}// 补充了一个js待验证else if(entry.getKey().contains(skywalking)){ // /skywalking_sh_jg131_test/General-Service/ServicesinnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}// 初步让为 √else if(entry.getKey().contains(pinpoint)){ // /pinpoint_gcgz_gzb1_prod/#/maininnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}// 120网络不通else if(entry.getKey().contains(redmine)){ // /redmine_gcgz_nmb3_prod/logininnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}// 初步让为harbor上下文路径可以修改else if(entry.getKey().contains(harbor)){ // /harbor_gcgz_gzb1_prod/harbor/sign-ininnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}// 能登陆但主页面显示不正常else if(entry.getKey().contains(jenkins)){ // /jenkins_sh_cs124_prod/jenkins/logininnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}// 登陆有问题else if(entry.getKey().contains(nexus)){ // /nexus_sh_jg122_prod/nexus/#welcomeinnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}// 静态资源访问有问题else if(entry.getKey().contains(gitlab)){ // /gitlab_sh_jg122_prod/users/sign_ininnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}// 未知错误else if(entry.getKey().contains(kubesphere)){ // /kubesphere_sh_cs131_prod/logininnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}// 可以登陆静态资源加载有问题else if(entry.getKey().contains(opsportal)){ // /opsportal_sh_prod/logininnerBuilder CommonRoute.route(innerBuilder, entry, rootUri);}};return innerBuilder.build();}}
eureka动态路由实现类
package person.daizd.config.route;import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.cloud.gateway.route.builder.GatewayFilterSpec;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.cloud.gateway.route.builder.UriSpec;
import person.daizd.filters.factory.*;import java.util.Map;
import java.util.function.Function;/*** 路由** Author: daizd* CreateDate: 2024/12/13 9:28 PM* Version: 1.0*/
Slf4j
public class EurekaRoute {public static RouteLocatorBuilder.Builder route(EurekaFilterFactory1 filterFactory1,EurekaFilterFactory2 filterFactory2,RouteLocatorBuilder.Builder innerBuilder,Map.EntryString, String entry,String rootUri){// 每个eureka要配两个路由 第一个innerBuilder innerBuilder.route( entry.getKey()_1, // idr - r.path(/entry.getKey()/**) // -- /cteureka/**.filters( f - f.stripPrefix(1).preserveHostHeader().saveSession() ).uri( entry.getValue() ));log.debug(Referer:rootUri/entry.getKey()[^\\s]* );log.debug(uri:entry.getValue() );// 每个eureka要配两个路由第二个 modifyRedirectFilterFactoryinnerBuilder.route( entry.getKey()_2, // idr - r.header(Referer,rootUri/entry.getKey()[^\\s]* )
// .filters( f - f.stripPrefix(0).preserveHostHeader() ).filters(new FunctionGatewayFilterSpec, UriSpec() {Overridepublic UriSpec apply(GatewayFilterSpec gatewayFilterSpec) {return gatewayFilterSpec.filter(filterFactory2.apply(applyFilter(app,entry.getKey() )));}}).uri( entry.getValue() ));return innerBuilder;}/*** 构造config** param headerName* param headerValue* return NameValueConfig*/private static AbstractNameValueGatewayFilterFactory.NameValueConfig applyFilter(String headerName, String headerValue) {AbstractNameValueGatewayFilterFactory.NameValueConfig config new AbstractNameValueGatewayFilterFactory.NameValueConfig();config.setName(headerName);config.setValue(headerValue);return config;}
}
GatewayFilterFactory1【保留】
package person.daizd.filters.factory;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;/*** 用在路由1上** Author: dand* CreateDate: 2024/12/8 7:49 PM* Version: 1.0** 没有用到*/
Component
Slf4j
public class EurekaFilterFactory1 extends AbstractNameValueGatewayFilterFactory {Value(${gwproxy.root_uri})private String rootUri;/*** 1、如果是重定向则定向到配置参数应用名对应的路径* 2、如果不是重定向且第一级路径与应用名不一致则修改为一致** param config* return*/Overridepublic GatewayFilter apply( NameValueConfig config) {return (exchange, chain) -chain.filter(exchange).then(Mono.fromRunnable(() - {ServerHttpRequest request exchange.getRequest();ServerHttpResponse response exchange.getResponse();HttpStatusCode statusCode response.getStatusCode();String name config.getName();String value config.getValue();String rootUrl rootUri/config.getValue();if (statusCode HttpStatus.SEE_OTHER || statusCode HttpStatus.FOUND) {String location response.getHeaders().getFirst(HttpHeaders.LOCATION);// 修改location的逻辑if(response.getHeaders().containsKey(Set-Cookie)
// || request.getHeaders().containsKey(Cookie)){// 有 Set-Cookie 和 cookie都认为已登陆response.getHeaders().set(HttpHeaders.LOCATION, rootUrl );log.info(response.getHeaders().containsKey(\Set-Cookie\) , to rootUrl:{} ,rootUrl);}else{response.getHeaders().set(HttpHeaders.LOCATION, rootUrl/signin );log.info( else : {}/signin ,rootUrl);}}}));}Overridepublic ClassNameValueConfig getConfigClass() {// 如果你有配置属性返回配置属性的类如果没有返回nullreturn NameValueConfig.class; // 或者 return YourConfigProperties.class;}
} GatewayFilterFactory2
package person.daizd.filters.factory;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractNameValueGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;import java.net.URI;
import java.util.List;/*** 用在路由2上** Author: dand* CreateDate: 2024/12/8 7:49 PM* Version: 1.0*/
Component
Slf4j
public class EurekaFilterFactory2 extends AbstractNameValueGatewayFilterFactory {Value(${gwproxy.root_uri})private String rootUri;/*** 1、如果是重定向则定向到配置参数应用名对应的路径* 2、如果不是重定向且第一级路径与应用名不一致则修改为一致** param config* return*/Overridepublic GatewayFilter apply( NameValueConfig config) {return (exchange, chain) -chain.filter(exchange).then(Mono.fromRunnable(() - {ServerHttpResponse response exchange.getResponse();HttpStatusCode statusCode response.getStatusCode();String remoteIp exchange.getRequest().getRemoteAddress().getHostName();log.info(remoteIp:remoteIp);// http://127.0.0.1:8089/oldcmdb;String rootUrl rootUri/config.getValue();System.out.println(statusCode:statusCode);
// FluxOnAssembly a;if (statusCode ! HttpStatus.SEE_OTHER statusCode ! HttpStatus.FOUND) {ServerHttpRequest request exchange.getRequest();URI uri request.getURI() ;String path request.getPath().value();HttpHeaders headers request.getHeaders();ListString referer headers.get(referer);log.info(path:{}, uri.getPath() );if( referer!null referer.size()0 referer.get(0).indexOf( rootUrl ) ! -1 // referer 包含http://127.0.0.1:8089/oldcmdb uri.getPath().indexOf( /config.getValue() ) -1 // uri 不包含 /oldcmdb (uri.getPath().equalsIgnoreCase(/)|| uri.getPath().equalsIgnoreCase(/lastn) )) // 是html页面{// 重定向到 RewritePath/(?segment.*), /oldcmdb/$\{segment}exchange.getResponse().setStatusCode(HttpStatus.FOUND);exchange.getResponse().getHeaders().setLocation( URI.create( /config.getValue() path) );log.info(uri.getPath().indexOf( \.html\) );}}}));}Overridepublic ClassNameValueConfig getConfigClass() {// 如果你有配置属性返回配置属性的类如果没有返回nullreturn NameValueConfig.class; // 或者 return YourConfigProperties.class;}
}
效果说明
为了让读者更好的读懂上面的代码下面给出静态配置实现上面代码动态实现了该效果且更灵活
server:port: 8089gwproxy:root_uri: ${root_uri:http://127.0.0.1:8089}spring:application:name: api-gatewaycloud:gateway:httpclient:response-timeout: PT60Sconnect-timeout: 2000# 链接池配置pool:# 最大连接数max-connections: 10000# 仅对于FIXED类型等待获取线程的最长时间毫秒acquire-timeout: 1000# 最大空闲时间max-idle-time: PT10S# 设置固定链接池type: fixeddiscovery:locator:enabled: truelower-case-service-id: true#路由规则routes:# eureka - id: cteureka_route_1 # 8100000 #路由的ID没有固定规则但要求唯一建议配合服务名uri: http://eureka:eureka127.0.0.1:8200 #匹配后提供服务的路由地址predicates:- Path/cteureka/** # 断言路径相匹配的进行路由filters:- StripPrefix1 # 转发之前去掉第一层路径- id: cteureka_route_2uri: http://eureka:eureka127.0.0.1:8200 #匹配后提供服务的路由地址predicates:- HeaderReferer,${gwproxy.root_uri}/cteurekamanagement:info: # 显示任意的应用信息默认关闭 springBoot版本2.7.15 GA如果是2.7.5 的版本默认是开启的env:enabled: trueendpoints:web:exposure:include: *base-path: /whoami
info:app:name: gatewayencoding: project.build.sourceEncodingjava:source: java.versiontarget: java.versioncompany:name: www.asiainfo.comdebug: true
附件一整合界面地址效果截图 附件二springcloud gateway官方文档
Spring Cloud Gateway 帮助文档
Spring Cloud Gateway 官方首页