这两天工作有点忙 所以学习的进度也慢下来了 今天记录一下zuul
首先先放个图
我们使用了SpringCloud Netflix 中的Eureka实现了服务注册中心以及服务的注册和发现,儿服务件通过Ribbon或者Feign实现服务的消费以及负载均衡。为了使服务集群更加健壮,使用Hystrix的熔断机制来避免微服务架构中个别服务出现异常时引起的故障蔓延。
在该架构中我们的服务集群包括,内部服务Service A 和Service B ,他们都会注册与订阅服务至Eureka 服务中心,而open Service 是一个对外的服务,通过均衡负载公开至服务调用方。我们现在就来看看对外服务
下面是我从某处摘抄来的,比较高大上
- 首先,破坏了服务无状态特点。为了保证对外服务的安全性,我们需要实现对服务访问的权限控制,而开放服务的权限控制机制将会贯穿并污染整个开放服务的业务逻辑,这会带来的最直接问题是,破坏了服务集群中REST API无状态的特点。从具体开发和测试的角度来说,在工作中除了要考虑实际的业务逻辑之外,还需要额外可续对接口访问的控制处理。
- 其次,无法直接复用既有接口。当我们需要对一个即有的集群内访问接口,实现外部服务访问时,我们不得不通过在原有接口上增加校验逻辑,或增加一个代理调用来实现权限控制,无法直接复用原有的接口。
为了解决这么高大上的问题 我们就来说说服务网关
我们需要将权限控制这样的东西从我们的服务单元中抽离出去,而最合适这些逻辑的地方就是处于对外访问最前端的地方,我们需要一个更强大一些的均衡负载器,它就是我们要说的服务网关
服务网关是微服务架构中不可或缺的一部分。通过服务网关统一向外提供REST API的过程中,除了具备服务路由,负载均衡功能之外,还具备了权限控制等功能。SpringCloud Netflix 中的Zuul就担任了这样一个角色,为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主题能够具备更高的可复用性和可测试性。
下面进入正题,还是基于我们之前的工程
首先创建一个新的SpringBoot工程 service_zuul 需要依赖
web
eureka
zuul
pom文件是这样的
<?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>
<groupId>com.chunying</groupId>
<artifactId>zuul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>zuul</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Camden.SR6</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-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>
<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>
</project>
主类加注解@EnableEurekaClient 向注册中心注册,@EnableZuulProxy 开启zuul
package com.chunying.zuul;
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;
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
我们先来说服务的路由转发,当然是在配置文件中配置的,有两种配置方法
第一种配置URL与另一个服务路径对应
server.port=8766
spring.application.name=service_zuul
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
#routes to url 所有访问api-a-url/**的访问都映射到localhost:2222上
zuul.routes.api-a-url.path=/api-a-url/**
zuul.routes.api-a-url.url=http://localhost:2222/
端口8766 , 服务名称service_zuul , 服务中心地址http://localhost:8761/eureka/
下面的就重要了
zuul.routes.api-a-url.path=/api-a-url/**
zuul.routes.api-a-url.url=http://localhost:2222/
表示将所有/api-a-url/**的访问都映射到http://localhost:2222上面,也就是当访问http://localhost:1111/api-a-url/xxxx时会路由到http://localhost:2222/xxxx上面 , 我这里没有做测试 因为我并不喜欢用这种方法
所以我们看第二种:
第二种是通过服务名,
#routes to url 用eureka 服务名字进行负载调用
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.url=service_ribbon
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.url=service_feign
这里要注意path与url之前的 api-a是自定义的 但是必须要一一对应 否则就映射丢啦,这里的url使用的是我们之前ribbon和feign的服务名称。也就是说在访问/api-a/**时会路由到service_ribbon ,访问/api-b/时会路由到service_feign
启动我们所有的五个服务serv 8761 , client 8762、8763 (和之前的一样启动两个哈), service_ribbon 8764 , service_feign 8765 ,service_zuul 8766。
启动成功
访问 http://localhost:8766/api-b/hello?name=ying
浏览器交替出现
hello!8763,ying,come here
hello!8762,ying,come here
访问http://localhost:8766/api-a/hello?name=ying 是一样的 说明就成功了,我在练习这里的时候出现了一个问题,在第一次访问的时候总是会超时,继续就不会出现。
还没有找到解决办法 ,感觉配置一下超时时间就可以了~~好了服务路由配置就记录到这里了,继续加油咯