发布于2026-06-02 阅读(0)
扫一扫,手机访问
在实际的微服务架构落地过程中,有一个问题始终绕不开:不同微服务通常拥有不同的网络地址,而一个完整的业务需求,往往需要客户端去调用多个服务接口。如果让客户端直接与各个微服务打交道,会带来一系列麻烦:

面对这些棘手的问题,引入微服务网关就成了一个顺理成章的选择。微服务网关可以看作客户端与服务器端之间的一个中间层,所有来自外部的请求都会先经过它,然后再被转发到后端的各个微服务,整个过程对客户端来说是透明的。

微服务网关将应用程序的内部结构封装得严严实实,客户端只需要与网关交互即可,无需关心背后具体是哪个微服务在提供服务。它的好处显而易见:不仅便于在网关这一层统一收集监控数据并推送到外部系统进行分析,还大大减少了客户端与各个微服务之间的直接交互次数。
注意:A服务和B服务之间的相互调用是允许的,作图时遗漏了这条线。另外,配置服务也作为微服务注册到了服务注册中心。
在Spring Cloud微服务体系中,一个常见的负载均衡方案是:客户端的请求首先经过负载均衡器(比如Zuul或Nginx),接着到达服务网关集群(如Zuul集群),然后再路由到具体的服务实例。所有服务都统一注册到高可用的服务注册中心集群,而服务的配置信息则统一由配置服务管理(这个我们留到下一篇文章详细讨论),配置服务的配置文件通常放在Git仓库中,方便开发人员随时调整。
Zuul是Netflix开源的微服务网关,它可以与Eureka、Ribbon、Hystrix等组件无缝配合使用。Spring Cloud对Zuul进行了很好的整合与增强,Zuul默认使用Apache HTTPClient作为HTTP客户端,当然你也可以根据需要换成RestClient或OkHttpClient。
Zuul的核心功能可以概括为两大块:路由转发和过滤器。路由功能是微服务架构的基础部分,例如,将/api/user的请求转发到user服务,将/api/shop的请求转发到shop服务。Zuul默认与Ribbon结合,实现了负载均衡的能力。
Zuul的核心是一系列过滤器,这些过滤器可以实现以下功能:
Zuul的功能列表如下:
我们继续沿用上一节创建的工程,在此基础上进行扩展。
首先,我们需要创建一个新的工程,它的pom.xml文件配置如下:
4.0.0 org.springframework.boot spring-boot-starter-parent 2.1.6.RELEASE com.lijunhao eureka-zuul 0.0.1-SNAPSHOT eureka-zuul Demo project for Spring Boot 1.8 Greenwich.SR1 org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-netflix-zuul org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.boot spring-boot-ma ven-plugin
在入口的Application类上加上@EnableZuulProxy注解,以开启Zuul的功能:
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class EurekaZuulApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaZuulApplication.class, args);
}
}
接下来,在application.yml文件中添加以下配置:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8080/eureka/
server:
port: 8088
spring:
application:
name: eureka-zuul
zuul:
routes:
api-a:
path: /student/**
serviceId: eureka-student
api-b:
path: /grade/**
serviceId: eureka-grade
这里指定了服务注册中心的地址是http://localhost:8080/eureka/,服务的端口是8088,服务名为eureka-zuul。同时,我们通过路由规则,将以/student/开头的请求转发给eureka-student服务,将以/grade/开头的请求转发给eureka-grade服务。
依次启动这五个工程后,访问http://localhost:8088/student/students,可以看到:

再访问http://localhost:8088/grade/grades,显示:

这说明Zuul已经成功地将请求路由到了对应的服务,发挥了网关的路由作用。
Zuul的功能远不止路由转发这么简单,它还能通过过滤器来执行一些安全验证等逻辑。我们继续改造这个工程,来实现一个自定义过滤器。
创建一个过滤器类:
@Component
public class MyFilter extends ZuulFilter {
private static Logger log = LoggerFactory.getLogger(MyFilter.class);
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
Object accessToken = request.getParameter("token");
if(accessToken == null) {
log.warn("token is empty");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
try {
ctx.getResponse().getWriter().write("token is empty");
}catch (Exception e){}
return null;
}
log.info("ok");
return null;
}
}
filterType()方法返回一个字符串,用于标识过滤器的类型。Zuul定义了四种不同生命周期的过滤器:
而filterOrder()方法决定了过滤器的执行顺序,shouldFilter()方法用于逻辑判断,决定当前请求是否需要经过该过滤器(这里我们设置为始终过滤)。run()方法则是过滤器的具体执行逻辑,它可以非常复杂,甚至可以查询数据库或NoSQL来判定请求是否有权限访问。
现在,直接访问http://localhost:8088/student/students,会看到:

而访问http://localhost:8088/student/students?token=0,则可以看到:

这里我们可以看到,当请求携带了正确的token参数时,过滤器放行;否则,网关会直接拒绝它并返回401状态码。一个简单的安全验证就这样实现了。
通过这篇文章,我们从微服务网关的必要性开始,逐步了解了Zuul的定位、核心功能,并通过一个实际的例子演示了如何创建一个Zuul网关服务,以及如何通过自定义过滤器来增加安全控制。Zuul在Spring Cloud微服务体系中的角色至关重要,它为微服务提供了统一的入口和强大的过滤能力,是构建生产级微服务应用不可或缺的组件。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8