SpringCloud的学习03

1. Hystrix DashBoard

hystrix 对请求的降级和熔断,可以产生监控信息,hystrix dashboard可以实时的进行监控,底层利用actuator来暴露hystrix错误处理的监控日志

1.1 actuator是什么

在这里插入图片描述

springboot提供的项目监控工具,们可以暴露项目中的多种监控数据

1.2 相关功能

  • 健康状态
  • sping容器中所有的对象
  • springmvc映射的所有路径
  • 环境变量

1.3 如何添加actuator

1.3.1 添加actuator依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

1.3.2 配置yml

management:
  endpoints:
    web:
      exposure:
       //暴露所有监控信息
        include: "*"

1.3.3 查看监控数据

  • http://localhost:3001/actuator
    在这里插入图片描述

1.4 Hystrix DashBoard 仪表盘

在这里插入图片描述

1.4.1 创建sp08-hystrixdashboard项目

在这里插入图片描述
在这里插入图片描述

1.4.2 配置yml

  • hystrix 仪表盘可以为完全独立项目
  • 也不需要连接eureka
# hystrix 仪表盘可以为完全独立项目
# 也不需要连接eureka
server:
  port: 4001

# hystrix dashboard
hystrix:
  dashboard:
    proxy-stream-allow-list: localhost

# 注册eureka,可以不注册

1.4.3 启动类添加@EnableHystrixDashboard注解

package cn.tedu.sp08;

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

@SpringBootApplication
@EnableHystrixDashboard
public class Sp08HystrixdashboardApplication {

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

}

1.4.4 开启监控

  • http://localhost:4001/hystrix
  • http://localhost:3001/actuator/hystrix.stream
    在这里插入图片描述
    在这里插入图片描述

1.4.5 访问网址测试

开启所有启动类
在这里插入图片描述
访问下面网址进行测试

  • http://localhost:3001/item-service/35
  • http://localhost:3001/user-service/7
  • http://localhost:3001/user-service/7/score?score=100
  • http://localhost:3001/order-service/123abc
  • http://localhost:3001/order-service/

1.4.6 图标分析

在这里插入图片描述

1.4.7 压力测试

  • hystrix 熔断
    整个链路达到一定的阈值,默认情况下,10秒内产生超过20次请求,则符合第一个条件。满足第一个条件的情况下,如果请求的错误百分比大于阈值,则会打开断路器,默认为50%。Hystrix的逻辑,先判断是否满足第一个条件,再判断第二个条件,如果两个条件都满足,则会开启断路器.断路器打开 5 秒后,会处于半开状态,会尝试转发请求,如果仍然失败,保持打开状态,如果成功,则关闭断路器
1.4.7.1 使用 apache 的并发访问测试工具 ab

http://httpd.apache.org/docs/current/platform/windows.html#down
在这里插入图片描述
在工具文件bin目录下,开启cmd,输入下面命令测试,次数根据配置自定

ab -n 20000 -c 10 http://localhost:3001/item-service/35
ab -n 20000 -c 10 http://localhost:3001/user-service/35
ab -n 20000 -c 10 http://localhost:3001/order-service/35
1.4.7.2 测试效果

在这里插入图片描述

2. feign整合ribbon/hystrix

  • 微服务应用中,ribbon 和 hystrix 总是同时出现,feign 整合了两者,并提供了声明式消费者客户端
  • feign 使用声明式客户端接口远程调用

2.1 创建sp09-feign项目

在这里插入图片描述

2.1.1 pom.xml

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.8.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>cn.tedu</groupId>
	<artifactId>sp09-feign</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>sp09-feign</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
	</properties>
	<dependencies>
		<!--actuator-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<!--web-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!--eureka-client-->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		<!--Openfeign-->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</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>
			<dependency>
				<groupId>cn.tedu</groupId>
				<artifactId>sp01-commons</artifactId>
				<version>1.0-SNAPSHOT</version>
			</dependency>
		</dependencies>
	</dependencyManagement>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

2.1.2 application.yml

spring:
  application:
    name: feign
    
server:
  port: 3001
  
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka

2.1.3 配置启动类

添加注解:

  • @EnableFeignClients
  • @EnableDiscoveryClient
package cn.tedu.com;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class Sp09FeignApplication {

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

}

2.2 实现远程调用

2.2.1 feign 声明式客户端

