一、gateway的标准使用
我们在gateway服务配置中, 每新增一个服务, 我们需要手动增加一个route配置项
server:
port: 8080
spring:
application:
name: app_name
cloud:
gateway:
# 跨域处理
globalcors:
cors-configurations:
'[/**]':
allowed-origins: "*"
allowed-headers: "*"
allow-credentials: true
allowed-methods:
- GET
- POST
- DELETE
- PUT
- OPTION
- PATCH
# 路由转发
routes:
- id: exchange-admin-server
uri: lb://rdc-exchange-admin${spring.profiles.active}-service
predicates:
- Path=/admin/api/v1/**
- id: exchange-web-server
uri: lb://rdc-exchange${spring.profiles.active}-service
predicates:
- Path=/api/v1/**
2. 结合Discovery的服务发现机制, 实现自动的服务路由转发代理注册
通过DiscoveryClient获取服务列表, 然后通过正则匹配出需要路由转发的服务, 然后使用 /service-id/** 的方式来做统一路由转发处理
@Slf4j
@Component
public class RouterAutoRegistry implements InitializingBean {
@Resource
private DiscoveryClient discoveryClient;
@Resource
private RouteDefinitionWriter routeDefinitionWriter;
@Resource
private ApplicationEventPublisher publisher;
@Value("${server.pattern:rdc([\\s\\S]*?)service}")
private String serverPattern;
private static Map<String, RouteDefinition> definitions = new ConcurrentHashMap<>();
@Scheduled(cron = "0/30 * * * * ? ")
public void registryRouter() {
log.info("refresh gateway routers");
discoveryClient.getServices()
.stream()
.filter(x -> x.matches(serverPattern))
.filter(x -> definitions.get(x) == null)
.forEach(x -> {
RouteDefinition definition = new RouteDefinition();
definition.setId(x);
definition.setUri(URI.create("lb://" + x));
// 设置匹配断言 /serviceId/**
PredicateDefinition predicateDefinition = new PredicateDefinition();
predicateDefinition.setName("Path");
Map<String, String> predicateArgs = new HashMap<>(16);
predicateArgs.put("pattern", "/" + x + "/**");
predicateDefinition.setArgs(predicateArgs);
definition.setPredicates(Lists.newArrayList(predicateDefinition));
//设置过滤器 RewritePath: /serviceId/** -> /**
FilterDefinition filterDefinition = new FilterDefinition();
filterDefinition.setName("RewritePath");
Map<String, String> filterArgs = new HashMap<>(16);
filterArgs.put("regexp", "/" + x + "/(?<segment>.*)");
filterArgs.put("replacement", "/$\\{segment}");
filterDefinition.setArgs(filterArgs);
definition.setFilters(Lists.newArrayList(filterDefinition));
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
definitions.put(x, definition);
log.info("auto registry discovery server router: {} -> {}", x, definition);
});
publisher.publishEvent(new RefreshRoutesEvent(this));
}
@Override
public void afterPropertiesSet() {
registryRouter();
}
}