SpringCloudGateway 개발 과정 분석
1.SpringCloudGateWay 는 zuul 을 API 게 이 트 웨 이 로 대체 하 는 데 사용 되 는데 gateway 에서 세 가지 중요 한 명사 가 있 습 니 다.필터,단언,경로 입 니 다.
필터 와 단언 은 루트 의 일부분 이 며,루트 는 일련의 처 리 를 요청 한 후 각 서비스 에 나 누 어 주 는 과정 이다.
경로 의 과정:먼저 단언 과 경 로 를 불 러 옵 니 다.요청 을 받 은 후에 단언 에 따라 불 러 오 는 순서 에 따라 먼저 불 러 오 는 단언 과 일치 합 니 다.단언 에 맞 는 요청 만 경로 에 들 어 갑 니 다.일치 하지 않 는 서 비 스 는 요청 을 일반적인 방문 요청 으로 간주 합 니 다.
2:루트 에서 단언 을 불 러 오 는 방식:
프로필,자바 인 코딩,데이터베이스 및 등록 센터 등 네 가지 로 불 러 옵 니 다.
첫 번 째 프로필:
공식 문서 에서 주로 소개 하 는 것 은 설정 파일 의 로드 방식 입 니 다.
공식 주소:https://cloud.spring.io/spring-cloud-gateway/reference/html/#gateway-starter
일반적인 단언 에는 세 가지 요소 가 있다.id,uri,predicate.
id 는 단언 의 표지 이 고 uri 는 ip+포트 이 며 predicate 는 단언 이 일치 하 는 규칙 입 니 다.
3:예시:
spring boot 프로젝트 를 새로 만 들 고 spring cloudgateway 의존 도 를 도입 합 니 다.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
시작 클래스 에 세 개의 전역 필 터 를 등록 합 니 다.
@SpringBootApplication
public class GateWayApplication {
public static void main(String[] args) {
SpringApplication.run(GateWayApplication.class, args);
}
@Bean
@Order(-1)
public GlobalFilter a() {
return (exchange, chain) -> {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
System.out.println(-1);
}));
};
}
@Bean
@Order(0)
public GlobalFilter b() {
return (exchange, chain) -> {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
System.out.println(0);
}));
};
}
@Bean
@Order(1)
public GlobalFilter c() {
return (exchange, chain) -> {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
System.out.println(1);
}));
};
}
}
설정 파일 클래스 에 두 개의 루트 를 설정 합 니 다
server.port: 7777
spring:
application:
name: gateway
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
routes:
- id: method_route
uri: http://127.0.0.1:9999
predicates:
- Method=GET
- id: method_route
uri: http://127.0.0.1:8006
predicates:
- Method=GET
요청 을 보 냅 니 다.요청 이 도착 하면 첫 번 째 경로 와 일치 합 니 다.경로 가 일치 하 는 순 서 는 로 딩 순서 에 따라 이 루어 집 니 다.4:SpringCloudGateway 등록 센터 에서 경로 얻 기
공식 문서 에서 우 리 는 이런 말 을 볼 수 있다.
Configuring Predicates and Filters For DiscoveryClient Routes
By default the Gateway defines a single predicate and filter for routes created via a DiscoveryClient.
The default predicate is a path predicate defined with the pattern /serviceId/**, where serviceId is the id of the service from the DiscoveryClient.
The default filter is rewrite path filter with the regex /serviceId/(?
If you would like to customize the predicates and/or filters used by the DiscoveryClient routes you can do so by setting spring.cloud.gateway.discovery.locator.predicates[x] and spring.cloud.gateway.discovery.locator.filters[y]. When doing so you need to make sure to include the default predicate and filter above, if you want to retain that functionality. Below is an example of what this looks like.
주소
spring.cloud.gateway.discovery.locator.predicates[0].name: Path
spring.cloud.gateway.discovery.locator.predicates[0].args[pattern]: "'/'+serviceId+'/**'"
spring.cloud.gateway.discovery.locator.predicates[1].name: Host
spring.cloud.gateway.discovery.locator.predicates[1].args[pattern]: "'**.foo.com'"
spring.cloud.gateway.discovery.locator.filters[0].name: Hystrix
spring.cloud.gateway.discovery.locator.filters[0].args[name]: serviceId
spring.cloud.gateway.discovery.locator.filters[1].name: RewritePath
spring.cloud.gateway.discovery.locator.filters[1].args[regexp]: "'/' + serviceId + '/(?<remaining>.*)'"
spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/${remaining}'"
문서 소개 에 따 르 면 이 방식 에 따라 등록 센터 에서 단언 과 필 터 를 설정 할 수 있 습 니 다.5:SpringGateway 데이터베이스 설정 루트
public class DBRouteDefinitionRepository implements RouteDefinitionRepository
프로젝트 에서 Route DefinitionRepository 를 실현 한 후,springgateway 는 이 클래스 를 사용 하여 루트 를 불 러 옵 니 다.만약 실현 되 지 않 는 다 면,그의 기본 적 인 방식 으로 루트 를 불 러 옵 니 다
public class DBRouteDefinitionRepository implements RouteDefinitionRepository {
//
private final Map<String, RouteDefinition> routes = synchronizedMap(new LinkedHashMap<String, RouteDefinition>());
private Logger log = LoggerFactory.getLogger(DBRouteDefinitionRepository.class);
//
private boolean init_flag = true;
//
private final GatewayProperties properties;
private DynamicRouteServiceImpl service;
public DBRouteDefinitionRepository(GatewayProperties properties) {
this.properties = properties;
this.service = new DynamicRouteServiceImpl();
}
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
if(init_flag) {
List<RouteDefinition> routeDefinitions = new ArrayList<>();
List<RouteDefinition> rs = new ArrayList<>();
try {
routeDefinitions = service.quertAllRoutes();// route
rs = this.properties.getRoutes();// route
for (RouteDefinition rse : rs) {
routeDefinitions.add(rse);
}
routes.clear();
routeDefinitions.forEach(x->routes.put(x.getId(), x));
init_flag=false;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error("Init Route Fail,Can't get Routes.",e);
}
return Flux.fromIterable(routeDefinitions);
}else {
return Flux.fromIterable(routes.values());
}
}
@Override
public Mono<Void> delete(Mono<String> routeId) {
return routeId.flatMap(id -> {
if (routes.containsKey(id)) {
routes.remove(id);
return Mono.empty();
}
return Mono.defer(() -> Mono.error(new NotFoundException("RouteDefinition not found: "+routeId)));
});
}
@Override
public Mono<Void> save(Mono<RouteDefinition> route) {
return route.flatMap( r -> {
routes.put(r.getId(), r);
return Mono.empty();
});
}
}
이것 은 제 가 실현 한 클래스 입 니 다.이 클래스 는 데이터베이스 와 프로필 에서 루트 설정 을 얻 을 수 있 고 데이터베이스 에서 루트 설정 을 얻 으 면 개인의 요구 에 따라
@Validated
public class RouteDefinition {
@NotEmpty
private String id = UUID.randomUUID().toString();
@NotEmpty
@Valid
private List<PredicateDefinition> predicates = new ArrayList<>();
@Valid
private List<FilterDefinition> filters = new ArrayList<>();
@NotNull
private URI uri;
private int order = 0;
public RouteDefinition() {
}
public RouteDefinition(String text) {
int eqIdx = text.indexOf('=');
if (eqIdx <= 0) {
throw new ValidationException("Unable to parse RouteDefinition text '" + text
+ "'" + ", must be of the form name=value");
}
setId(text.substring(0, eqIdx));
String[] args = tokenizeToStringArray(text.substring(eqIdx + 1), ",");
setUri(URI.create(args[0]));
for (int i = 1; i < args.length; i++) {
this.predicates.add(new PredicateDefinition(args[i]));
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<PredicateDefinition> getPredicates() {
return predicates;
}
public void setPredicates(List<PredicateDefinition> predicates) {
this.predicates = predicates;
}
public List<FilterDefinition> getFilters() {
return filters;
}
public void setFilters(List<FilterDefinition> filters) {
this.filters = filters;
}
public URI getUri() {
return uri;
}
public void setUri(URI uri) {
this.uri = uri;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RouteDefinition routeDefinition = (RouteDefinition) o;
return Objects.equals(id, routeDefinition.id)
&& Objects.equals(predicates, routeDefinition.predicates)
&& Objects.equals(order, routeDefinition.order)
&& Objects.equals(uri, routeDefinition.uri);
}
@Override
public int hashCode() {
return Objects.hash(id, predicates, uri);
}
@Override
public String toString() {
return "RouteDefinition{" + "id='" + id + '\'' + ", predicates=" + predicates
+ ", filters=" + filters + ", uri=" + uri + ", order=" + order + '}';
}
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.