SpringCloud 学习笔记总结
Posted IT_Holmes
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud 学习笔记总结相关的知识,希望对你有一定的参考价值。
文章目录
- 1. OpenFeign 之 介绍
- 2. OpenFeign 之 消费端的 服务调用
- 3. OpenFeign 之 超时控制
- 4. OpenFeign 之 日志增强
- 5. Hystrix 之 重要概念
- 6. jmeter 普通服务测试
- 7. Hystrix 之 服务提供 和 服务消费 环境搭建
- 8. Hystrix 之 服务降级 消费端和服务端
- 9. Hystrix 之 全局服务降级@DefaultProperties
- 10. Hystrix 之 通配服务降级
- 11. Hystrix 之 服务熔断
- 11. Hystrix 之 图形化dashboard(图形化监控)
- 12. Hystrix 之 图形化dashboard 实战演示
git代码地址:https://gitee.com/it-sherlock/java-project-template。
1. OpenFeign 之 介绍
OpenFeign官方地址:https://spring.io/projects/spring-cloud-openfeign/
OpenFeign Github官方地址:https://github.com/spring-cloud/spring-cloud-openfeign
feign英文翻译:假装,佯装。
Feign是一个声明式WebService客户端,让编写Web服务客户端变得非常容易,只需要创建一个接口并在接口上添加注解即可。
之前是通过ribbon + restTemplate方式封装处理,形成一套模板化的调用方法。
现在,feign集成了ribbon,通过feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。
现在OpenFeign已经取代了Feign:
2. OpenFeign 之 消费端的 服务调用
feign是定义在消费端的。
简单说就是,更加简便了:只需要 微服务调用接口 + @FeignClient注解,就能实现。
第一步:添加OpenFeign的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
第二步:主启动类,添加激活feign的注解@EnableFeignClients:
package com.itholmes.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients//使用feign,激活开启feign
public class OrderFeignMain80
public static void main(String[] args)
SpringApplication.run(OrderFeignMain80.class,args);
第三步:写一个service接口,配置好@FeignClient注解对应。
package com.itholmes.springcloud.service;
import com.itholmes.springcloud.entities.CommonResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService
/**
* 这时候就是去注册中心找一个CLOUD-PAYMENT-SERVICE名称的微服务加上对应地址。
*/
@GetMapping("/payment/get/id")
public CommonResult getPaymentById(@PathVariable("id") Long id);
3. OpenFeign 之 超时控制
OpenFeign默认等待1秒钟,超过后就报错read time out。
# 设置feign 客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
# 指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ReadTimeout: 5000
# 指的是进建立连接后从服务器读取到可用资源所用的时间
ConnectTimeout: 5000
4. OpenFeign 之 日志增强
Feigon 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中Http请求的细节。对Feign接口的调用情况进行监控和输出。
OpenFeign的日志级别:
配置类设置日志级别:
package com.itholmes.springcloud.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignConfig
//设置日志级别
@Bean
Logger.Level feignLoggerLevel()
return Logger.Level.FULL;
feign日志以什么级别监控那个接口:
server:
port: 80
eureka:
client:
# 表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
# 入驻地址是哪个
service-url:
#设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
#defaultZone: http://localhost:7001/eureka #单机版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版
# 设置feign 客户端超时时间(OpenFeign默认支持ribbon)
ribbon:
# 指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ReadTimeout: 5000
# 指的是进建立连接后从服务器读取到可用资源所用的时间
ConnectTimeout: 5000
logging:
level:
# feign日志以什么级别监控哪个接口
com.itholmes.springcloud.service.PaymentFeignService: debug
日志如下:
5. Hystrix 之 重要概念
分布式系统面临的问题:
- 相互之间都是微服务调用,一个过程,可能要走好多微服务系统,其中一个微服务系统出现问题,整个过程就相当于失败了。
服务雪崩:
- 多个微服务相互
依赖调用
的时候,微服务A调用微服务B,微服务B调用微服务C,微服务C有调用其他微服务,这就是扇出效果(像一把扇子,不断张开)
。 - 如果一个微服务出现了问题(超时,宕机等等),例如:微服务C宕机了,那么微服务B就会不断堆积请求(请求的线程阻塞),微服务B占用越来越多的系统资源,进而微服务B系统也崩溃了,微服务B崩溃了,同样A也会不断堆积进而崩溃掉,这就是雪崩效果。
为了解决上面的问题,就有了熔断降级
的思想。
Hystrix是一个用于处理分布式系统的延迟 和 容错的开源库。
在分布式系统里,许多依赖不可避免的会调用失败,比如:超时,异常等。
Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
断路器:(熔断保险丝)
官方地址:https://github.com/Netflix/Hystrix
服务降级:
- 就是返回一个友好提示(fallback),例如:服务器忙,请稍后再试;不让客户端等待并且立刻返回一个友好提示(fallback)。
那些情况下会触发降级:
- 程序运行异常。
- 超时。
- 服务熔断触发服务降级。
- 线程池 / 信号量 打满也会导致服务降级。
服务熔断:
- 类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示。
- 熔断过程:服务降级 -》 进而熔断 -》 恢复调用链路
服务限流:
- 像秒杀,高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行,这就是服务限流。
6. jmeter 普通服务测试
使用jmeter来测试。
在线程组里面,设定200个线程,1秒内发送请求,循环100次。之后,再次通过浏览器访问两个接口,都有严重的卡顿。
原因就是:tomcat的默认工作线程数被打满了,没有多余的线程来分担压力和处理。
这样就是雪崩效应。
7. Hystrix 之 服务提供 和 服务消费 环境搭建
第一步:导入hystrix依赖:
<!--添加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>
<!--添加hystrix依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
第二步:搭建好SpringBoot项目。
第三步:使用openFeign,链接好消费者和提供者之间的调用。
第四步:使用Jmeter来测试,高并发的请求。
- 通过测试,不难看出,一旦高并发的请求进来,就会导致严重的卡顿。
解决思想:
如何解决上面问题:
8. Hystrix 之 服务降级 消费端和服务端
官方github文档使用方式是通过程序:
这里使用@HystrixCommand注解:
@HystrixCommand报异常后的处理过程:
- 一旦调用服务方法失败,并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法。
服务端降级代码如下:
第一步:service层逻辑代码:
package com.itholmes.springcloud.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
public class PaymentService
public String paymentInfo_OK(Integer id)
return "线程池: " + Thread.currentThread().getName() + "paymentInfo_OK,id:"+id+"\\t"+"hello,world";
//一旦调用服务方法失败,并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法。
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties =
// 超过3秒走兜底的错误方法。
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
)
public String paymentInfo_TimeOut(Integer id)
int timeNumber = 5;
//无论是异常还是其他的,都会引起指定的兜底方法执行。
//int age = 10/0;
try
TimeUnit.SECONDS.sleep(timeNumber);
catch (InterruptedException e)
e.printStackTrace();
return "线程池: " + Thread.currentThread().getName() + "paymentInfo_OK,id:"+id+"\\t"+"hello,world。"+"耗时(秒)"+timeNumber+"秒钟";
// 被上面指定兜底的方法
public String paymentInfo_TimeOutHandler(Integer id)
return "线程池: " + Thread.currentThread().getName() + "8001系统繁忙,请稍后再试,id:"+id+"\\t"+"GG.";
第二步:主启动类,添加注解@EnableCircuitBreaker。
package com.itholmes.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaClient
@EnableCircuitBreaker
public class PaymentHystrixMain8001
public static void main(String[] args)
SpringApplication.run(PaymentHystrixMain8001.class,args);
这样,当我们访问这个服务提供者就会有兜底方法来帮我们处理超时,异常等情况。
客户端服务降级代码如下:
- 一般我们在客户端进行服务降级!
第一步:因为客户端是通过openfeign来调用的,所以在feign要开启hystrix。
server:
port: 80
eureka:
client:
# 表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
# 入驻地址是哪个
service-url:
#设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7001.com:7001/eureka #单机版
# defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版
ribbon:
ReadTimeout: 5000
ConnectTimeout: 5000
# 在feign中开启hystrix
feign:
hystrix:
enabled: true
第二步:主启动类上面添加@EnableHystrix注解。
package com.itholmes.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
@EnableHystrix
public class OrderHystrixMain80
public static void main(String[] args)
SpringApplication.run(OrderHystrixMain80.class,args);
第三步:对于消费端(客户端),一般采用openfeign调用服务端,注解@HystrixCommand也配置在了controller层中。
package com.itholmes.springcloud.controller;
import com.itholmes.springcloud.service.PaymentHystrixService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class PaymentHystrixController
@Resource
private PaymentHystrixService paymentHystrixService;
/**
* 这里与服务端不同!
* 服务端在service层添加的@HystrixCommand注解。
* 在openfeign的消费端,是在controller层添加@HystrixCommand注解。
*/
@GetMapping("/consumer/payment/hystrix/timeout/id")
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod", commandProperties =
// 超过3秒走兜底的错误方法。
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")
)
public String paymentInfo_TimeOut(@PathVariable("id") Integer id)
String result = paymentHystrixService.paymentInfo_TimeOut(id);
return result;
public String paymentTimeOutFallbackMethod(@PathVariable("id")Integer id)
return "我是消费者80,对方支付系统繁忙或自身运行出错!";
9. Hystrix 之 全局服务降级@DefaultProperties
如果想要统一的有一个兜底的代码来处理,也就是全局服务降级的效果。
使用@DefaultProperties(defaultFallback = “”) 来实现。
@DefaultProperties(defaultFallback = “”) 注解的使用如下:
package com.itholmes.springcloud.controller;
import com.itholmes.springcloud.service.PaymentHystrixService;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
//指名全局
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
public class PaymentHystrixController
@Resource
private PaymentHystrixService paymentHystrixService;
@GetMapping("/consumer/payment/hystrix/id")
public String paymentInfo_OK(@PathVariable("id") Integer id)
String result = paymentHystrixService.paymentInfo_OK(id);
return result;
@GetMapping("/consumer/payment/hystrix/timeout/id")
//对于有@HystrixCommand注解指定的fallbackMethod,就走指定的服务降级兜底的方法。
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod", commandProperties =
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")
)
public String paymentInfo_TimeOut(@PathVariable("id") Integer id)
String result = paymentHystrixService.paymentInfo_TimeOut(id);
return result;
@GetMapping("/consumer/payment/hystrix/timeout2/id")
//使用全局的fallback
@HystrixCommand
public String paymentInfo_TimeOut2(@PathVariable("id") Integer id)
String result = paymentHystrixService.paymentInfo_TimeOut(id);
return result;
public String paymentTimeOutFallbackMethod(@PathVariable("id")Integer id)
return "我是消费者80,对方支付系统繁忙或自身运行出错!";
//全局fallback方法
public String payment_Global_FallbackMethod()
return "Global 全局的服务降级,返回信息。系统方法请稍后重试。";
10. Hystrix 之 通配服务降级
通过@FeignClient注解里面的fallback参数来配置。
第一步:创建一个实现 当前使用OpenFeign对应的service接口
的一个实现类。
package com.itholmes.springcloud.service;
import org.springframework.stereotype.Component;
//实现了PaymentHystrixService,该类就是使用的OpenFeign远程调用。
//不要忘记装配到ioc容器中。
@Component
public class PaymentFallbackService implements PaymentHystrixService
@Override
public String paymentInfo_OK(Integer id)
return "paymentInfo_OK fallback";
@Override
public String paymentInfo_TimeOut(Integer id)
return "paymentInfo_TimeOut fallback";
第 以上是关于SpringCloud 学习笔记总结的主要内容,如果未能解决你的问题,请参考以下文章