Eureka用于服务的注册与发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的的熔断防止故障扩散,Spring Cloud Config 服务集群配置中心,似乎一个微服务框架已经完成了
我们还是少考虑了一个问题:外部的应用如何访问内部的各种各样的为服务呢?在微服务架构中,后端服务往往不直接给开放给调用端。而是通过一个API网关根据请求的url,路由到相应的服务。当添加API网关后,在第三方调用端口和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制,后将请求均衡分发给后台服务端。
为什么需要需要API Gateway
1,简化客户端调用复杂度
在微服务架构模式下后端服务的实例数一般是动态的,对于客户端而言发现动态改变的服务实例的访问地址信息。因此在基于微服务的项目中为了简化前端的调用逻辑,通常会引入API Gateway 作为轻量级网关,同时API Gateway中也会实现相关的认证逻辑从而简化内部服务之间相互调用的复杂度。
api_gateway.png
2,数据裁剪以及聚合
通常而言不同的客户端对于显示时对于数据的需求是不一致的,比如手机端或者web端又或者在低延迟的网络环境或者高延迟的网络环境
因此为了优化客户端的使用体验,API Gateway 可以通过对通用性的响应数据进行裁剪以适应不同客户端的使用需求。同时还可以将多个API调用逻辑进行聚合,从而减少客户端的请求数,优化客户端用户体验。
3,渠道支持
当然我们还可以针对不同的渠道和客户端提供不同的API Gateway,对于该模式的使用另外一个大家都熟知的方式叫 Backend for front-end,在Backend for front-end模式当中,我恶魔你可以针对不同的客户端分别创建其BFF,进一步了解BFF可以参考这个文章,Pattern: Backends For Frontends
4,遗留系统的微服务化改造
对于系统而言进行为服务改造通常由于原有的系统存在或多或少的问题,比如技术债务,代码质量,可维护性,可拓展性等等。API Gateway的模式同样适用于这一类遗留系统的改造,通过微服务化的改造逐步实现对元哪有系统中的问题修复,从而提升对于原有业务响应力的提升。通过引入抽象层,逐步使用新的实现替换旧的实现。
在spring Cloud体系中,Spring Cloud Zuul就是提供负载均衡,反向代理,权限认证的一个API gateway。
Spring Cloud Zuul
Spring Cloud Zuul 路由是微服务架构的不可或缺的一部分,提供动态路由,监控,弹性,安全等的边缘服务。Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。
下面通过代码来了解Zuul是如何工作的
Zuul 是提供动态路由,监控,弹性,安全等的边缘服务。Zuul相当于设备和 Netflix 流应用的 Web 网站后端所有请求的前门。
Zuul 可以适当的对多个Amazon Auto Scaling Groups进行路由请求
首先新建maven项目,加入如下依赖
<?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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.taotao</groupId>
<artifactId>zuul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zuul</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<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/milestone</url>
</repository>
</repositories>
</project>
启动类:
package com.taotao.zuul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@EnableZuulProxy
@SpringBootApplication
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
控制类;
package com.taotao.zuul.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HomeController {
@RequestMapping("/index")
public Object index(){
return "index";
}
@RequestMapping("/home")
public Object home(){
return "home";
}
}
配置文件;
server.port=8181
#这里的配置表示,访问/baidu/** 直接重定向到http://www.baidu.com
zuul.routes.baidu.path=/baidu/**
zuul.routes.baidu.url=http://www.baidu.com
#反响代理配置
#这里的配置类似nginx的反响代理
#当请求/api/**会直接交给listOfServers配置的服务器处理
#当stripPrefix=true的时候 (http://127.0.0.1:8181/api/user/list -> http://192.168.1.100:8080/user/list)
#当stripPrefix=false的时候(http://127.0.0.1:8181/api/user/list -> http://192.168.2.100:8080/api/user/list)
zuul.routes.api.path=/api/**
zuul.routes.api.stripPrefix=false
api.ribbon.listOfServers=192.168.2.100:8080,192.168.2.101:8080,192.168.2.102:8080
#url重写配置
#这里的配置,相当于访问/index/** 会直接渲染/home的请求内容(和直接请求/home效果一样), url地址不变
zuul.routes.index.path=/index/**
zuul.routes.index.url=forward:/home
http://127.0.0.1:8181/index
http://127.0.0.1:8181/api/user/list
http://127.0.0.1:8181/api/user/list
网友评论