在spring cloud netflix时使用zuul作为官网,但是随着zuul2.0的多次跳票和getway异军突起。getway已经是一款主流的产品了,同时springcloud alibaba官网的推荐网关也是getway,所以在选型时不需要犹豫。干就完了。同时getway使用了webflux,较第一代网关更优秀。
1.为什么使用网关
使用网关后,对于系统相当有了一个统一的入口,例如你有100个微服务系统,现在只需要对外暴露网关的地址即可。同时所有的请求都是通过网关的分发,所以很方便的在网关上对请求拦截,重而实现反向代理,鉴权,流量控制,熔断,日志监控等。
2.实现
getway基础实现很简单。鉴权等功能会在以后章节中发布。
1.添加pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
复制代码
注意:getway使用的是webflux,不要引入spring-boot-starter-web
2.修改启动类
@EnableDiscoveryClient
@SpringBootApplication
public class GetwayApplication {
public static void main(String[] args) {
//去除nacos日志
System.setProperty("nacos.logging.default.config.enabled", "false");
SpringApplication.run(GetwayApplication.class, args);
}
}
复制代码
3.bootstrap.yml
getway也需要注册到nacos中。也需要将namespace和group对应。
server:
port: 6001
spring:
application:
name: gateway-server
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 192.168.xx.xx:8848
#命名空间
namespace: b80f0aa4-3af2-a6e3-c6fda24c2bc0
#分组
group: xxx
config:
# 配置中心地址
server-addr: 192.168.xx.xx:8848
# 配置文件格式
file-extension: yml
#命名空间
namespace: b80f0aa4-3af2-a6e3-c6fda24c2bc0
#分组
group: xxx
gateway:
routes:
# 路由标识(id:标识,具有唯一性)
- id: auth
# 目标服务地址(uri:地址,请求转发后的地址) 此处是nacos中服务名称
uri: lb://auth-server
# 路由条件(predicates:断言,匹配 HTTP 请求内容)
predicates:
## 当路径为/auth/xx/xx的请求都会转发到auth-server (也就是请求system-resource/auth/xx/xx)
- Path=/auth/**
- id: systemresource
uri: lb://system-resource
predicates:
- Path=/system/**
复制代码
楼主因为在小公司,所以只使用该规则就满足了业务要求,如果有其他规则使用,请自行百度,这里不具体介绍。
注意:
- getway只能获取同namespace和group中的服务。
- websocket接口与普通接口用以上配置就可以同时接受,不用额外配置路由。
3.配置oauth2的跨域
spring cloud ouath2 + getway跨域是有特别的配置的(与普通跨域不同)需要特别注意。
1.修改bootstrap.yml
spring:
cloud:
gateway:
globalcors:
add-to-simple-url-handler-mapping: true
corsConfigurations:
'[/**]':
# 支持跨域访问的来源 也就是前台地址 可以配置多个 方法如下
allowedOrigins:
- "http://192.168.xx.xx:8080"
- "http://192.168.xx.xx:8080"
# 切记 allowCredentials 配置 为true时,allowedOrigins不能为 *
allowCredentials: true
maxAge: 86400
# 支持的方法 * 代表所有
allowedMethods: "*"
allowedHeaders: "*"
exposedHeaders: "setToken"
routes:
# 路由标识(id:标识,具有唯一性) 截取请求
- id: auth
# 目标服务地址(uri:地址,请求转发后的地址)
uri: lb://auth
# 路由条件(predicates:断言,匹配 HTTP 请求内容)
predicates:
## 转发地址格式为 uri/archive,/str 部分会被下面的过滤器给截取掉
- Path=/auth/**
复制代码
2.添加GatewayConfig
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.config.GlobalCorsProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.util.pattern.PathPatternParser;
@Configuration
@EnableConfigurationProperties(GlobalCorsProperties.class)
public class GatewayConfig {
/**
* 配置全局解决cors跨域问题
*
* @return
*/
@Order(Ordered.HIGHEST_PRECEDENCE)
@RefreshScope
@Bean
public CorsWebFilter corsWebFilter(GlobalCorsProperties globalCorsProperties){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
globalCorsProperties.getCorsConfigurations().forEach((k,v) -> source.registerCorsConfiguration(k, v));
return new CorsWebFilter(source);
}
}
复制代码
注意如果网关中添加了跨域配置,业务服务就不要添加了,否则就会报错!