前面写了服务的负载均衡搭建应用,这次开始搭建zuul服务。
至于为什么要用zuul组件呢?
因为页面对多服务的调用过程中,每个服务是不是都还得对每次的http请求和权限进行检查控制,总不能挨个服务加一套吧?
所以需要将这部分功能独立出来,有zuul实现。
一、创建zuul-service服务
二、在启动类上添加注解
@EnableEurekaClient
@EnableZuulProxy
package com.example.zuulservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulServiceApplication.class, args);
}
}
三、修改配置文件
spring.application.name=zuul-service
# 应用服务 WEB 访问端口
server.port=8400
#忽略未配置的其他访问
zuul.ignored-services=*
#添加对ribbon-client服务的代理路由(将以/ribbon/开头的请求转到ribbon-client服务)
zuul.routes.ribbon.path=/ribbon/**
zuul.routes.ribbon.service-id=ribbon-client
#添加对feign-client服务的代理路由将以/feign/开头的请求转到feign-client服务)
zuul.routes.feign.path=/feign/**
zuul.routes.feign.service-id=feign-client
四、依次启动eureka-server、eureka-client、ribbon-client、feign-client、zuul-service后进行测试
访问feign服务同理,就不贴出来了。
以上是zuul的路由功能,下面接着写zuul的过滤功能
过滤器分为以下4中:
Pre filters:(个人理解为请求过滤,如果不妥还请指正 )
-
ServletDetectionFilter
:检测请求是否通过Spring Dispatcher。设置键为的布尔值FilterConstants.IS_DISPATCHER_SERVLET_REQUEST_KEY
。 -
FormBodyWrapperFilter
:解析表单数据并为下游请求重新编码。 -
DebugFilter
:如果debug
设置了请求参数,则将RequestContext.setDebugRouting()
和设置RequestContext.setDebugRequest()
为true
。
Route filters:(个人理解为服务过滤,如有不妥还请指正)
SendForwardFilter
:通过使用Servlet转发请求RequestDispatcher
。转发位置存储在RequestContext
属性中FilterConstants.FORWARD_TO_KEY
。这对于转发到当前应用程序中的端点很有用。
Post filters:(个人理解为返回过滤,如有不妥还请指正)
SendResponseFilter
:将代理请求的响应写入当前响应。
Error filters:(个人理解为异常过滤,如有不妥还请指正)
SendErrorFilter
:/error
如果RequestContext.getThrowable()
不为null,则转发到(默认情况下)。您可以/error
通过设置error.path
属性来更改默认转发路径()。
光说不练假把式,接着写一个自定义过滤器(以pre filter 为例)
package com.example.zuulservice.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@Component
public class QueryParamPreFilter extends ZuulFilter {
@Override
public int filterOrder() {
return 0;
// return PRE_DECORATION_FILTER_ORDER - 1; // run before PreDecoration
}
@Override
public String filterType() {
return "pre";
// return PRE_TYPE;
}
@Override
public boolean shouldFilter() {
// RequestContext ctx = RequestContext.getCurrentContext();
// return !ctx.containsKey(FORWARD_TO_KEY) // a filter has already forwarded
// && !ctx.containsKey(SERVICE_ID_KEY); // a filter has already determined serviceId
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
String message = ctx.getRequest().getParameter("message");
if (message == null) {
// 设置zuul过滤器不向下进行过滤
ctx.setSendZuulResponse(false);
// 设置返回的code
ctx.setResponseStatusCode(401);
PrintWriter printWriter = null;
try {
HttpServletResponse response = ctx.getResponse();
response.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=utf-8");
printWriter = response.getWriter();
printWriter.write("参数message不能为空");
printWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(printWriter != null){
printWriter.close();
}
}
}
return null;
}
}
重启zuul-service测试
源码地址:https://github.com/houfanGitHub/springcloud.git