Spring Cloud API网关服务 5.2

为何须要API网关

  经过前面内容的学习,咱们已经能够构建一个简单的微服务架构系统。这个系统可使用Spring Boot实现微服务的开发,使用Spring Cloud Eureka实现注册中心以及服务的注册与发现,使用Spring Cloud Ribbon实现服务间的负载均衡,使用Spring Cloud Hystrix实现线程的隔离和断路器功能。经过这些技术,能够设计出如图5-11所示的基础架构。

  在图5-11中,集群包含了Service A和Service B两种服务,它们会向Eureka Server注册和订阅服务,Open Service是一个对外的RESTful API服务,客户端会经过负载均衡技术(如Nginx)实现对Open Service的调用,同时服务之间也会经过Ribbon技术实现服务之间负载均衡的调用。
虽然经过这种方式实现系统功能是没有问题的,但在实际使用时,客户端与微服务进行直接的交互仍是存在着一些困难和限制的,具体表现以下。

  1. 增长开发和维护成本
  在大多数状况下,为了保证对外服务的安全性,开发人员在服务端实现的服务接口会有必定的权限校验机制(如用户登陆状态校验等),而且为了防止客户端在发起请求时被篡改等安全方面的考虑,还会编写一些签名校验功能。在微服务中,咱们会将原来处于一个应用中的多个模块拆分红多个应用服务,而这些拆分出来的应用服务接口也须要原来的校验逻辑,这就致使咱们不得不在这些应用中所有实现这样的一套逻辑。随着微服务规模的不断扩大,这些校验逻辑的冗余将愈来愈多,一旦校验规则有了变化或者出了问题,咱们将不得不去每个应用中修改这些逻辑。

  2. 微服务重构困难
  随着时间的推移,咱们可能须要改变系统服务目前的拆分方案(如将两个服务合并或将一个服务拆分为多个),但若是客户端直接与微服务交互,那么这种重构就很难实施。

  3. 微服务协议限制
  客户端直接请求的微服务可能使用的是与Web无关的协议。一个服务多是用Thrift的RPC协议,而另外一个服务多是用AMQP消息协议,两种协议都不是特别适合浏览器或防火墙,最好是内部使用。应用应该在防火墙外采用HTTP或者WEBSocket之类的协议。

  因为上述缘由,客户端直接与服务器端通讯的方式几乎不会在实际应用中使用。那么咱们要如何解决上面这些问题呢?
  一般来讲,一个很好的解决办法就是采用API Gateway(网关)的方式。API Gateway是一个服务器,也能够说是进入系统的惟一节点,它封装了内部系统的架构,而且提供了API给各个客户端。它还能够有其余功能,如受权、监控、负载均衡、缓存、请求分片和管理、静态响应处理等。

 

  图5-12展现了一个适应当前架构的API Gateway。

  在图5-12中,API Gateway负责请求转发、合成和协议转换。全部来自客户端的请求都要先通过API Gateway,而后负载均衡这些请求到对应的微服务。
API Gateway的一个最大好处是封装了应用的内部结构,与调用指定的服务相比,客户端直接跟Gateway交互会更简单。API Gateway提供给每个客户端一个特定API,这样减小了客户端与服务器端的通讯次数,也简化了客户端代码。API Gateway还能够在Web协议与内部使用的非Web协议间进行转换,如HTTP协议、WebSocket协议。
  API Gateway能够有不少实现方法,如Nginx、Zuul、Node.js等。本书中使用的是Spring Cloud Netflix中的Zuul,下一小节咱们将对Spring Cloud Zuul的使用进行详细讲解。

如何使用Zuul构建API网关服务

  Zuul原是Netflix公司开发的基于JVM的路由器和服务器端负载均衡器,后来被加入到了Spring Cloud中。Zuul属于边缘服务,能够用来执行认证、动态路由、服务迁移、负载均衡、安全和动态响应处理等操做。
了解了Zuul的概念和做用后,接下来经过一个具体的应用案例来说解如何在微服务中使用Zuul。
  本案例主要涉及到3个工程,其做用分别以下。
  ·xcservice-eureka-server工程:服务注册中心,端口为8761。
  ·xcservice-eureka-order工程:服务提供者,须要启动一个订单实例,其端口号为7900。
  ·xcservice-gateway-zuul工程:使用Zuul实现的APIGateway,端口号为8050。
  上面3个工程中,注册中心和服务提供者可使用前面所建立的工程,而网关服务须要从新建立,其实现过程以下。
  (1)建立工程,添加依赖。在父工程xcservice-spring-cloud下建立子模块xcservice-gateway-zuul工程,并在其pom.xml中添加eureka和Zuul的依赖,如文件5-8所示。
  文件5-8 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.xc</groupId>
        <artifactId>xcservice-springcloud</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>com.xc</groupId>
    <artifactId>xcservice-gateway-zuul</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>xcservice-gateway-zuul</name>
    <description>网关服务</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

 

  (2)编辑配置文件。在配置文件中编写Eureka服务实例的端口号、服务端地址等信息,如文件5-9所示。
  文件5-9 application.yml
server:
  port: 8050 # 指定该Eureka实例的端口号

eureka:
  instance:
    prefer-ip-address: true  # 是否显示主机的IP
    #instance-id: ${spring.cloud.client.ipAddress}:${server.port} #将Status中的显示内容也以“IP:端口号”的形式显示
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/ # 指定Eureka服务端地址

spring:
  application:
    name: xcservice-gateway-zuul # 指定应用名称

zuul:
  routes:
    order-serviceId: # zuul的惟一标识
      path: /order/**   # 须要映射的路径
      service-id: xcservice-eureka-order  # Eureka中的serviceId

  在上述配置信息中,zuul就是API网关服务的路由配置。其中order-serviceId为Zuul的惟一标识,能够任意设置名称,但必须惟一,若是该值与service-id的名称相同时,service-id的值能够省略。path属性后面的值表示须要映射的路径,service-id后面的值为Eureka中的serviceId,应用在运行时,全部符合映射路径的URL都会被转发到xcservice-eureka-order中。java

  须要注意的是,Zuul的配置方式有不少,这里只是针对本案例实现的一种方式。若是读者想要了解更多的配置方式,能够参考官方文档中Zuul的配置进一步学习。spring


  (3)在工程主类Application中使用@EnableZuulProxy注解开启Zuul的API网关功能,其代码如文件5-10所示。
package com.xc.xcservicegatewayzuul;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

/**
 * http://localhost:8050/xcservice-eureka-order/order/1
 */
@EnableZuulProxy
@SpringBootApplication
@EnableEurekaClient
public class XcserviceGatewayZuulApplication {

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

}

 

  (4)分别启动注册中心、服务提供者和网关服务后,注册中心已注册的服务如图5-13所示。

  此时能够经过地址http://localhost:7900/order/1单独访问订单服务   下面经过Zuul来验证路由功能,经过网关服务来访问订单信息。在浏览器地址栏中输入地址http://localhost:8050/xcservice-eureka-order/order/1后,浏览器已经显示出来所要访问的订单信息。这说明使用Zuul配置的路由功能已经生效,经过服务ID映射的方式已能够进行跳转。 
相关文章
相关标签/搜索