博主分享免费Java教学视频,B站账号:Java刘哥
Zuul 是 Netflix 开源的微服务网关,它可以和 Eureka、Ribbon、Hystrix 等组件配合使用。Zuul 的核心就是一系列过滤器,这些过滤器可以完成以下功能:
2.启动类添加 @EnableZuulProxy 注解
3.添加配置
application.yml
启动在 9000 端口,注册服务到 Eureka
4.运行启动类,启动 Zuul 在 9000 端口
可以看到网关注册到了 Eureka
通过地址栏访问
http://localhost:9000/服务名/请求路径,就可以访问到其他服务的路径
如我的用户中心服务消费者服务名为 sens-user-web (上图左侧的 Application 名称是全部大写,实际我的服务名是全小写的)
即下面两个请求结果是一样的
http://localhost:9000/sens-user-web/hello
http://localhost:8081/hello
可见,网关帮我们转发了这个请求
如果想访问另一个服务,一样的方法
http://localhost:9000/sens-user-core/user/1 也能访问到 http://localhost:8080/user/1
可见,目前我们几乎没有任何其他的配置,就能实现通过网关访问到所有的请求
但是这还不够,下面我们会介绍自定义路由和容错回退的一些配置
上面几行配置,分别是设置统一的前缀,单条路由重写,排除自定义路由(排除后,访问404),排除服务(该服务所有请求404)
这样一来
配置前是 http://localhost:9000/sens-user-web/hello
配置后是 http://localhost:9000/api/user/hello
注意:因为我没有排除 sens-user-web,所有之前的 http://localhost:9000/sens-user-web/hello 也可以访问
效果如下
解决办法
在 pom.xml 中设置超时时间
重启网关服务
这个配置在 springboot 1.x 版本是 management.security.enabled=false,端点路径是 /routes和 /filters
- 身份认证和安全
- 审查和监控
- 动态路由
- 压力测试
- 负载均衡
- 等待
准备
Eureka 注册中心,启动在 8761 端口 一个或多个服务,注册在 Eureka 中 比如我目前 Eureka 上已经注册了两个服务 分别是用户中心的服务提供者(8080端口)和服务消费者(8081端口) 通过地址栏访问 http://localhost:8080/user/1 和 http://localhost:8081/hello 均能访问到两个服务 其中后者访问效果如下,下面以这个为示例,介绍网关的使用 下面我们来介绍 zuul,通过网关来访问这两个服务(通常我只暴露服务消费者,即 web 那个服务,服务提供者我们通常不暴露出去)一、编写 Zuul 微服务网关
1.创建一个 SpringBoot 项目 注意:目前我使用都是最新版本, SpringBoot 版本是 2.1.7.RELEASE,SpringCloud 版本是 Greenwich.RELEASE pom.xml 添加依赖- <!-- 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>
- @SpringBootApplication
- @EnableZuulProxy
- public class SensApiGatewayApplication {
- public static void main(String[] args) {
- SpringApplication.run(SensApiGatewayApplication.class, args);
- }
- }
- server:
- port: 9000
- spring:
- application:
- name: sens-api-gateway
- eureka:
- client:
- serviceUrl:
- defaultZone: http://localhost:8761/eureka/
二、自定义路由
目前通过网关访问其他服务的路径,示例如下 http://localhost:9000/sens-user-web/hello http://localhost:9000/sens-user-core/user/1 现在我有两个需求- 首先我觉得 sens-user-web 太长,我想改成 user
- sens-user-core 这个服务我不想暴露,我只想暴露服务消费者。访问生产者的话让网关响应404比较好
- zuul:
- # 前缀,所有服务里的路径前加 /api
- prefix: /api
- routes:
- sens-user-web: /user/**
- # 排除某些路由, 支持正则表达式
- ignored-patterns:
- - /**/abc/efg
- # 排除服务
- ignored-services: sens-user-core
三、设置超时时间
通常我们通过网关访问一个路径,如 http://localhost:9000/sens-user-web/hello, 网关会自己转发到 sens-user-web 服务中的 /hello 路径, 因为 Zuul 内部使用了 Ribbon 做负载均衡,那么对于一些时间比较长的请求,可能会被作为超时处理。 默认时间是 1 秒 示例 访问 http://localhost:9000/sens-user-web/hello 我在 sens-user-web 服务 /hello 方法里写一个 sleep,睡眠5s,看会不会超时(也可以通过打断点暂停的方法测试)- @GetMapping("/hello")
- public String index() throws InterruptedException {
- System.out.println("进来了");
- //主线程暂停5s
- Thread.sleep(5000);
- return "Hello, this is user web page.";
- }
- # 超时时间,ribbon和hystrix是同时生效的,哪个值小哪个生效
- hystrix:
- command:
- default:
- execution:
- isolation:
- thread:
- timeoutInMilliseconds: 60000
- ribbon:
- ReadTimeout: 60000
- ConnectTimeout: 3000
四、Zuul 的容错和回归
当服务不可用的时候,网关会响应 50X 之类的错 比如超时是这样的 这是系统默认的界面,很不友好 我们可以重写回归响应的方法,给用户一个比较好的提示 解决办法如下 在网关项目中新建一个类- package com.liuyanzhao.sens.api.gateway.config;
- import com.netflix.hystrix.exception.HystrixTimeoutException;
- import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.HttpStatus;
- import org.springframework.http.MediaType;
- import org.springframework.http.client.ClientHttpResponse;
- import org.springframework.stereotype.Component;
- import java.io.ByteArrayInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.nio.charset.Charset;
- /**
- * @author 言曌
- * @date 2019-08-08 10:34
- */
- @Component
- public class MyFallbackProvider implements FallbackProvider {
- @Override
- public String getRoute() {
- //表明是为哪个微服务提供回退,*表示所有微服务
- return "*";
- }
- @Override
- public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
- if(cause instanceof HystrixTimeoutException) {
- return response(HttpStatus.GATEWAY_TIMEOUT);
- }
- return this.fallbackResponse();
- }
- public ClientHttpResponse fallbackResponse() {
- return this.response(HttpStatus.INTERNAL_SERVER_ERROR);
- }
- private ClientHttpResponse response(final HttpStatus status) {
- return new ClientHttpResponse() {
- @Override
- public HttpStatus getStatusCode() throws IOException {
- return status;
- }
- @Override
- public int getRawStatusCode() throws IOException {
- return status.value();
- }
- @Override
- public String getStatusText() throws IOException {
- return status.getReasonPhrase();
- }
- @Override
- public void close() {
- }
- @Override
- public InputStream getBody() throws IOException {
- return new ByteArrayInputStream("服务不可用,请稍后再试。Service is not available, please try again later.".getBytes());
- }
- @Override
- public HttpHeaders getHeaders() {
- //headers设定
- HttpHeaders headers = new HttpHeaders();
- MediaType mediaType = new MediaType("application", "json", Charset.forName("UTF-8"));
- headers.setContentType(mediaType);
- return headers;
- }
- };
- }
- }
五、管理端点
当 @EnableZuulProxy 和 Spring Boot Actuator配合使用时,Zuul 会暴露两个端点:/actuator/routes, /actuator/filters 。借助这两个端点,我们可以方便地、直观地查看级管理 Zuul。 通常,我们直接访问是会报 404,如下配置可以解决 在 application.yml 添加- # 开启权限访问端点,如 /actuator/routes, /actuator/filters
- management:
- endpoints:
- web:
- exposure:
- include: '*'
- 路由端点
- 过滤器路由路径
- 微信
- 交流学习,有偿服务
- 博客/Java交流群
- 资源分享,问题解决,技术交流。群号:590480292
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