1、在父工程 “microservicecloud” 下新建一个 Module,名称为 “zuul-8501”
2、修改 pom.xml 文件
microservicecloud
com.lakey.springcloud
1.0-SNAPSHOT
4.0.0
zuul-8501
zuul-8501
Zuul 8501
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-netflix-zuul
3、在 java 路径下创建目录 “com.lakey.springcloud” 并添加启动类 Zuul8501Application.java
package com.lakey.springcloud;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableEurekaClient // 本服务启动后会自动注册进eureka服务中
@EnableDiscoveryClient // 开启服务发现,寻找服务提供者
@EnableZuulProxy // 开启 Zuul 路由服务
public class Zuul8501Application {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Zuul8501Application.class);
application.setBannerMode(Banner.Mode.OFF);// 不输出Banner
application.run(args);
System.out.println(" _____ _ _ _ _ _ ___ ____ ___ _ \n" +
" |__ / | | | | | | | | | | ( _ ) | ___| / _ \\ / |\n" +
" / / | | | | | | | | | | / _ \\ |___ \\ | | | | | |\n" +
" / /_ | |_| | | |_| | | |___ | (_) | ___) | | |_| | | |\n" +
" /____| \\___/ \\___/ |_____| \\___/ |____/ \\___/ |_|");
}
}
4、在 resources 路径下添加配置文件 application.yml
# 服务器配置
server:
port: 8501
# Spring 配置
spring:
application:
name: zuul
# Eureka 配置
eureka:
client: # 客户端注册进 Eureka 服务列表
serviceUrl:
defaultZone: http://localhost:8101/eureka/
instance:
instance-id: zuul-8501 # 自定义服务名称信息
prefer-ip-address: true # 访问路径可以显示 IP 地址
# Eureka 微服务详细信息配置
info:
app.name: zuul-8501
company.name: www.lakey.com
build.artifactId: microservicecloud
build.version: 1.0-SNAPSHOT
# Zuul 配置
zuul:
# ignored-services: consumer-ribbon # 不允许通过某个具体服务名称调用接口
ignored-services: "*" # 不允许通过具体服务名称调用接口
prefix: /lakey # 统一入口
routes: # 路由配置
api-a:
path: /api-ribbon/**
serviceId: consumer-ribbon
api-b:
path: /api-feign/**
serviceId: consumer-feign
5、Zuul 路由说明
5.1、在不进行路由配置即删除 application.yml 文件中 Zuul 配置的情况下可直接通过服务名称访问服务,如:
通过 http://localhost:8501/provider/hello 直接访问生产者服务
通过 http://localhost:8501/consumer-ribbon/hello?name=liming 直接访问 robbin 消费者服务
通过 http://localhost:8501/consumer-feign/hello?name=liming 直接访问 feign 消费者服务
5.2、在添加了自定义路由配置即在 application.yml 文件中添加 Zuul 的 routes 后可通过自定义链接访问相应服务,如:
通过 http://localhost:8501/api-ribbon/hello?name=liming 直接访问 robbin 消费者服务
通过 http://localhost:8501/api-feign/hello?name=liming 直接访问 feign 消费者服务
5.3、在设置不允许通过服务名称调用接口配置即在 application.yml 文件中添加 Zuul 的 ignore-services 配置后,则不可再使用 5.1 中的方式进行访问,访问将会返回 404 错误
5.4、继续对路由进行统一规范,统一入口配置即在 application.yml 文件中添加 Zuul 的 prefix 配置后,5.2 中的访问方式也将失效,需要修改为 http://localhost:8501/lakey/api-ribbon/hello?name=liming 和 http://localhost:8501/lakey/api-feign/hello?name=liming
6、Zuul 还具有过滤作用,在目录 “com.lakey.springcloud” 下创建一个过滤器文件夹 “filter” 并添加继承自 ZuulFilter 的自定义过滤器 MyFilter.java
package com.lakey.springcloud.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* 自定义 Zuul 过滤器
*
* @author liming
* @date 2019-05-07
*/
@Component
public class MyFilter extends ZuulFilter {
private static Logger log = LoggerFactory.getLogger(MyFilter.class);
/**
* filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:
* pre:路由前
* routing:路由时
* post: 路由后
* error:捕获异常
*
* @return
*/
@Override
public String filterType() {
return "pre";
}
/**
* filterOrder:过滤的顺序
*
* @return
*/
@Override
public int filterOrder() {
return 0;
}
/**
* shouldFilter:过滤逻辑判断,是否要过滤
* @return
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 执行自定义过滤操作
*
* @return
*/
@Override
public Object run() {
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;
}
}
7、自定义过滤器 MyFilter.java 中对链接 token 做了过滤,因此 5.4 中的链接将被过滤,需修改为 http://localhost:8501/lakey/api-ribbon/hello?name=liming&token=123 和 http://localhost:8501/lakey/api-feign/hello?name=liming&token=123
8、目录结构截图:
9、参考文章:
https://github.com/forezp/SpringCloudLearning
10、码云源码:
https://gitee.com/nangongyanya/microservicecloud