1、maven 依赖
主要依赖
< ! -- 网关 -- >
< dependency>
< groupId> org. springframework. cloud< / groupId>
< artifactId> spring- cloud- starter- gateway< / artifactId>
< / dependency>
案件差不多完整主要依赖
< ! -- Spring boot 依赖( 微服务基础) -- >
< dependency>
< groupId> org. springframework. boot< / groupId>
< artifactId> spring- boot- starter< / artifactId>
< ! -- 使用exclusions标签来标明要排除的包-- >
< ! -- 排除logback-- >
< exclusions>
< exclusion>
< groupId> org. springframework. boot< / groupId>
< artifactId> spring- boot- starter- logging< / artifactId>
< / exclusion>
< / exclusions>
< / dependency>
< ! -- Web 服务相关-- >
< dependency>
< groupId> org. springframework. boot< / groupId>
< artifactId> spring- boot- starter- web< / artifactId>
< / dependency>
< ! -- 生成配置元数据,比如你平常在yml文件里面配置 -- >
< dependency>
< groupId> org. springframework. boot< / groupId>
< artifactId> spring- boot- configuration- processor< / artifactId>
< optional> true < / optional>
< / dependency>
< ! -- 单元测试依赖, 子工程中需要单元测试时, 不需要再次引入此依赖了-- >
< dependency>
< groupId> org. springframework. boot< / groupId>
< artifactId> spring- boot- starter- test< / artifactId>
< scope> test< / scope>
< exclusions>
< exclusion>
< groupId> org. junit. vintage< / groupId>
< artifactId> junit- vintage- engine< / artifactId>
< / exclusion>
< / exclusions>
< / dependency>
< ! -- bootstrap 相关-- >
< ! -- SpringBoot2 .4 . x之后默认不加载bootstrap. yml文件,需要在pom里加上依赖-- >
< dependency>
< groupId> org. springframework. cloud< / groupId>
< artifactId> spring- cloud- starter- bootstrap< / artifactId>
< version> 4.0 .0 < / version>
< / dependency>
< ! -- 服务的注册和发现-- >
< dependency>
< groupId> com. alibaba. cloud< / groupId>
< artifactId> spring- cloud- starter- alibaba- nacos- config< / artifactId>
< / dependency>
< dependency>
< groupId> com. alibaba. cloud< / groupId>
< artifactId> spring- cloud- starter- alibaba- nacos- discovery< / artifactId>
< / dependency>
< ! -- lombok 依赖, 子工程中假如需要lombok, 不需要再引入-- >
< ! -- https: / / mvnrepository. com/ artifact/ org. projectlombok/ lombok -- >
< dependency>
< groupId> org. projectlombok< / groupId>
< artifactId> lombok< / artifactId>
< version> 1.18 .30 < / version>
< scope> provided< / scope>
< / dependency>
< ! -- 网关 -- >
< dependency>
< groupId> org. springframework. cloud< / groupId>
< artifactId> spring- cloud- starter- gateway< / artifactId>
< / dependency>
2、bootstrap.yml配置
server:
port: 9999
tomcat:
max- http- form- post- size: - 1
max- threads: 500
min- spare- threads: 50
servlet:
context- path: /
spring:
main:
web- application- type: reactive
#当遇到同样名字的时候,是否允许覆盖注册
allow- bean- definition- overriding: true
profiles:
active: ${ SYS_ENV : } # local: 本地,dev:测试,uat: uat
application:
name: gateway- service
cloud:
nacos:
# 配置中心#
config:
username: ${ NACOS_USER : nacos}
password: ${ NACOS_PASSWORD : nacos}
server- addr: ${ NACOS_IP : nacos. com} : ${ NACOS_POST : 8848 }
namespace: ${ NACOS_NAMESPACE : }
file- extension: yml
refresh- enabled: true
override- none: true #本地配置优先
shared- configs:
- application. ${ spring. cloud. nacos. config. file- extension} # 配置文件名- Data Id
# 路由网关配置
gateway:
# 启用了自动根据服务名建立路由
discovery:
locator:
enabled: true
lower- case - service- id: true
# 动态路由配置
config:
# 动态
gateway- route:
# nacos 配置dataId
dataId: gateway- router
# nacos服务地址
server- addr: ${ spring. cloud. nacos. config. server- addr}
# 命名空间
namespace: ${ spring. cloud. nacos. config. namespace}
3、nacos 中心网关路由配置
[
{
"id" : "auth-service" ,
"uri" : "lb://auth-service" ,
"predicates" : [
{
"args" : {
"pattern" : "/auth-service/**"
} ,
"name" : "Path"
}
] ,
"filters" : [
{
"args" : {
"parts" : 1
} ,
"name" : "StripPrefix"
}
] ,
"order" : 1
} ,
{
"id" : "user-service" ,
"uri" : "lb://user-service" ,
"predicates" : [
{
"args" : {
"pattern" : "/user-service/**"
} ,
"name" : "Path"
}
] ,
"filters" : [
{
"args" : {
"parts" : 1
} ,
"name" : "StripPrefix"
}
] ,
"order" : 2
}
]
4、配置文件 GatewayRouteConfig
import cn. hutool. core. lang. Assert ;
import cn. hutool. core. util. StrUtil ;
import com. alibaba. fastjson. JSONObject ;
import com. alibaba. nacos. api. NacosFactory ;
import com. alibaba. nacos. api. config. ConfigService ;
import com. alibaba. nacos. api. config. listener. Listener ;
import com. alibaba. nacos. api. exception. NacosException ;
import jakarta. annotation. PostConstruct ;
import lombok. extern. slf4j. Slf4j ;
import org. springframework. beans. factory. annotation. Value ;
import org. springframework. cloud. context. config. annotation. RefreshScope ;
import org. springframework. cloud. gateway. event. RefreshRoutesEvent ;
import org. springframework. cloud. gateway. route. RouteDefinition ;
import org. springframework. cloud. gateway. route. RouteDefinitionWriter ;
import org. springframework. context. ApplicationEventPublisher ;
import org. springframework. context. ApplicationEventPublisherAware ;
import org. springframework. stereotype. Component ;
import reactor. core. publisher. Mono ;
import java. util. ArrayList ;
import java. util. List ;
import java. util. Properties ;
import java. util. concurrent. Executor ;
@Slf4j
@RefreshScope
@Component
public class GatewayRouteConfig implements ApplicationEventPublisherAware {
private static final String PROPERTIES_SERVER_ADDR = "serverAddr" ;
private static final String PROPERTIES_NAMESPACE = "namespace" ;
private static final String PROPERTIES_GROUP = "group" ;
@Value ( "${config.gateway-route.dataId:gateway-router}" )
private String dataId = "gateway-routes" ;
@Value ( "${config.gateway-route.group:DEFAULT_GROUP}" )
private String group = "DEFAULT_GROUP" ;
@Value ( "${config.gateway-route.server-addr}" )
private String serverAddr;
@Value ( "${config.gateway-route.namespace}" )
private String namespace;
private static final List < String > ROUTE_LIST = new ArrayList < > ( ) ;
private final RouteDefinitionWriter routeDefinitionWriter;
private ApplicationEventPublisher applicationEventPublisher;
public GatewayRouteConfig ( RouteDefinitionWriter routeDefinitionWriter) {
this . routeDefinitionWriter = routeDefinitionWriter;
}
@Override
public void setApplicationEventPublisher ( ApplicationEventPublisher applicationEventPublisher) {
this . applicationEventPublisher = applicationEventPublisher;
}
@PostConstruct
public void loadRouteFromNacosAndListener ( ) {
try {
ConfigService configService = NacosFactory . createConfigService ( getProperties ( ) ) ;
String initConfigInfo = configService. getConfig ( dataId, group, 5000 ) ;
addRouteAndPublish ( initConfigInfo) ;
addListener ( configService) ;
} catch ( NacosException e) {
log. error ( "加载路由配置错误,详情:" , e) ;
}
}
private void addListener ( ConfigService cs) throws NacosException {
cs. addListener ( dataId, group, new Listener ( ) {
@Override
public void receiveConfigInfo ( String configInfo) {
addRouteAndPublish ( configInfo) ;
}
@Override
public Executor getExecutor ( ) {
return null ;
}
} ) ;
}
private Properties getProperties ( ) {
Assert . notBlank ( serverAddr, "Nacos的服务地址为空了!" ) ;
Properties properties = new Properties ( ) ;
properties. put ( PROPERTIES_SERVER_ADDR , serverAddr) ;
if ( StrUtil . isNotBlank ( namespace) ) {
properties. put ( PROPERTIES_NAMESPACE , namespace) ;
}
if ( StrUtil . isNotBlank ( group) ) {
properties. put ( PROPERTIES_GROUP , group) ;
}
return properties;
}
private void addRouteAndPublish ( String configInfo) {
clearRoute ( ) ;
List < RouteDefinition > gatewayRouteDefinitions = JSONObject . parseArray ( configInfo, RouteDefinition . class ) ;
for ( RouteDefinition routeDefinition : gatewayRouteDefinitions) {
routeDefinitionWriter. save ( Mono . just ( routeDefinition) ) . subscribe ( ) ;
ROUTE_LIST . add ( routeDefinition. getId ( ) ) ;
}
this . applicationEventPublisher. publishEvent ( new RefreshRoutesEvent ( this . routeDefinitionWriter) ) ;
}
private void clearRoute ( ) {
ROUTE_LIST . forEach ( id -> this . routeDefinitionWriter. delete ( Mono . just ( id) ) . subscribe ( ) ) ;
ROUTE_LIST . clear ( ) ;
}
}