feign 利用了我们熟悉的 spring mvc 注解来对接口方法进行设置,降低了我们的学习成本。
通过这些设置,feign可以拼接后台服务的访问路径和提交的参数

例如:

@GetMapping("/{userId}/score") 
JsonResult addScore(@PathVariable Integer userId, @RequestParam Integer score);

当这样调用该方法:

service.addScore(7, 100);

那么 feign 会向服务器发送请求:

http://用户微服务/7/score?score=100

注意:如果 score 参数名与变量名不同,需要添加参数名设置:

@GetMapping("/{userId}/score") 
JsonResult addScore(@PathVariable Integer userId, @RequestParam("score") Integer s);

2.2.2 编辑ItemClient

package cn.tedu.com.service;

import cn.tedu.sp01.pojo.Item;
import cn.tedu.web.util.JsonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;

@FeignClient(name="item-service")
public interface ItemClient {
    //获取商品列表
    @GetMapping("/{orderId}")
    JsonResult<List<Item>> getItems(@PathVariable String orderId);

    //减少商品库存
    @PostMapping("/decreaseNumber")
    JsonResult<?> decreaseNumber(@RequestBody List<Item> items);
}

2.2.3 编辑UserClient

package cn.tedu.com.service;

import cn.tedu.sp01.pojo.User;
import cn.tedu.web.util.JsonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(name = "user-service")
public interface UserClient {

    //获取用户信息
    @GetMapping("/{userId}")
    JsonResult<User> getUser(@PathVariable Integer userId);

    // 拼接路径 /{userId}/score?score=新增积分
    @GetMapping("/{userId}/score")
    JsonResult addScore(@PathVariable Integer userId,@RequestParam Integer score);

}

2.2.4 编辑OrderClient

package cn.tedu.com.service;

import cn.tedu.sp01.pojo.Order;
import cn.tedu.web.util.JsonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "order-service")
public interface OrderClient {
    //获取订单信息
    @GetMapping("/{orderId}")
    JsonResult<Order> getOrder(@PathVariable String orderId);

    //添加订单
    @GetMapping("/")
    JsonResult addOrder();
}

2.2.5 编辑FeignController

package cn.tedu.com.controller;

import cn.tedu.com.service.ItemClient;
import cn.tedu.com.service.OrderClient;
import cn.tedu.com.service.UserClient;
import cn.tedu.sp01.pojo.Item;
import cn.tedu.sp01.pojo.Order;
import cn.tedu.sp01.pojo.User;
import cn.tedu.web.util.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
@RestController
public class FeignController {

    @Autowired
    private ItemClient itemClient;
    @Autowired
    private OrderClient orderClient;
    @Autowired
    private UserClient userClient;

    @GetMapping("/item-service/{orderId}")
    public JsonResult<List<Item>> getItems(@PathVariable String orderId){
        //通过ItemClient 声明式客户端接口,调用远程服务
        return itemClient.getItems(orderId);
    }

    @PostMapping("/item-service/decreaseNumber")
    public JsonResult<?> decreaseNumber(@RequestBody List<Item> items){
        return itemClient.decreaseNumber(items);
    }

    @GetMapping("/user-service/{userId}")
    public JsonResult<User> getUser(@PathVariable Integer userId){
        return userClient.getUser(userId);
    }

    @GetMapping("/user-service/{userId}/score")
    public JsonResult<?> addScore(Integer userId,Integer score){
        return userClient.addScore(userId, score);
    }

    @GetMapping("/order-service/{orderId}")
    public JsonResult<Order> getOrder(@PathVariable String orderId){
        return orderClient.getOrder(orderId);
    }

    @GetMapping("/order-service/")
    public JsonResult addOrder(){
        return orderClient.addOrder();
    }
}

2.2.6 测试

启动所有启动类
在这里插入图片描述
使用postman,GET发送以下格式数据:

  • http://eureka1:2001
  • http://localhost:3001/item-service/35
  • http://localhost:3001/item-service/decreaseNumber
  • http://localhost:3001/user-service/7
  • http://localhost:3001/user-service/7/score?score=100
  • http://localhost:3001/order-service/123abc
  • http://localhost:3001/order-service/

使用postman,POST发送以下格式数据:

  • [{“id”:1, “name”:“abc”, “number”:23},{“id”:2, “name”:“def”, “number”:11}]

