官网说明 Netflix uses Zuul for the following:
Authentication 认证
Insights 洞察力
Stress Testing 压力测试
Canary Testing 金丝雀测试
Dynamic Routing 动态路由
Service Migration 服务迁移
Load Shedding 减载
Security 安全
Static Response handling 静态响应处理
Active/Active traffic management
Zuul可以实现好些功能,路由功能是微服务的一部分,这里主要记录下使用zuul做负载均衡。
具体配置如下:
在根目录spring_cloud中创建Maven Moudle模块:zuul-server
pom.xml
spring-cloud
com.sam
0.0.1
4.0.0
zuul-server
org.springframework.cloud
spring-cloud-starter-zuul
创建消费者服务启动类:ZuulApplication
package com.sam.zuul.server;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
/**
* @ClassName: ZuulApplication
* @Description: Zuul路由服务
* Zuul的主要功能是路由和过滤器。路由功能是微服务的一部分,zuul实现了负载均衡。
* @author sam
* @date 2018年8月10日 上午11:38:24
*/
@SpringCloudApplication //这个注解整合了@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreake
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
@Bean
public MyZuulFilter getZuulFilter(){
return new MyZuulFilter();
}
}
创建过滤器:MyZuulFilter
package com.sam.zuul.server;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
/**
* @ClassName: MyZuulFilter
* @Description: 自定义过滤器
* @author sam
* @date 2018年8月10日 上午11:23:11
*/
public class MyZuulFilter extends ZuulFilter {
private static Logger log = LoggerFactory.getLogger(MyZuulFilter.class);
/**
* 返回过滤器类型
*
* @return pre:可以在请求被路由之前调用 routing:在路由请求时候被调用 post:在routing和error过滤器之后被调用
* error:处理请求时发生错误时被调用
*/
@Override
public String filterType() {
return "pre";
}
/**
* 通过int值来定义过滤器的执行顺序
*/
@Override
public int filterOrder() {
return 0;
}
/**
* 判断过滤器是否执行
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 过滤器的具体逻辑 ctx.setSendZuulResponse(false)令zuul不允许请求,
* ctx.setResponseStatusCode(401)设置了其返回的错误码
* ctx.setResponseBody(body)编辑返回body内容
*
* @return
*/
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
Object id = request.getParameter("id");
if (id == null) {
log.warn("id is null");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
return null;
}
log.info("pass!");
return null;
}
}
创建配置文件:application.yml
spring:
application:
name: zuul
server:
port: 8020
eureka:
client:
service-url:
defaultZone: http://localhost:8010/eureka/
zuul:
routes:
api-a:
path: /service-producer/**
serviceId: service-producer
api-b:
path: /service-producer-c/**
serviceId: service-producer-c
sensitive-headers: #设置忽略的头信息,设置为空能解决会话保持问题
add-host-header: true #设为true才能保持Host头信息处理正确
上面配置说明
把/service-producer/开头的所有请求都转发给service-producer服务执行,
把/service-producer-c/开头的所有请求都转发给service-producer-c服务执行,
PS: 由于用到新的一个生产者服务,于是创建一个新的生产者服务service-producer-c,直接从service-producer-A拷贝一份,修改端口名称,及服务名,其它的一致,其中配置文件application.yml如下:
spring:
application:
name: service-producer-c
server:
port: 8813
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8010/eureka/ #eureka服务注册地址
注意名称是 service-producer-c 。
以上配置完成后,启动 zuul-server 等服务,如下图:
访问Zuul服务,
分别打开
http://localhost:8020/service-producer/hi?id=zuul
hi, zuul, service-producer:8811
和
http://localhost:8020/service-producer-c/hi?id=zuul
hi, zuul, service-producer-c:8813
可以看到Zuul已经实现了相应的路由规则,根据不同的访问路径进行动态 分发!