Spring cloud zuul (初级)

1.简介

  (1)Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,似乎一个微服务框架已经完成了。

还是少考虑了一个问题,外部的应用如何来访问内部各种各样的微服务呢?

在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的url,路由到相应的服务。当添加API网关后,在第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制,后将请求均衡分发给后台服务端。

  (2)在Spring Cloud体系中, Spring Cloud Zuul就是提供负载均衡、反向代理、权限认证的一个API gateway。

  (3)Zuul网关使用模式,以及自动转发机制,但其实Zuul还有更多的应用场景,比如:鉴权、流量转发、请求统计等等,这些功能都可以使用Zuul来实现。

2.为什么需要api gateway

2.1简化客户端调用复杂度

  在微服务架构模式下后端服务的实例数一般是动态的,对于客户端而言很难发现动态改变的服务实例的访问地址信息。因此在基于微服务的项目中为了简化前端的调用逻辑,通常会引入API Gateway作为轻量级网关,同时API Gateway中也会实现相关的认证逻辑从而简化内部服务之间相互调用的复杂度。

2.2数据裁剪及聚合

  通常而言不同的客户端对于显示时对于数据的需求是不一致的,比如手机端或者Web端又或者在低延迟的网络环境或者高延迟的网络环境。
因此为了优化客户端的使用体验,API Gateway可以对通用性的响应数据进行裁剪以适应不同客户端的使用需求。同时还可以将多个API调用逻辑进行聚合,从而减少客户端的请求数,优化客户端用户体验

2.3多渠道支持

  当然我们还可以针对不同的渠道和客户端提供不同的API Gateway,对于该模式的使用由另外一个大家熟知的方式叫Backend for front-end, 在Backend for front-end模式当中,我们可以针对不同的客户端分别创建其BFF,进一步了解BFF可以参考这篇文章:Pattern: Backends For Frontends

2.4 遗留系统的微服务化改造

  对于系统而言进行微服务改造通常是由于原有的系统存在或多或少的问题,比如技术债务,代码质量,可维护性,可扩展性等等。API Gateway的模式同样适用于这一类遗留系统的改造,通过微服务化的改造逐步实现对原有系统中的问题的修复,从而提升对于原有业务响应力的提升。通过引入抽象层,逐步使用新的实现替换旧的实现。

#3.Spring cloud zuul (初级)

  Spring Cloud Zuul路由是微服务架构的不可或缺的一部分,提供动态路由,监控,弹性,安全等的边缘服务。Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。

3.1简单的应用

3.1.1pom.xml

 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.3.RELEASE</version>
</parent> 
  <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-config-server -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zuul</artifactId>
        <version>1.3.1.RELEASE</version>
    </dependency>

</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
<!--注意:这里必须要添加,否则各种依赖有问题-->
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/libs-milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

3.1.2application.yml

spring:
  application:
    name: cloud-starter-zuul

server:
  port: 8001

zuul:
  routes:
    baidu:
      path: /it/**
      url: http://www.ityouknow.com/springcloud/

3.1.3main方法启动

@SpringBootApplication
@EnableZuulProxy //支持网关路由。
public class ZuulRun {
    public static void main(String[] args) {
        SpringApplication.run(ZuulRun.class, args);
    }

}

3.1.4测试访问

在浏览器中访问:http://127.0.0.1:8001/it/spring-cloud,看到页面返回了:http://www.ityouknow.com/spring-cloud 页面的信息,
说明访问Cloud-Starter-ZUUL的请求自动转发到了http://www.ityouknow.com/spring-cloud,并且将结果返回。

3.2服务化

  通过url映射的方式来实现zull的转发有局限性,比如每增加一个服务就需要配置一条内容,另外后端的服务如果是动态来提供,就不能采用这种方案来配置了。实际上在实现微服务架构时,服务名与服务实例地址的关系在eureka server中已经存在了,所以只需要将Zuul注册到eureka server上去发现其他服务,就可以实现对serviceId的映射。

### 3.2.1eureka注册中心

3.2.1.1pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
</parent> 
  <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        <version>2.0.1.RELEASE</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
<!--注意:这里必须要添加,否则各种依赖有问题-->
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/libs-milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

3.2.1.2 application.yml

server:
  port: 8000

spring:
  application:
    name: zuul-eureka

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8000/eureka
    register-with-eureka: false
fetchRegistry: false

3.2.1.3 main方法启动

@SpringBootApplication
@EnableEurekaServer
public class EurekaRun {
    public static void main(String[] args) {
        SpringApplication.run(EurekaRun.class, args);
    }
}

3.2.2producer生产者

3.2.2.1pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.3.RELEASE</version>
</parent> 
  <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.3.1.RELEASE</version>
</dependency>

</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
<!--注意:这里必须要添加,否则各种依赖有问题-->
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/libs-milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

3.2.2.2application.yml

server:
  port: 8002

spring:
  application:
    name: zuul-producer

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8000/eureka

3.2.2.3main方法启动

@SpringBootApplication
@EnableDiscoveryClient
public class ProducerRun {

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

3.2.2.4Controller

@RestController
public class TestHello {

    @RequestMapping("/test")
    public String getHello(@RequestParam String name){
        return name+",say hello1";
    }
}

3.2.3gataway 网关调用

3.2.3.1pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.3.RELEASE</version>
</parent> 
  <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-config-server -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zuul</artifactId>
        <version>1.3.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.3.1.RELEASE</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
<!--注意:这里必须要添加,否则各种依赖有问题-->
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/libs-milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

3.2.3.2 application.yml

server:
  port: 8003

spring:
  application:
    name: zuul-gataway

zuul:
  routes:
    api-a:
      path: /producer/**
      serviceId: zuul-producer

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8000/eureka

3.2.3.3main方法启动

@SpringBootApplication
@EnableZuulProxy
public class GateWayRuN {
    public static void main(String[] args) {
        SpringApplication.run(GateWayRuN.class, args);
    }
}

3.2.4调试说明

浏览器 访问:http://127.0.0.1:8003/zuul-producer/test?name=’cc’

http://127.0.0.1:8003/producer/test?name=’cc’
说明访问zuul-gataway的请求自动转发到了zuul-producer,并且将结果返回。
返回:’cc’,say hello

负载均衡: 修改 producer生产者 启动端口,和controller 输出name,say hello 1
浏览器访问: http://127.0.0.1:8003/zuul-producer/test?name=’cc’

http://127.0.0.1:8003/producer/test?name=’cc’
返回:’cc’,say hello ,和 ‘cc’,say hello1
说明访问zuul-gataway的请求自动转发到了zuul-producer,同时负载均衡成功。

3.2.5网关的默认路由规则

  但是如果后端服务多达十几个的时候,每一个都这样配置也挺麻烦的,spring cloud zuul已经帮我们做了默认配置。默认情况下,Zuul会代理所有注册到Eureka Server的微服务,并且Zuul的路由规则如下:http://ZUUL_HOST:ZUUL_PORT/微服务在Eureka上的serviceId/**会被转发到serviceId对应的微服务。

我们注销掉zuul-gataway项目中关于路由的配置:

#zuul:

routes:

api-a:

path: /producer/**

serviceId: zuul-producer

重新启动后,访问http://127.0.0.1:8003/zuul-producer/test?name=’cc’

测试返回结果如上述所示相同,说明Spring cloud zuul默认已经提供了转发功能。

文章标题:Spring cloud zuul (初级)

发布时间:2019-11-13, 17:35:48

最后更新:2019-11-13, 17:35:49