2.3 feign实现负载均衡和重试功能

2.3.1 启用ribbon

无需额外配置,feign 默认已启用了 ribbon 负载均衡和重试机制。可以通过配置对参数进行调整

重试默认配置参数:
ConnectTimeout=1000
ReadTimeout=1000
MaxAutoRetries=0
MaxAutoRetriesNextServer=1

2.3.2 配置application.yml

  • ribbon.xxx 全局配置,对所有服务都有效
  • item-service.ribbon.xxx 对特定服务实例的配置
spring:
  application:
    name: feign
    
server:
  port: 3001
  
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
      
ribbon:
  ConnectTimeout: 1000
  ReadTimeout: 1000
  
item-service:
  ribbon:
    MaxAutoRetries: 1
    MaxAutoRetriesNextServer: 2
    ConnectTimeout: 1000
    ReadTimeout: 500

2.3.3 测试

访问测试

  • http://localhost:3001/item-service/35
    在这里插入图片描述
    在这里插入图片描述

默认1秒会快速失败,没有降级方法时,会显示白板页
在这里插入图片描述

添加配置,暂时减小降级超时时间,以便对降级进行测试

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 500

2.4 Feign实现降级

Feign默认关闭,Feign不推荐启动Hystrix

2.4.1 启动hystrix

  • 添加依赖
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
  • 配置applicaiton.yml

feign:
hystrix:
enabled: true

  • 启动类添加注解: @EnableCircuitBreaker

2.4.2 暴露hystrix监控

  • 添加actuator依赖(已添加)
  • 配置yml暴露监控端点:
management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream

2.4.3 实现降级类

2.4.3.1 远程调用接口指定降级类
2.4.3.1.1 ItemClient

在这里插入图片描述

2.4.3.1.2 UserClient

在这里插入图片描述

2.4.3.1.3 OrderClient

在这里插入图片描述

2.4.3.2 ItemClientFB
package cn.tedu.com.service;

import cn.tedu.sp01.pojo.Item;
import cn.tedu.web.util.JsonResult;
import org.springframework.stereotype.Component;

import java.util.List;
@Component
public class ItemClientFB implements ItemClient{
    @Override
    public JsonResult<List<Item>> getItems(String orderId) {
        return JsonResult.err("无法获取订单商品列表");
    }

    @Override
    public JsonResult<?> decreaseNumber(List<Item> items) {
        return JsonResult.err("无法修改商品库存");
    }
}
2.4.3.3 UserClientFB
package cn.tedu.com.service;

import cn.tedu.sp01.pojo.User;
import cn.tedu.web.util.JsonResult;
import org.springframework.stereotype.Component;

@Component
public class UserClientFB implements UserClient{

    @Override
    public JsonResult<User> getUser(Integer userId) {
        return JsonResult.err("无法获取用户信息");
    }

    @Override
    public JsonResult addScore(Integer userId, Integer score) {
        return JsonResult.err("无法增加用户积分");
    }
}
2.4.3.4 OrderClientFB
package cn.tedu.com.service;

import cn.tedu.sp01.pojo.Order;
import cn.tedu.web.util.JsonResult;
import org.springframework.stereotype.Component;

@Component
public class OrderClientFB implements OrderClient{
    @Override
    public JsonResult<Order> getOrder(String orderId) {
        return JsonResult.err("无法获取订单信息");
    }

    @Override
    public JsonResult addOrder() {
        return JsonResult.err("无法添加订单信息");
    }
}

2.4.4 测试

在这里插入图片描述

2.5 监控和熔断测试

2.5.1 查看监控端点

http:localhost:3001/actuator
在这里插入图片描述

2.5.2 启动Hystrix Dashboard

在这里插入图片描述

访问 http://localhost:4001/hystrix

  • 填入 feign 监控路径:
    http://localhost:3001/actuator/hystrix.stream
  • 访问微服务,以产生监控数据
    http://localhost:3001/item-service/35
    http://localhost:3001/user-service/7
    http://localhost:3001/user-service/7/score?score=100
    http://localhost:3001/order-service/123abc
    http://localhost:3001/order-service/

2.5.3 使用ab工具测试熔断

ab -n 20000 -c 10 http://localhost:3001/item-service/35

断路器状态为 Open,所有请求会被短路,直接降级执行 fallback 方法
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Solider

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值