SpringCloud之服务网关
1.zuul
1.1定义
zuul叫路由网关,它包含对请求的路由和过滤的功能。
路由负责将外部的请求转发到具体的微服务实例上,是实现外部访问统一入口的基础。而过滤是负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能基础。
1.2项目开发
源代码:https://github.com/zhongyushi-git/cloud-zuul.git
1)参考ribbon的项目新建一个项目cloud-zuul,把eureka集群、api以及服务提供者8001拿过来
2)在pom中导入依赖
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- zuul路由网关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
3)配置yml
server:
port: 9527 spring:
application:
name: cloud-zuul-gateway #把客户端注册到服务列表中
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/, http://eureka7002.com:7002/eureka/, http://eureka7003.com:7003/eureka/
#设置入驻的服务的名称,是唯一的
instance:
instance-id: gateway-9527.com
#访问路径显示ip
prefer-ip-address: true
4)在hosts文件添加映射
127.0.0.1 myzuul.com
5)在com.zys.cloud包下创建启动类并添加注解@EnableZuulProxy
package com.zys.cloud; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication
@EnableZuulProxy
public class ZuulMain9527 {
public static void main(String[] args) {
SpringApplication.run(ZuulMain9527.class, args);
}
}
6)启动测试
先启动eureka集群,然后启动微服务提供者8001,最后启动路由9527。
不用路由访问:http://localhost:8001/user/get/1
使用路由访问: http://myzuul.com:9527/cloud-provider/user/get/1,其中cloud-provider是微服务提供者的名称
在使用路由访问的时候,暴露出了微服务的名称,但是一般情况下是不会这样做的,因此需要对微服务名称进行代理。
7)配置服务代理
在路由的yml配置代理的名称并设置不能使用微服务名进行访问。
#配置微服务代理
zuul: routes:
#指定要代理的微服务名称
myuser.serviceId: cloud-provider
#指定代理的路径
myuser.path: /myuser/**
#忽略真实的服务名,即不能使用服务名访问,只能通过代理访问以保证安全
#忽略单个微服务
ignored-services: cloud-provider
#批量忽略微服务
# ignored-services: "*"
重启路由的服务,访问http://myzuul.com:9527/myuser/user/get/1是没有问题的,访问http://myzuul.com:9527/cloud-provider/user/get/1出现404,已达到效果。
实例中设置忽略了单个微服务,如果要批量忽略微服务,给ignored-services设置为"*"即可。
8)设置统一前缀
有时候多个系统之间访问的路径需要相同的前缀,这个时候只需要在yml配置即可。
zuul:
#设置统一的前缀
prefix: /springcloud
然后访问的时候都需要加这个前缀,访问路径是http://myzuul.com:9527/springcloud/myuser/user/get/1。
2.gateway
2.1定义
旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤功能,如熔断、限流、重试等。三大核心概念如下:
Route(路由):是构建网关的基本模块,由ID、URL、一系列断言和过滤器组成。
Predicate(断言):用于匹配Http请求中的所有内容,如果匹配则进行路由。
Filter(过滤):指的是Spring框架中GatewayFilter的实例
2.2zuul与gateway的区别
它是基于WebFlux框架实现的,而WebFlux框架底层使用了高性能的Reactor模式通信框架Netty,是基于异步非阻塞模型开发的。而zuul使用的是阻塞框架。
2.3项目开发
源代码:https://github.com/zhongyushi-git/cloud-gateway.git
2.3.1环境搭建
1)创建maven的父工程cloud-gateway,导入依赖
<!--统一管理jar包版本-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
</properties> <!-- 依赖管理,父工程锁定版本-->
<dependencyManagement>
<dependencies>
<!--spring boot 2.2.2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud Hoxton.SR1-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
2)创建eureka服务子模块cloud-eureka-server7001,导入依赖
<dependencies>
<!--eureka server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--boot web actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependencies>
3)eureka的yml配置
server:
port: 7001 eureka:
instance:
#eureka服务端的实例名称
hostname: localhost
client:
#false表示不向注册中心注册自己
register-with-eureka: false
#false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
#设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
4)创建eureka启动类
package com.zys.cloud; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class, args);
}
}
5)创建服务提供者子模块cloud-provider8001,导入依赖
<dependencies>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--boot web actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
6)8001的yml配置
server:
port: 8001 spring:
application:
name: cloud-provider #把客户端注册到服务列表中
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka/
#设置入驻的服务的名称,是唯一的
instance:
instance-id: cloud-provider8001
#访问路径显示ip
prefer-ip-address: true
7)创建8001启动类
package com.zys.cloud; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication
@EnableEurekaClient
public class ProviderMain8001 {
public static void main(String[] args) {
SpringApplication.run(ProviderMain8001.class, args);
}
}
8)创建8001的controller接口
package com.zys.cloud.controller; import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*; import java.util.Date; @RestController
@RequestMapping("/user")
public class UserController { @Value("${server.port}")
private String port; @Value("${eureka.client.service-url.defaultZone}")
private String eureka; @GetMapping("/get")
public String get(){
return "server port is \t"+port+".\t\t\t\t time:"+new Date();
} @GetMapping("/get2")
public String get2(){
return "eureka server is \t"+eureka+".\t\t\t\t time:"+new Date();
} }
9)创建服务提供者子模块cloud-provider8002,方式同8001,只是端口号不同。创建完成后先启动eureka,然后启动8001和8002,在浏览器测试接口。
2.3.2创建路由子模块cloud-gateway9527
1)导入依赖
<dependencies>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
需要注意的是,这里不需要导入web。
2)yml配置
server:
port: 9527 spring:
application:
name: cloud-gateway
cloud:
gateway:
#开启从注册中心动态创建路由的功能,利用微服务名进行路由
discovery:
locator:
enabled: true
routes:
- id: provider_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
uri: lb://cloud-provider #匹配后提供服务的路由地址,根据服务名访问
predicates:
- Path=/user/get/** #断言,路径相匹配的进行路由 - id: provider_routh #路由的ID,没有固定规则但要求唯一,简易配合服务名
uri: lb://cloud-provider #匹配后提供服务的路由地址
predicates:
- Path=/user/get2/** #断言,路径相匹配的进行路由 eureka:
instance:
hostname: cloud-gateway-service
instance-id: cloud-gateway
#访问路径显示ip
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka/
3)创建启动类
package com.zys.cloud; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication
@EnableEurekaClient
public class GatewayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GatewayMain9527.class,args);
}
}
4)启动测试
先启动eureka,然后启动8001和8002,最后启动9527。浏览器输入http://127.0.0.1:9527/user/get2就可以正常访问了。多刷新几次,可以看出是8001和8002轮询的。
2.3.3动态路由配置
除了2.3.2中使用yml的方式配置路由外,还可以通过编码方式配置。
新建配置类GateWayConfig
package com.zys.cloud.config;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* 编码方式配置路由
*/
@Configuration
public class GateWayConfig {
/**
* 配置一个id为route-name的路由规则,
* 当访问地址http://localhost:9527/guonei时会自动转发到地址:http://news.baidu.com/guonei
* @param routeLocatorBuilder
* @return
*/
@SuppressWarnings("JavaDoc")
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("path_route1",
r -> r.path("/guonei")
.uri("http://news.baidu.com/guonei")).build();
return routes.build();
}
}
重启9527,访问地址http://localhost:9527/guonei时会自动转发到地址:http://news.baidu.com/guonei。
2.3.4断言配置
有时候为了进行配置,就可以配置断言。
例如:配置get2请求在某个时间后生效。只需要在yml的predicates设置After即可。
predicates:
- Path=/user/get2/** #断言,路径相匹配的进行路由
- After=2020-04-09T21:15:28.872+08:00[Asia/Shanghai]
后面的时间格式必须正确,获取格式时间的方法
public static void getTime(){
ZonedDateTime zbj = ZonedDateTime.now();
System.out.println(zbj);
}
又如设置请求的方法必须为get
predicates:
- Path=/user/get2/** #断言,路径相匹配的进行路由
- After=2020-04-09T21:15:28.872+08:00[Asia/Shanghai]
- Method=GET
2.3.5过滤器配置
自定义一个过滤器,只有在请求中包含unmae且不为null时才能访问。创建过滤器类MyLogGateWayFilter
package com.zys.cloud.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono; /**
* 自定义过滤器
*/
@Component
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//每次进来后判断带不带uname这个key
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
//uname为null非法用户
if(uname == null){
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
重启9527,访问地址http://127.0.0.1:9527/user/get2时无法访问,而http://127.0.0.1:9527/user/get2?uname=1可以正常访问。
SpringCloud之服务网关的更多相关文章
- 八、springcloud之服务网关zuul(一)
一.Zuul简介 zuul 是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用. Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器. ...
- 微服务SpringCloud之服务网关zuul二
Zuul的核心 Filter是Zuul的核心,用来实现对外服务的控制.Filter的生命周期有4个,分别是“PRE”.“ROUTING”.“POST”.“ERROR”,整个生命周期可以用下图来表示. ...
- 微服务SpringCloud之服务网关zuul一
前面学习了Eureka.Feign.Hystrix.Config,本篇来学习下API网关zuul.在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的url,路由到相应的服 ...
- SpringCloud的服务网关zuul
演示如何使用api网关屏蔽各服务来源 一.概念和定义 1.zuul最终还是使用Ribbon的,顺便测试一下Hystrix断路保护2.zuul也是一个EurekaClient,访问服务注册中心,获取元数 ...
- 二十一、springcloud(七)服务网关zuul
1.简介 Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,在微服务架构中,后端 ...
- 九、springcloud之服务网关zuul(二)
一.路由熔断 当我们的后端服务出现异常的时候,我们不希望将异常抛出给最外层,期望服务可以自动进行一降级.Zuul给我们提供了这样的支持.当某个服务出现异常时,直接返回我们预设的信息. 我们通过自定义的 ...
- SpringCloud之服务网关Gateway,入门+实操
SpringCloudAlibaba微服务实战教程系列 Spring Cloud 微服务架构学习记录与示例 一. GateWay简介 Spring Cloud GateWay是Spring Cloud ...
- 【微服务】之六:轻松搞定SpringCloud微服务-API网关zuul
通过前面几篇文章的介绍,我们可以轻松搭建起来微服务体系中比较重要的几个基础构建服务.那么,在本篇博文中,我们重点讲解一下,如何将所有微服务的API同意对外暴露,这个就设计API网关的概念. 本系列教程 ...
- SpringCloud微服务负载均衡与网关
1.使用ribbon实现负载均衡ribbon是一个负载均衡客户端 类似nginx反向代理,可以很好的控制htt和tcp的一些行为.Feign默认集成了ribbon. 启动两个会员服务工程,端口号分别为 ...
随机推荐
- 小白搭建WAMP详细教程---apache安装与设置
一.apache官网下载Apache HTTP Server服务器 1.打开apache官网http://www.apache.org/,拉到最底下,找到HTTP Server,点击进去下载.也可以直 ...
- UI自动化实战进阶后续
前言 最近几天因为回老家的缘故,暂时没空学习和记录,好不容易抽空那就赶紧开始后面的实战. 前面我们已经基本完成了测试的框架,并且也有了PO设计模式,后面我们还缺少什么呢?做为自动化测试最主要的测试报告 ...
- HDU-3240(卡特兰数+分解质因数后求逆元)
卡特兰数相关公式 : \(H_n = {C_{2n}^n \over n+1)}\) \(H_n = {(4n-2)\over n+1}\times H_{n-1}\) \(H_n = C_{2n}^ ...
- Codeforces 1355 C. Count Triangles
传送门:C - Count Triangles 题意:给你四个数A,B,C,D,求有多少个三边为x,y,z (A ≤ x ≤ B ≤ y ≤ C ≤ z ≤ D)的三角形. 题解:枚举 x=A~B, ...
- 用数组模拟STL中的srack(栈)和queue(队列)
我们在理解stack和queue的基础上可以用数组来代替这两个容器,因为STL中的stack和queue有可能会导致程序运行起来非常的慢,爆TLE,所以我们使用数组来模拟他们,不仅可以更快,还可以让代 ...
- Milk Patterns POJ - 3261 后缀数组
Farmer John has noticed that the quality of milk given by his cows varies from day to day. On furthe ...
- Codeforces Global Round 9 B. Neighbor Grid (构造,贪心)
题意:给一个\(n\)X\(m\)的矩阵,矩阵中某个数字\(k\)表示其四周恰好有\(k\)个不为0的数字,你可以使任意位置上的数字变大,如果操作后满足条件,输出新矩阵,否则输出NO. 题解:贪心,既 ...
- 要想用活Redis,Lua脚本是绕不过去的坎
前言 Redis 当中提供了许多重要的高级特性,比如发布与订阅,Lua 脚本等.Redis 当中也提供了自增的原子命令,但是假如我们需要同时执行好几个命令的同时又想让这些命令保持原子性,该怎么办呢?这 ...
- Scanner用户交互
Scanner用户交互 Scanner对象 引入语法: Scanner scanner=new Scanner(System.in);(固定的) 小写scanner为定义的名称 scanner.clo ...
- k8s二进制部署 - coredns安装
coredns的资源清单文件rabc.yaml apiVersion: v1 kind: ServiceAccount metadata: name: coredns namespace: kube- ...