Spring Cloud 学习——6. netflix zuul 实现网关路由、负载均衡

1.前言

  在一个大微服务架构的系统中,可能存在着很多服务,如果将这些服务全部对外暴露,会带来很多问题。比如安全问题,有些核心服务直接对外暴露很容易被攻击;比如身份验证问题,有些接口服务是要求登录的,如果各种服务各自对外暴露,那么这些要求登录的请求第一个触达的服务模块都要向“用户服务模块”查询鉴权结果,这样既对“用户服务模块”造成额外压力,也增加了这些其它服务模块的开发成本,所以应该考虑将身份验证的事情交到网关模块中直接完成;比如运维难度和成本问题,如果每一种服务都各自对外暴露,那么整个系统就需要提供很多个域名(或者引入额外的路由中间件,如:nginx)。为了解决这些问题,给系统添加一个网关是很有必要的。

2.创建一个spring boot 模块

  

3.添加依赖

<dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
                <version>2.2.1.RELEASE</version>
            </dependency>

  版本自选。

4.启用zuul

  启动类:

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class RouteZuulApplication {

    public static void main(String[] args) {
        SpringApplication.run(RouteZuulApplication.class, args);
    }

}

  其中, @EnableEurekaClient  注解是将该网关模块声明为eureka服务客户端,从而注册到 eureka server(这个很容易理解,既然作为网关,那么肯定是需要将请求转发到其它服务模块,那么就需要从注册中心获取其它所有服务的信息的); @EnableZuulProxy  注解这是启用 zuul 组件,该组件内置了 ribbon 负载均衡并且默认开启。

5.配置路由

  application.properties 配置:

server.port=7100
server.servlet.context-path=/gateway

spring.application.name=gateway

##################### eureka 实例(instance)信息配置 ####################
eureka.instance.appname=${spring.application.name}
#eureka.instance.hostname=localhost

##################### eureka 注册中心(server)特性配置。该模块为服务模块,不是注册中心,所以无需配置 ##################

##################### eureka 客户端(client)特性配置 ####################
#是否向 eureka server 注册服务(默认true)
eureka.client.enabled=true
eureka.client.register-with-eureka=true
#是否向 eureka server 查找服务列表(默认true)
eureka.client.fetch-registry=true
eureka.client.service-url.defaultZone=http://localhost:7000/eureka/server/eureka/

##################### zuul 网关配置 #######################################
zuul.host.max-total-connections=500
zuul.host.max-per-route-connections=50
#开启饥饿加载(zuul内置使用 ribbon 调用远程服务地址,而 ribbon 客户端默认是懒加载的,即第一次调用的时候才加载),配置为 true 代表应用启动的时候就加载。默认false
#zuul.ribbon.eager-load.enabled=true
zuul.routes.user=/user/**

  其中:

    5.1. zuul.routes  接收一个  Map<String, ZuulProperties.ZuulRoute>  类型的参数集,zuul.routes. 后紧跟的点分串值(上例中的 “user”)就是 map 参数的key,同一个 key 认为是一组配置,通常代表着一种服务;

    5.2. path 参数指定路由规则的前缀,即该组路由规则适用于 url 前缀为 /user/** 的请求,/user/** 代表任意以 /user开通的url,/user/*则只能匹配一级;

    5.3. service-id 指定服务,可以是服务名(eureka.instance.appname 指定的值);

    5.4. 综上,本例中路由规则的含义是:所有 http://hostname:port/user/** 的请求都转发到 sys 服务模块。

  上述  zuul.routes.user=/user/**  是一个服务级别的配置例子,就是说 user 服务的所有实例都会在这个路由规则里面,并参与负载均衡和熔断。另外,zuul 也支持更细粒度的配置,也就是指定服务的具体实例的 url 转发规则。这里不详述,请参照官方文档:https://cloud.spring.io/spring-cloud-static/Greenwich.SR5/multi/multi__router_and_filter_zuul.html#netflix-zuul-starter

    5.5. 关于路由超时配置,zuul 默认的超时时间不是很长,如果后端微服务调用链有耗时较长的,就会有很大概率一定会熔断。想要修改超时时间,分两种情况:

      5.5.1. 如果路由规则是使用服务发现的(本例),则配置: ribbon.ReadTimeout  和  ribbon.SocketTimeout ;

      5.5.2. 如果路由规则是直接指定服务的 url,则配置: zuul.host.connect-timeout-millis 和  zuul.host.socket-timeout-millis ;

6.验证结果

  本文中没有添加新的服务服务,使用的是前文中介绍的 sys 服务模块的 UserController,链接:

    Spring Cloud 学习——5.使用 feign 的 hystrix 支持

  结果:

    

   从结果看,网关服务已经生效了。

7.验证负载

  sys 接收该请求的接口代码:

    

  启动两个 sys 模块的进程实例,多次刷新请求,结果:

    

     

   从打印结果看,两个 sys 进程实例都打印了请求,并且数量相当,说明负载也生效了。这也说明 zuul 默认是开启负载的,并不需要额外的配置。

8.未完待续

  身份验证、支持 https 等相关功能和配置示例待续......

原文地址:https://www.cnblogs.com/coding-one/p/12302115.html