1. 概述
注意:内部服务之间请求数据一般不需要使用网关,因为多此一举。 - 而某些服务提供给外界使用则必须通过网关进行校验过滤
2. 简单使用
整合:Zuul和Eureka进行配合使用,将Zuul自身注册为Eureka服务治理下的应用,同时从Eureka中获得其他微服务的消息,也即以后的访问微服务都是通过Zuul跳转后获得
步骤1 - 添加依赖
<dependencies>
<!-- 默认集成熔断器Hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
步骤2 - 配置文件application.yml
server:
port: 8080
spring:
application:
name: apiGateway
eureka:
client:
#将可用区映射到与eureka服务器通信的完全限定URL列表
service-url:
defaultZone: http://127.0.0.1:1111/eureka/
eureka-server-port:
registry-fetch-interval-seconds: 1
instance:
#获取要注册到eureka的该实例的唯一ID(在appName范围内) -- 默认为服务名+端口号。
instance-id: apiGateway
# 表示在猜测主机名时,服务器的IP地址应用于参考操作系统报告的主机名的标志。 -eureka中介存储Ip地址
prefer-ip-address: true
#服务失效时间 -- 90s内没接收到心跳包,则该服务进入自我保护功能 -- 服务90s后自动删除(接收心跳包从重新刷新时间)
lease-expiration-duration-in-seconds: 90
#服务每隔几秒发送心跳包进行验证该服务还能进行提供使用 -- (服务30s内发送心跳包证明自己存活)
lease-renewal-interval-in-seconds: 30
ribbon:
ReadTimeout: 90000
ConnectTimeout: 90000
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 1
hystrix:
command:
c4i-store:
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 90000
ribbon:
#服务连接之后断开的时间
ReadTimeout: 90000
#服务与服务从未连接到连接的时间
ConnectTimeout: 90000
# 自定义通过网关访问服务的地址
zuul:
routes:
productService: /apiGateway/productService/**
orderService: /apiGateway/orderService/**
memberService: /apiGateway/memberService/**
advService: /apiGateway/advService/**
#忽略匹配的地址
ignored-patterns: /*Service/**
#阻止网关清理cookie的信息
sensitive-headers:
步骤3 - 启动类添加两个注解@EnableZuulProxy、@EnableEurekaClient
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
步骤4 - 测试
3. 网关跨域配置 - 强烈建议添加
@Configuration
public class MyConfig {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
// 允许cookies跨域
config.setAllowCredentials(true);
// #允许跨域访问的域名地址+端口号,*表示所有域名+端口号都被允许
// 如果设成*,会自动转成当前请求头中的Origin
config.addAllowedOrigin("*");
// config.addAllowedOrigin("http://localhost:8888");
// #允许访问的头信息,*表示全部
config.addAllowedHeader("*");
// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
config.setMaxAge(7200L);
// 允许请求的方法,*表示全部允许 get、post等等
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
4. 网关过滤功能
@Component
public class loginFilter extends ZuulFilter {
//定义网关过滤的类型
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
//定义网关过滤器的优先顺序,越小有优先过滤
@Override
public int filterOrder() {
return 6;
}
//判断是否应该放行请求 true调用run方法,false不调用run方法放行处理
@Override
public boolean shouldFilter() {
// 获取当前请求的上下文
RequestContext currentContext = RequestContext.getCurrentContext();
//设置响应回去的字符编码
currentContext.getResponse().setContentType("application/json;charset=UTF-8");
HttpServletRequest request = currentContext.getRequest();
String requestURI = request.getRequestURI();
if(requestURI.startsWith("/apiGateway/productService")) {
return true;
}
return false;
}
// 核心方法,请求放行之后的逻辑处理,被拦截的不会经过这里
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
// 放行后检查请求头是否有 token字段
String token = request.getHeader("token");
// 没有token字段 则返回未授权页面给浏览器
if(token == null || token.trim() == "") {
//拒绝请求分发给微服务进行处理
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
// 有token字段则放行,给具体的微服务进行处理
return null;
}
}