Previous article we introduced, Eureka for services registered in the discovery, Feign support service calls and load balancing, Hystrix processing service fuse to prevent the proliferation of failure, Spring Cloud Config service center cluster configuration, it seems that a micro-services framework has been completed .
We consider less a question of how external applications to access a wide variety of internal micro-services? In the micro-service architecture, the backend services are often not directly open to the calling terminal, but according to the appropriate service request url, routed through a gateway API. When adding API Gateway, third-party service providers and end calls between the parties to create a wall, this wall permissions control directly communicate with the caller, after requesting a balanced distribution to the background server.
Why do I need API Gateway
1, to simplify the complexity of client calls
The number of instances in the micro-services architecture model back-end services in general is dynamic, in terms of hard to find the client access address service instances dynamically changing information. Thus based on the micro-program services in order to simplify the front end of the call logic, which usually involves a gateway API Gateway As a lightweight, while API Gateway will also implementation-dependent authentication logic to simplify the complexity of the cross call between the inner and services.
2, cutting data and polymeric
Generally speaking a different client demand for the display data is inconsistent, such as mobile phones or the Web side and end or low-latency network environment or high-latency network environment.
Therefore, in order to optimize the client experience, API Gateway can be tailored to the versatility of the response data to suit the needs of different clients. But also can be a plurality of API call logic polymerization, thereby reducing the number of request from the client, the client user experience optimized
3, multi-channel support
Of course, we can also provide for different channels and client different API Gateway, for the use of this mode is called by another well-known way Backend for front-end, among Backend for front-end mode, we can target different client were to create their BFF.
4, micro-services transformation of legacy systems
对于系统系统而言进行微服务改造通常是由于原有的系统存在或多或少的问题,比如技术债务,代码质量,可维护性,可扩展性等等。API Gateway的模式同样适用于这一类遗留系统的改造,通过微服务化的改造逐步实现对原有系统中的问题的修复,从而提升对于原有业务响应力的提升。通过引入抽象层,逐步使用新的实现替换旧的实现。
在Spring Cloud体系中, Spring Cloud Zuul就是提供负载均衡、反向代理、权限认证的一个API gateway。
Spring Cloud Zuul
Spring Cloud Zuul路由是微服务架构的不可或缺的一部分,提供动态路由,监控,弹性,安全等的边缘服务。Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。
下面我们通过代码来了解Zuul是如何工作的
简单使用
1、添加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency>
引入spring-cloud-starter-netflix-zuul包
2、配置文件
spring.application.name=gateway-service-zuul
server.port=8888
#这里的配置表示,访问/it/** 直接重定向到http://www.ityouknow.com/**,其中baidu代表路由别名,没啥特殊意义
zuul.routes.baidu.path=/it/**
zuul.routes.baidu.url=http://www.ityouknow.com/
3、启动类
@SpringBootApplication @EnableZuulProxy public class GatewayServiceZuulApplication { public static void main(String[] args) { SpringApplication.run(GatewayServiceZuulApplication.class, args); } }
启动类添加@EnableZuulProxy
,支持网关路由。
史上最简单的zuul案例就配置完了
4、测试
启动gateway-service-zuul-simple
项目,在浏览器中访问:http://localhost:8888/it/spring-cloud
,看到页面返回了:http://www.ityouknow.com/spring-cloud
页面的信息,如下:
我们以前面文章的示例代码spring-cloud-producer
为例来测试请求的重定向,在配置文件中添加:
zuul.routes.hello.path=/hello/**
zuul.routes.hello.url=http://localhost:9000/
启动spring-cloud-producer
,重新启动gateway-service-zuul-simple
,访问:http://localhost:8888/hello/hello?name=%E5%B0%8F%E6%98%8E
,返回:hello 小明,this is first messge
说明访问gateway-service-zuul-simple
的请求自动转发到了spring-cloud-producer
,并且将结果返回。
服务化
通过url映射的方式来实现zull的转发有局限性,比如每增加一个服务就需要配置一条内容,另外后端的服务如果是动态来提供,就不能采用这种方案来配置了。实际上在实现微服务架构时,服务名与服务实例地址的关系在eureka server中已经存在了,所以只需要将Zuul注册到eureka server上去发现其他服务,就可以实现对serviceId的映射。
我们结合示例来说明,在上面示例项目gateway-service-zuul-simple
的基础上来改造。
1、添加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
增加spring-cloud-starter-netflix-eureka-client包,添加对eureka的支持。
2、配置文件
配置修改为:
spring.application.name=gateway-service-zuul
server.port=8888
zuul.routes.api-a.path=/producer/**
zuul.routes.api-a.serviceId=spring-cloud-producer
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
3、测试
依次启动 spring-cloud-eureka
、 spring-cloud-producer
、gateway-service-zuul-eureka
,访问:http://localhost:8888/producer/hello?name=%E5%B0%8F%E6%98%8E
,返回:hello 小明,this is first messge
说明访问gateway-service-zuul-eureka
的请求自动转发到了spring-cloud-producer
,并且将结果返回。
为了更好的模拟服务集群,我们复制spring-cloud-producer
项目改为spring-cloud-producer-2
,修改spring-cloud-producer-2
项目端口为9001,controller代码修改如下:
@RestController public class HelloController { @RequestMapping("/hello") public String index(@RequestParam String name) { return "hello "+name+",this is two messge"; } }
修改完成后启动spring-cloud-producer-2
,重启gateway-service-zuul-eureka
。测试多次访问http://localhost:8888/producer/hello?name=%E5%B0%8F%E6%98%8E
,依次返回:
hello 小明,this is first messge hello 小明,this is two messge hello 小明,this is first messge hello 小明,this is two messge ...
说明通过zuul成功调用了producer服务并且做了均衡负载。
网关的默认路由规则
但是如果后端服务多达十几个的时候,每一个都这样配置也挺麻烦的,spring cloud zuul已经帮我们做了默认配置。默认情况下,Zuul会代理所有注册到Eureka Server的微服务,并且Zuul的路由规则如下:http://ZUUL_HOST:ZUUL_PORT/微服务在Eureka上的serviceId/**
会被转发到serviceId对应的微服务。
我们注销掉gateway-service-zuul-eureka
项目中关于路由的配置:
#zuul.routes.api-a.path=/producer/**
#zuul.routes.api-a.serviceId=spring-cloud-producer
重新启动后,访问http://localhost:8888/spring-cloud-producer/hello?name=%E5%B0%8F%E6%98%8E
,测试返回结果和上述示例相同,说明spirng cloud zuul默认已经提供了转发功能。