简述
Zuul会代理所有注册到Eureka Server的微服务,并根据Zuul路由规则跳转到不同的微服务上,并且在跳转前可以进行一系列的过滤.
环境
3个服务
1.eureka服务:http://localhost:7001/eureka
2.provider(服务提供者):{
spring.application.name:provider
使用的测试接口地址为:/provider/test/getTestAll
}
3.zuul服务:80 {
zuul.prefix: /api
}
1.添加架包
关键架包 zuul和eureka
<!--引入网关依赖-->
<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>
2.创建启动项
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class,args);
}
}
3.配置yml文件
server:
port: 80
spring:
application:
name: zuul
eureka:
client:
register-with-eureka: true
fetchRegistry: true
service-url:
defaultZone: http://localhost:7001/eureka
instance:
instance-id: zuul80
prefer-ip-address: true
zuul:
prefix: /api # 访问网关路径的前缀(在映射路径的前面,一般用于区别开发的版本)
routes:
zuul-service01: # 随意写的区分不同映射服务器的名称(只是区分不同的映射服务器)
path: /myZullProvider/** # 自定义映射服务器路径的名称(相当于key,外部访问这个地址会映射到下面的service-id这个value值。然后从eureka服务列表找到对应服务名称,进而负载均衡的请求一个服务器)
# url: http://localhost:80 # 这是写的固定映射url,可代替service-id。但是不能实现服务器的负载均衡和高可用,因为总是访问同一服务器
service-id: provider # eureka注册中心中要映射的服务名称,因为是双层map结构,所以可以实现负载均衡和高可用
#http://localhost/api/myZullProvider/provider/test/getTestAll
#http://地址:端口/${zuul.prefix}/${zuul.routes.zuul-service01.path}/目标接口
# zuul-service02: # 搭建另一个映射服务器,这里就简单的映射同一服务了。简单测试下而已
# path: /user-service-zuul-first/**
# service-id: user-service # 映射服务器名称简单的使用上面的,仅供测试
# 配置zuul的连接时间,一般不需要配置
# host:
# max-per-route-connections:
# socket-timeout-millis:
# connect-timeout-millis:
# ignored-services: microservice-comsumer-movie-ribbon-withhystrix # 这是表示某一个服务不允许代理,上面配置的是需要代理的
通过访问http://localhost/api/myZullProvider/provider/test/getTestAll 即可访问到服务provider对应接口http://地址:端口/${zuul.prefix}/${zuul.routes.zuul-service01.path}/目标服务接口地址
4.自定义过滤规则
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* @author kittlen
* @version 1.0
* @date 2021/4/26 0026 10:11
* @email kittlen@qq.com
*/
@Slf4j
@Component
public class MyZuulFilter extends ZuulFilter {
@Override
public String filterType() {
// 登录校验的过滤级别,肯定是第一层过滤
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
// 执行顺序,值越小执行顺行越靠前
return FilterConstants.PRE_DECORATION_FILTER_ORDER;
}
@Override
public boolean shouldFilter() {
// 默认此类过滤器时false,不开启的,需要改为true
return true;
}
/**
* 登录校验过滤器,执行逻辑的方法
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
// 1)获取zuul提供的请求上下文对象(即是请求全部内容)
RequestContext rc=RequestContext.getCurrentContext();
// 2) 从上下文中获取request对象
HttpServletRequest request=rc.getRequest();
log.info(String.format("send %s request to %s", request.getMethod(), request.getRequestURL().toString()));
// 如果校验通过,可以考虑吧用户信息放入上下文,继续向后执行
return null;
}
}