网关可以对请求进行过滤拦截,转发等,这种跟过滤器不一样,它可以拦截入口,而不是单独一个服务。
业务场景,会员服务和订单服务,用户必须登录才能调用相关接口(即含有userToken)。
项目架构
Eureka作为注册中心,会员服务和订单服务注册到Eureka。网关项目配置相关规则,其中会员项目和订单项目可以部署成集群环境,zuul默认使用ribbon作为负载均衡器。
其中Eureka跑8100端口,会员项目和订单项目可以参考我之前的博客(搭建Eureka注册中心),非常简单。
pom文件
org.springframework.boot
spring-boot-starter-parent
2.0.1.RELEASE
org.springframework.cloud
spring-cloud-dependencies
Finchley.M7
pom
import
org.springframework.cloud
spring-cloud-starter-netflix-zuul
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
spring-milestones
Spring Milestones
https://repo.spring.io/libs-milestone
false
如果需要实现动态配置网关,可以结合springcloud config实现,需要增加如下pom依赖。
org.springframework.boot
spring-boot-starter-actuator
org.springframework.cloud
spring-cloud-config-client
application.yml
###服务注册地址
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8100/eureka/
###api网关端口号
server:
port: 8000
###网关名称
spring:
application:
name: service-zuul
# cloud:
# config:
# ####读取后缀
# profile: dev
# ####读取config-server注册地址
# discovery:
# service-id: config-server
# enabled: true
###默认服务读取eureka注册服务列表 默认间隔30秒
zuul:
routes:
api-a:
### 以 /api-member/访问转发到会员服务
path: /api-member/**
serviceId: app-itmayiedu-member
api-b:
### 以 /api-order/访问转发到订单服务
path: /api-order/**
serviceId: app-itmayiedu-order
###开启所有监控中心接口
#management:
# endpoints:
# web:
# exposure:
# include: "*"
启动类,@EnableZuulProxy 开启网关代理
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class AppGateWay {
// @EnableZuulProxy 开启网关代理
public static void main(String[] args) {
SpringApplication.run(AppGateWay.class, args);
}
// zuul配置能够使用config实现实时更新
// @RefreshScope
// @ConfigurationProperties("zuul")
// public ZuulProperties zuulProperties() {
// return new ZuulProperties();
// }
}
过滤器,使用@component注册到容器
@Component
public class TokenFilter extends ZuulFilter {
// 编写过滤器拦截业务逻辑代码
public Object run() throws ZuulException {
// 案例:拦截所有的服务接口,判断服务接口上是否有传递userToken参数
// 1.获取上下文
RequestContext currentContext = RequestContext.getCurrentContext();
// 2.获取 Request
HttpServletRequest request = currentContext.getRequest();
// 3.获取token 的时候 从请求头中获取
String userToken = request.getParameter("userToken");
if (StringUtils.isEmpty(userToken)) {
// 不会继续执行... 不会去调用服务接口,网关服务直接响应给客户端
currentContext.setSendZuulResponse(false);
currentContext.setResponseBody("userToken is null");
currentContext.setResponseStatusCode(401);
return null;
// 返回一个错误提示
}
// 正常执行调用其他服务接口...
return null;
}
public boolean shouldFilter() {
return true;
}
// 过滤器执行顺序,当一个请求在同一个阶段的时候存在多个过滤器的时候,多个过滤器执行顺序
public int filterOrder() {
return 0;
}
// 过滤类型 pre 表示在请求之前进行执行
@Override
public String filterType() {
return "pre";
}
// 网关过滤器如何编写
}
注意点:网关项目增加actuator和config
org.springframework.boot
spring-boot-starter-actuator
org.springframework.cloud
spring-cloud-config-client
开启所有监控
##开启所有监控中心接口
management:
endpoints:
web:
exposure:
include: "*"
增加配置中心配置,service-id跟server端要一致
cloud:
config:
####读取后缀
profile: dev
####读取config-server注册地址
discovery:
service-id: config-server
enabled: true
启动类中增加如下代码
// zuul配置能够使用config实现实时更新
@RefreshScope
@ConfigurationProperties("zuul")
public ZuulProperties zuulProperties() {
return new ZuulProperties();
}
配置中心服务端application.yml
###服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
spring:
application:
####注册中心应用名称
name: config-server
cloud:
config:
server:
git:
###git环境地址
uri: https://gitee.com/huang_baokang_daxian/microservices.git
####搜索目录
search-paths:
- gkconfig
####读取分支
label: master
####端口号
server:
port: 8888
启动类
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
pom.xml
org.springframework.boot
spring-boot-starter-parent
2.0.1.RELEASE
org.springframework.cloud
spring-cloud-dependencies
Finchley.M7
pom
import
org.springframework.cloud
spring-cloud-config-server
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
spring-milestones
Spring Milestones
https://repo.spring.io/libs-milestone
false