栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Cloud Eureka--Zuul API网关 Hystrix实践

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Cloud Eureka--Zuul API网关 Hystrix实践

统一的入口 1.新建spring模块:sp06-zuul 2.添加依赖

eureka+zuul



    4.0.0
    
        springcloud1
        cn.tedu
        1.0-SNAPSHOT
    
    
    cn.tedu
    sp06-zuul
    0.0.1-SNAPSHOT
    sp06-zuul
    Demo project for Spring Boot


    
        1.8
    

    
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            org.springframework.cloud
            spring-cloud-starter-netflix-zuul
        
        
            cn.tedu
            sp01-commons
            1.0-SNAPSHOT

        
    


    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    



3.yml配置
spring:
  application:
    name: zuul
# eureka2001 3001 3001 4001 5001 6001
server:
  port: 3001
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka,http://eureka2:2002/eureka
zuul:
  routes:
    # **包含深层子路径
    # *只包含一层路径
    # service-id 作为访问子路径,是默认设置
    # 根据注册表中的注册信息,zuul可以自动配置,防止注册表不全
    # 最好自己手动配置
    item-service: /item-service/**
    user-service: /user-service/**
    order-service: /order-service/**
4.启动类注解

@EnableZuulProxy

package cn.tedu.sp06;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableZuulProxy
public class Sp06ZuulApplication {

    public static void main(String[] args) {
        SpringApplication.run(Sp06ZuulApplication.class, args);
    }
}

5. rest.http测试
### 获取订单的商品列表
GET http://localhost:8001/ty4g33t3

### 减少商品库存
POST http://localhost:8001/decreaseNumber
Accept: application/json
Content-Type: application/json

[{"id":1, "name":"abc", "number":23},{"id":2, "name":"def", "number":11}]

### 获取用户
GET http://localhost:8101/7
###
GET http://localhost:8101/8
###
GET http://localhost:8101/9
###
GET http://localhost:8101/10
### 增加积分
GET http://localhost:8101/8/score?score=1000

### 获取订单
GET http://localhost:8201/iujhygf435tg
### 添加订单
GET http://localhost:8201/add


# ---------------------------------------------------------------------------------


### 获取订单的商品列表
GET http://localhost:3001/item-service/ty4g33t3

### 减少商品库存
POST http://localhost:3001/item-service/decreaseNumber
Accept: application/json
Content-Type: application/json

[{"id":1, "name":"abc", "number":23},{"id":2, "name":"def", "number":11}]

### 获取用户
GET http://localhost:3001/user-service/7
###
GET http://localhost:3001/user-service/8
###
GET http://localhost:3001/user-service/9
###
GET http://localhost:3001/user-service/10
### 增加积分
GET http://localhost:3001/user-service/8/score?score=1000

### 获取订单
GET http://localhost:3001/order-service/iujhygf435tg
### 添加订单
GET http://localhost:3001/order-service/add

统一权限校验
  • zuul的过滤器XZuulProxy,可以过滤客户端请求,在过滤器中可以检查访问权限
    前置、路由、后置、错误过滤器
    测试:http://localhost:3001/item-service/jsihfhj 没有登录不允许访问
    http://localhost:3001/item-service/jsihfhj?token=ndhfjdhsjfdjs bfjhdskj 有令牌,则一登陆允许访问 (真正项目token应放在协议头,很测试没有登录系统)
1.新建过滤器类
  • AccessFilter 按照Zull的规则实现 继承ZuulFilter
2.重写ZuulFilter接口的四个抽象方法
  • 设置过滤器的类型
  • 设置过滤器添加的顺序号
  • 针对当前请求判断是否要执行下面的过滤代码
  • 过滤代码
  • @Component 自动扫描自动创建实例
    实现代码
package cn.tedu.sp06.filter;

import cn.tedu.web.util.JsonResult;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
public class AccessFilter extends ZuulFilter {
    
    @Override
    public String filterType() {
//        return "pre";
        return FilterConstants.PRE_TYPE;
    }

    
    @Override
    public int filterOrder() {
        return 6;
    }
    
    @Override
    public boolean shouldFilter() {
        
        //1.获得一个请求上下文对象
        RequestContext ctx=RequestContext.getCurrentContext();
        //2.从上下文对象获得调用后台服务的 serviceid  类型要转成字符串类型
        String serviceId = (String)ctx.get(FilterConstants.SERVICE_ID_KEY);//"serviceId"
        //3.如果调用了item-service 返回true
        return "item-service".equals(serviceId);
    }
    
    @Override
    public Object run() throws ZuulException {
        //1.获得上下文对象
        RequestContext ctx=RequestContext.getCurrentContext();
        //2.获得Request对象
        HttpServletRequest request = ctx.getRequest();
        //3.接收token参数
        String token = request.getParameter("token");
        //4.如果token不存在: ①null ②"" ③"   "
        if(StringUtils.isBlank(token)){ //区别idEmpty()
            //5.阻止继续调用
            ctx.setSendZuulResponse(false);//发送zuul响应关闭
            //6.直接返回响应 提示未登录
            //JsonResult--{code:400,msg:未登录,data:null}
            String json=JsonResult.build().code(400).msg("not log in").toString();
            //响应协议头
            ctx.addZuulResponseHeader("Content-Type", "application/json;charset=UTF-8");
            //响应协议体
            ctx.setResponseBody(json);
        }
        return null;//zuul当前版本这个返回值不起任何作用
    }
}


设置过滤器的类型

实现效果

  • 为什么顺序号为6???
  • 前置过滤器中有五个默认过滤器PreDecorationFilter 自定义过滤器放在末尾 位置为6
    在第五个过滤器放入了serviceid
Zuul集成Ribbon
  • 负载均衡默认启用
  • 重试默认禁用
  • 在最前面重试会造成后台服务器大面积出现故障
    也可以启用重试,一般不会启用
    设置:
  • 添加spring-retry依赖
 
       org.springframework.retry
       spring-retry

  • yml配置启用重试
spring:
  application:
    name: zuul
# eureka2001 3001 3001 4001 5001 6001
server:
  port: 3001
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka,http://eureka2:2002/eureka
zuul:
  routes:
    # **包含深层子路径
    # *只包含一层路径
    # service-id 作为访问子路径,是默认设置
    # 根据注册表中的注册信息,zuul可以自动配置,防止注册表不全
    # 最好自己手动配置
    item-service: /item-service/**
    user-service: /user-service/**
    order-service: /order-service/**
  retryable: true
# 对所有服务都有效的通用配置
ribbon:
  MaxAutoRetries: 1
# 对某一个单独配置
item-service:
  ribbon:
    MaxAutoRetries: 0
Zuul集成Hystrix
  • Hystrix是容错和限流工具(与sentinel相似)
  • Hystrix容错:通过降级处理
  • Hystrix限流:熔断
1. Zuul网关使用Hystrix进行同错处理,执行降级
  • Zuul默认已经启用Hystrix,任何基础配置都不用做
  • 调用后台服务失败,执行前面模块中的降级代码,返回降级结果
    ①给出错误提示
    ②返回缓存数据
    ③根据业务逻辑返回任何结果都可以
1.新建降级类 ItemFB 实现FallbackProvider接口
package cn.tedu.sp06.fb;

import cn.tedu.web.util.JsonResult;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
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.StandardCharsets;

@Component
public class itemFB implements FallbackProvider {
    
    @Override
    public String getRoute() {
        return "item-service";
    }

    
    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.INTERNAL_SERVER_ERROR;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return HttpStatus.INTERNAL_SERVER_ERROR.value();
            }

            @Override
            public String getStatusText() throws IOException {
                return HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase();
            }

            @Override
            public void close() {
                //用来关闭流
                //BAIS不占用底层系统资源,不需要关闭

            }


            @Override
            public InputStream getBody() throws IOException {
                //JsonResult -{code msg data}
                String json = JsonResult.build().code(500).msg("后台服务出错请稍后重试").toString();

                return new ByteArrayInputStream(json.getBytes("UTF-8"));
            }
            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders h = new HttpHeaders();
                h.add("Content-Type", "application/json;charset=UTF-8");
                return h;
            }
        };
    }
}
2.新建降级类 ItemFB 实现FallbackProvider接口
package cn.tedu.sp06.fb;

import cn.tedu.web.util.JsonResult;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

@Component
public class orderFB implements FallbackProvider {
    
    @Override
    public String getRoute() {
        return "order-service";
    }

    
    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.INTERNAL_SERVER_ERROR;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return HttpStatus.INTERNAL_SERVER_ERROR.value();
            }

            @Override
            public String getStatusText() throws IOException {
                return HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase();
            }

            @Override
            public void close() {
                //用来关闭流
                //BAIS不占用底层系统资源,不需要关闭

            }


            @Override
            public InputStream getBody() throws IOException {
                //JsonResult -{code msg data}
                String json = JsonResult.build().code(500).msg("后台服务出错请稍后重试").toString();

                return new ByteArrayInputStream(json.getBytes("UTF-8"));

            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders h = new HttpHeaders();
                h.add("Content-Type", "application/json;charset=UTF-8");
                return h;
            }
        };
    }
}

实现效果

2. Zuul集成Hystrix实现限流,熔断
  • 当流量 过大,后台服务出现故障,可以断开链路,限制后台故障服务
  • 在06添加断路器,断开连接后,直接执行06的降级代码(不会进行远程调用),返回降级结果(短路请求),执行效率很高
    断路器打开条件
    ①20次/10s 请求,必须首先满足
    ②50%请求出错,执行了降级代码
    if(20){if(50%){}}
  • 断路器打开之后,会进入半开状态
    在半开状态下,会向服务器尝试发送一次客户端调用
    调用成功,自动关闭断路器恢复正常;
    调用失败,继续保持打开状态。再进入半开状态
    打开 半开 打开 半开…循环
Hystrix dashboard
  • 对降流和熔断的情况进行监控,可以通过监控快速定位故障模块
  • 调用02.03.04在06产生监控日志 使用Actuator工具
  • Actuator是spring提供的监控指标工具,可以暴露项目的各种监控指标
    ①健康状态
    ②spring容器中的所有对象
    ③spring mvc 映射的所有路径
    ④环境变量
    ⑤堆内存镜像(java虚拟机使用的堆内存)
暴露Actuator监控指标 1. Actuator依赖→06
 
      org.springframework.cloud
      >spring-cloud-starter-netflix-zuul

actuator依赖于zuul

2. 06yml配置
m.e.w.e.i="*"  # *:暴露所有监控指标
m.e.w.e.i=health,beans,mappings  # *:暴露指定监控指标
m.e.w.e.i=hystrix.stream

***********************************************************
#暴露actuator的监控指标
management:
  endpoints:
    web:
      exposure:
        include: "*"  #暴露所有监控

3.访问

http://localhost:3001/actuator

### actuator
GET http://localhost:3001/actuator
###
GET http://localhost:3001/actuator/health
###
GET http://localhost:3001/actuator/info
###
GET http://localhost:3001/actuator/beans
###
GET http://localhost:3001/actuator/mappings
###
GET http://localhost:3001/actuator/heapdump
###
GET http://localhost:3001/actuator/hystrix.stream # 监控数据路径
搭建Hystrix-dashboard(仪表盘) 1. 新建spring模块: sp07-hystrix-dashboard

2. 调整pom.xml 添加hystrix dashboard依赖


    4.0.0
    
        springcloud1
        cn.tedu
        1.0-SNAPSHOT
    
    cn.tedu
    sp07-hystrix-dashboard
    0.0.1-SNAPSHOT
    sp07-hystrix-dashboard
    Demo project for Spring Boot

    
        1.8
        UTF-8
        UTF-8

    

    
        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix-dashboard
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    
    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.8.1
                
                    1.8
                    1.8
                    UTF-8
                
            
            
                org.springframework.boot
                spring-boot-maven-plugin
                2.4.1
                
                    cn.tedu.sp07.Sp07HystrixDashboardApplication
                
                
                    
                        repackage
                        
                            repackage
                        
                    
                
            
        
    



3. 配置yml
server:
  port: 4001
#允许抓取日志的服务器列表
hystrix:
  dashboard:
    proxy-stream-allow-list: localhost

4. 启动类添加注解

@EnableHystrixDashboard

package cn.tedu.sp07;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

@SpringBootApplication
@EnableHystrixDashboard
public class Sp07HystrixDashboardApplication {

    public static void main(String[] args) {
        SpringApplication.run(Sp07HystrixDashboardApplication.class, args);
    }

}

5. 启动访问
http://localhost:4001/hystrix
http://localhost:3001/actuator/hystrix.stream

首先需要调用远端服务



6. 熔断工具ab
ab -n 20000 -c 50 http://localhost:3001/item-service/u56y4?token=u5y4f3
ab -n 20000 -c 50 http://localhost:3001/user-service/3

Apache24服务器里自带ab压力测试工具


总结

1.zuul是什么??
2.使用zuul网关的准备工作??
创建zuul工程→添加eureka+zuul依赖→配置eureka、zuul.routes→启动类上添加@EnableZuulProxy注解→测试
3.zuul的作用???
统一的入口
统一的权限校验 使用ZuulFilter类(过滤器)
集成Ribbon
集成hystrix
4.Zuul的过滤器分类??
前置、后置、路由、错误过滤器
5.如何配置ZuulFilter过滤器??
设置过滤器的类型
设置过滤器添加的顺序号
针对当前请求判断是否要执行下面的过滤代码
过滤代码
6.StringUtils.isBlank()与isEmpty()区别??
isBlank():字符串为null “” “ ” 返回true
isEmpty():字符串为 null “” 返回true
7.设置过滤器添加的顺序号为6???
前置过滤器中有五个默认过滤器PreDecorationFilter 自定义过滤器放在末尾 位置为6
在第五个过滤器放入了serviceid
8.Ribbon作用??
负载均衡+重试
9.zuul集成ribbon默认开启吗??
是默认关闭的 可以手动开启(在yml文件中配置)
10.hystrix作用???
Hystrix是容错和限流工具(与sentinel相似)
Hystrix容错:通过降级处理
Hystrix限流:熔断
11.Zuul默认开启hystrix,那么如何进行容错处理??降级 具体步骤??
首先创建FallbackProvider接口的实现类
调用后台服务失败,执行前面模块中的降级代码,返回降级结果
设置针对哪个后台服务进行降级
设置向客户端返回的响应数据
12.Zuul集成hystrix如何实现限流??
断路器
断路器开启的条件??
①20次/10s 请求,必须首先满足
②50%请求出错,执行了降级代码
13.Actuator是什么??
Actuator是spring提供的监控指标工具,可以暴露项目的各种监控指标
①健康状态
②spring容器中的所有对象
③spring mvc 映射的所有路径
④环境变量
⑤堆内存镜像(java虚拟机使用的堆内存)
14.Hystrix 的dashboard作用???
对降流和熔断的情况进行监控,可以通过监控快速定位故障模块

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/530786.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号