Spring cloud实战-Zuul如何动态负载和服务发现扩容

来源:互联网 发布:100以内质数的和c语言 编辑:程序博客网 时间:2024/06/05 08:27

Zuul、Fegin、Rebbion、Eureka一条龙

很多人都自然而然把zuul当成nginx那样来在配置写死节点配置来。实际上zuul和eureka的是可以完美配合,完全可以基于服务名的注册和发现,来动态的实现服务的动态负载动态注册,从而达到不需要重启zuul即可达到动态扩容的。下文将介绍静态配置路由表和从Eureka发现服务的两种方式来加强Zuul的使用。

项目地址:

AG-Admin:http://git.oschina.net/geek_qi/ace-security

GateWay搭建

img

Maven依赖

<dpendency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-zuul</artifactId></dependency><dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-feign</artifactId></dependency><dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-eureka</artifactId></dependency><dependency>    <groupId>org.springframework.session</groupId>    <artifactId>spring-session</artifactId>    <version>1.2.2.RELEASE</version></dependency><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-redis</artifactId></dependency>

基于Eureka的application.yml(关键)

spring:    application:        name: ace-gate    thymeleaf:        mode: LEGACYHTML5        cache: false    redis:        database: 1        host: 127.0.0.1        pool:            max-active: 20server:    port: 8765 #启动端口#开启动态网关服务发现ribbon:  eureka:    enabled: true #配置zuul路由表,静态路由#zuul:#  #prefix: /techouse #为zuul设置一个公共的前缀#  #ignoredServices: '*'#  routes:#    ace-admin: #随便定义,当不存在serviceId时,默认该值为serviceId(就是注册服务的名称,属性spring.application.name)#      path: /test/** #匹配/test/** 均路由到cloud-client#基于静态路由节点的ribbon负载均衡配置#ace-admin:#  ribbon:#    listOfServers: 127.0.0.1:8767 eureka:    instance:        statusPageUrlPath: ${management.context-path}/info        healthCheckUrlPath: ${management.context-path}/health    client:        serviceUrl:            defaultZone: http://localhost:8761/eureka/security:    user:        name: admin        password: admin        role: USER#避免第一次调用失败hystrix:  command:    default:      execution:        isolation:          thread:            timeoutInMilliseconds: 5000#请求和响应GZIP压缩支持feign:  compression:    request:      enabled: true      mime-types: text/xml,application/xml,application/json      min-request-size: 2048    response:      enabled: true

启用Zuul、Fegin、Eureka注解

@SpringBootApplication@EnableEurekaClient@EnableDiscoveryClient@EnableFeignClients@EnableZuulProxy@EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE)public class GateBootstrap {    public static void main(String[] args) {        SpringApplication.run(GateBootstrap.class, args);    }}

Zuul filter拦截示例代码

@Componentpublic class SessionAccessFilter extends ZuulFilter {  private final Logger log = LoggerFactory.getLogger(SessionAccessFilter.class);  @Autowired  private SessionRepository<?> repository;  @Autowired  private IUserService userService;  @Override  public String filterType() {    return "pre";  }  @Override  public int filterOrder() {    return 1;  }  @Override  public boolean shouldFilter() {    return true;  }  @Override  public Object run() {    RequestContext ctx = RequestContext.getCurrentContext();    HttpSession httpSession = ctx.getRequest().getSession();    if (不符合权限){      setFailedRequest("<h1>Forbidden!</h1>",403);    }    return null;  }  /**   * 路由重定向   *   * @param body   * @param code   */  private void setFailedRequest(String body, int code) {    log.debug("Reporting error ({}): {}", code, body);    RequestContext ctx = RequestContext.getCurrentContext();    ctx.setResponseStatusCode(code);    if (ctx.getResponseBody() == null) {      ctx.setResponseBody(body);      ctx.setSendZuulResponse(false);      throw new RuntimeException("Code: " + code + ", " + body); //optional    }  }}

访问网关地址示例

[ip]:[zuul port]/[Eureak 注册服务]/[资源路径]

Zuul兼容动态注册和静态路由表

核心思路

基于Eureka上注册另一个zuul,通过主的zuul gate way来分流到另外一个zuul,从而兼容静态路由的情况。
img