Spring Cloud构建微服务架构:服务网关(基础)【Dalston版】

释放双眼,带上耳机,听听看~!

通过之前几篇Spring Cloud中几个核心组件的介绍,我们已经可以构建一个简略的(不够完善)微服务架构了。比如下图所示:
Spring Cloud构建微服务架构:服务网关(基础)【Dalston版】
我们使用Spring Cloud Netflix中的Eureka实现了服务注册中心以及服务注册与发现;而服务间通过Ribbon或Feign实现服务的消费以及均衡负载;通过Spring Cloud Config实现了应用多环境的外部化配置以及版本管理。为了使得服务集群更为健壮,使用Hystrix的融断机制来避免在微服务架构中个别服务出现异常时引起的故障蔓延。

在该架构中,我们的服务集群包含:内部服务Service A和Service B,他们都会注册与订阅服务至Eureka Server,而Open Service是一个对外的服务,通过均衡负载公开至服务调用方。本文我们把焦点聚集在对外服务这块,这样的实现是否合理,或者是否有更好的实现方式呢?

先来说说这样架构需要做的一些事儿以及存在的不足:

  • 首先,破坏了服务无状态特点。为了保证对外服务的安全性,我们需要实现对服务访问的权限控制,而开放服务的权限控制机制将会贯穿并污染整个开放服务的业务逻辑,这会带来的最直接问题是,破坏了服务集群中REST API无状态的特点。从具体开发和测试的角度来说,在工作中除了要考虑实际的业务逻辑之外,还需要额外可续对接口访问的控制处理。(通俗的解释:应该是如果每一个服务提供者需要安全就必须加入权限控制,但是权限控制又需要一些手段来解析,这样和业务代码混合了!并且如果不是用了 session共享 和 JWT 等技术,就会造成有状态服务)
  • 其次,无法直接复用既有接口。当我们需要对一个即有的集群内访问接口,实现外部服务访问时,我们不得不通过在原有接口上增加校验逻辑,或增加一个代理调用来实现权限控制,无法直接复用原有的接口。(通俗的解释:也是说权限代码不能很容易和业务代码融合吧?如果加入 zuul这个门面就可以解决了,他在最前面检查用户是否已经有权限了!

面对类似上面的问题,我们要如何解决呢?下面进入本文的正题:服务网关!

为了解决上面这些问题,我们需要将权限控制这样的东西从我们的服务单元中抽离出去,而最适合这些逻辑的地方就是处于对外访问最前端的地方,我们需要一个更强大一些的均衡负载器,它就是本文将来介绍的:服务网关。

服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由、均衡负载功能之外,它还具备了权限控制等功能。Spring Cloud Netflix中的Zuul就担任了这样的一个角色,为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。

下面我们通过实例例子来使用一下Zuul来作为服务的路有功能。

准备工作

在构建服务网关之前,我们先准备一下网关内部的微服务,可以直接使用前几篇编写的内容,比如:

  • eureka-client
  • eureka-consumer

在启动了eureka-client和eureka-consumer的实例之后,所有的准备工作就以就绪,下面我们来试试使用Spring Cloud Zuul来实现服务网关的功能。

构建服务网关

使用Spring Cloud Zuul来构建服务网关的基础步骤非常简单,只需要下面几步:

  • 创建一个基础的Spring Boot项目,命名为:api-gateway。并在pom.xml中引入依赖:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1<parent>
2  <groupId>org.springframework.boot</groupId>
3  <artifactId>spring-boot-starter-parent</artifactId>
4  <version>1.5.4.RELEASE</version>
5  <relativePath/>
6</parent>
7
8<dependencies>
9  <dependency>
10    <groupId>org.springframework.cloud</groupId>
11    <artifactId>spring-cloud-starter-zuul</artifactId>
12  </dependency>
13  <dependency>
14    <groupId>org.springframework.cloud</groupId>
15    <artifactId>spring-cloud-starter-eureka</artifactId>
16  </dependency>
17</dependencies>
18
19<dependencyManagement>
20  <dependencies>
21    <dependency>
22      <groupId>org.springframework.cloud</groupId>
23      <artifactId>spring-cloud-dependencies</artifactId>
24      <version>Dalston.SR1</version>
25      <type>pom</type>
26      <scope>import</scope>
27    </dependency>
28  </dependencies>
29</dependencyManagement>
30
31
  • 创建应用主类,并使用@EnableZuulProxy注解开启Zuul的功能。


1
2
3
4
5
6
7
8
9
10
11
1@SpringBootApplication
2@EnableZuulProxy
3public class ApiGatewayApplication {
4
5    public static void main(String[] args) {
6        SpringApplication.run(ApiGatewayApplication.class, args);
7    }
8
9}
10
11
  • 创建配置文件application.yml,并加入服务名、端口号、eureka注册中心的地址:


1
2
3
4
5
6
7
8
9
10
11
12
13
1spring:
2  application:
3    name: api-gateway
4
5server:
6  port: 1101
7
8eureka:
9  client:
10    serviceUrl:
11      defaultZone: http://eureka.didispace.com/eureka/
12
13

到这里,一个基于Spring Cloud Zuul服务网关就已经构建完毕。启动该应用,一个默认的服务网关就构建完毕了。由于Spring Cloud Zuul在整合了Eureka之后,具备默认的服务路由功能,即:当我们这里构建的api-gateway应用启动并注册到eureka之后,服务网关会发现上面我们启动的两个服务eureka-client和eureka-consumer,这时候Zuul就会创建两个路由规则。每个路由规则都包含两部分,一部分是外部请求的匹配规则,另一部分是路由的服务ID,如下所示。针对当前示例的情况,Zuul会创建下面的两个路由规则:

  • 转发到eureka-client(这是服务ID)服务的请求规则为:/eureka-client/** (这是匹配规则)
  • 转发到eureka-consumer(这是服务ID)服务的请求规则为:/eureka-consumer/** (这是匹配规则)

最后,我们可以通过访问1101端口的服务网关来验证上述路由的正确性:

比如访问:http://localhost:1101/eureka-client/dc ,该请求将最终被路由到eureka-client的/dc接口上。(解释:这里的http://localhost:1101/是本项目api-gateway的server.port端口号,而eureka-client是在eureka注册中心上的某个服务应用名称,/dc是该服务下的某个接口方法)

转载地址来源:
http://blog.didispace.com/spring-cloud-starter-dalston-6-1/

给TA打赏
共{{data.count}}人
人已打赏
安全网络

CDN安全市场到2022年价值76.3亿美元

2018-2-1 18:02:50

安全活动

房价or二胎 职场人最关心的问题到底是什么?

2016-12-18 16:22:20

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索