代码gitee分享
1.Eureka
pmo文件依赖包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
1.1什么是服务治理
1.2什么是服务注册
- 架构图
1.3 Eureka两组件
1.4 构建单机euk服务注册
说明
我们构建3个模块模拟场景
80端口模拟消费者调用
8001端口模拟生产者生产
7001做euerka做服务注册
现在需要80端口跨模块调用8001端口的内容
1.4.1 构建7001EUK服务模块
添加主类启动
@EnableEurekaServer//启动eureak注册中心
server:
port: 7001
eureka:
server:
# enable-self-preservation: false #关闭自我保护机制及时清理不可以用的服务机器
instance:
hostname: localhost
client:
register-with-eureka: false #表识不向注册中心注册自己
fetch-registry: false
service-url:
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ 单机版指向自己
defaultZone: http://www.fupengdeng.top:7002/eureka/ #设置与eureka集群版本 指向对方地址
1.4.2 配置8001
视图层业务
server:
port: 8001
spring:
application:
name: cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
mybatis:
mapper-locations: classpath*:mapper/*.xml
# type-aliases-package: com.eiletxie.springcloud.entities #配置生成后xml文件中是属性路径前置都为这个
eureka:
client:
register-with-eureka: true #表示 是否将自己注册进 EukService 默认为true
fetchRegistry: true # 表示是否从EukService抓取自己的注册信息。默认为true,单节点无所谓,集群要设置为true
service-url:
defaultZone: http://localhost:7001/eureka,http://www.fupengdeng.top:7002/eureka #入驻主机地址 集群版本把所有的入驻地址都设置进去
instance:
instance-id: payment8001
prefer-ip-address: true #点击eureka管理页面 的服务别名跳转可以显示ip地址
开启euk服务
1.4.3 配置80端口
引用resttemplate
通过resttemplate跨模块调用,单机版的我们要修改一下地址
在启动类开启Euk服务
1.4.4 测试
8001访问本机业务
80访问8001业务
这样就实现跨模块调用视图层业务
1.5 eureka高可用(euk集群)
参考8001搭建8002
server:
port: 8002
spring:
application:
name: cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
mybatis:
mapper-locations: classpath*:mapper/*.xml
# type-aliases-package: com.eiletxie.springcloud.entities #配置生成后xml文件中是属性路径前置都为这个
eureka:
client:
register-with-eureka: true #表示 是否将自己注册进 EukService 默认为true
fetchRegistry: true # 表示是否从EukService抓取自己的注册信息。默认为true,单节点无所谓,集群要设置为true
service-url:
defaultZone: http://localhost:7001/eureka,http://www.fupengdeng.top:7002/eureka #入驻主机地址 集群版本把所有的入驻地址都设置进去
instance:
instance-id: payment8002
参考7001搭建7002服务
修改配置文件这台机器我部署在我的域名上(我解析到localhost了)
集群的设置要将defaultZone指向其他机器来实现高可用
- 修改80
为了80访问可以进行转发默认是轮训的方式
设置eku的集群服务地址
因为我们是集群所以在设置服务地址的时候要设置多个服务地址,我们用对外的服务名称映射地址
这样的集群我们就搭建完成了
测试
我们不断刷新他会进行轮训访问服务器我们的8001和8002交替显示
1.6 配置解释
instance: instance-id: payment8001 prefer-ip-address: true #点击eureka管理页面 的服务别名跳转可以显示ip地址
设置之后
如果不设置prefer-ip-address: true 点击服务的id不会进行ip跳转类似如下跳转到euk的服务地址而不是服务器真实的服务地址
1.7 发现服务
我们可以在8001服务端口获取到我们注册到euk服务器的服务器信息
1.8 euk的保护机制
eureka.server.enable-self-preservation = true(默认)
类似于你租房子延期交房租 房东不会赶你走如果关闭了立马赶你走,在我们的euk里面就是如果服务超时了或者挂机了立马下线未保护的服务
在7001测试
先后启动7001 8001 8002
下线8002
2.zookeeper
zookeeper是一个分布式协调工具,可以实现注册中心功能
因为Eureka已经停止更新服务,我们需要寻求其他的服务来帮我我们完成业务需求,虽然停更但是任然可用。
2.1 准备
在linux下安装zookeeper服务
2.2 部署8004消费者到zookeeper
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
主类开启zookeeper服务
视图层业务
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/payment/zk")
public String paymentzk(){
return "springcloud with zookeeper:"+serverPort+"\t"+ UUID.randomUUID().toString();
}
}
2.3 部署zookeeper80端口
引入依赖
配置信息
server:
port: 80
spring:
application:
name: cloud-consumer-order
cloud:
zookeeper:
connect-string: 192.168.1.111:2181
配置RestTemplate
@Configuration
public class ApplicationContextConfig {
@LoadBalanced
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
视图层业务
@RestController
@Slf4j
public class OrderZKController {
public static final String INVOME_URL = "http://cloud-provider-payment";
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/zk")
public String payment (){
String result = restTemplate.getForObject(INVOME_URL+"/payment/zk",String.class);
return result;
}
}
2.4测试
开启我们虚拟机的zookeeper
启动8004 80端口服务
可用获取到服务注册的名称
可用获取我们系统生成服务的uuid
根据uuid可用获取更多的服务信息
3.Consul服务注册与发现
官网地址
Downloads | Consul by HashiCorp
官网安装指南和api文档
Spring Cloud Consul 中文文档 参考手册 中文版
我用window版做演示
双击开启服务
consul agent -dev 运行
通过以下地址可以访问Consul的首页:http;//localhost:8500
3.1引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
3.2 使用consul服务注册
场景和上面相似 80端口作为消费端 800x端口作为生产端
3.2.1 创建cloud-consul-payment8006
- 配置文件
server:
port: 8006
spring:
application:
name: consul-provider-payment
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
我们的consul在本机开启运行的默认端口就是8500
- 主类入口
@EnableDiscoveryClient
@SpringBootApplication
public class PaymentMain8006 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8006.class);
}
}
- 视图层逻辑
@Slf4j
@RestController
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/payment/consul")
public String paymentConsul(){
return "springcloud with consul: "+serverPort+"\t"+ UUID.randomUUID().toString();
}
}
3.2.2 创建cloud-consumerconsul-order80
配置文件
server:
port: 80
spring:
application:
name: consul-consumer-order
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
主类入口
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class OrderConsulMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderConsulMain80.class,args);
}
}
配置RestTemplate
@Configuration
public class ApplicationContextConfig {
@LoadBalanced
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
视图层
@RestController
@Slf4j
public class OrderConsulController {
public static final String INVOME_URL = "http://consul-provider-payment"; //配置服务名称
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/consul")
public String payment (){
String result = restTemplate.getForObject(INVOME_URL+"/payment/consul",String.class);
return result;
}
}
我们这里也是使用对外暴露的服务名称做转发
我们先后运行8006 80端口
刷新 localhost;8500页面
我们可以看到2个已经注册的服务表示注册成功
3.3 Euk、zookeeper和consul总结
3.3.1 cap架构
3.3.2 异同点
- eureka的ap架构
- zookeeper和consul的cp架构
4.Ribbon负载均衡服务调用
4.1 介绍
Spring Cloud Ribbon是基于NetflixRibbon实现的一套客户端 负载均衡的工具。
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡街算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balance er(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ri obon实现自定义的负载均衡算法。
LB负载均衡
简单的说就是将用户的请求分摊到多个服务器上,从而达到高可用(HA)常见的高可用负载均衡器软件有nginx,lvs f5.
- 集中式LB
在服务器的消费方和提供方之间使用第三方的Lb设施,由第三方的设施负载将消费方的请求通过某种策略将请求分发到提供方的服务器。
- 进程内LB
将lb逻辑集成到消费方,消费方冲服务注册中心获取那些地址可用,让后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于进程内LB。
- 架构图
Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例
- 依赖说明
我们在引入下发的时候是包含了ribbon的依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
4.2代码演示
getForObject方法/getForEntity方法
postForObject/postForEntity
前面讲的80模块进行演示,在之前已经初步演示了
测试
4.3 IRule:根据特定算法从服务列表中选取一个要访问的服务
- com.netflix.loadbalancer.RoundRobinRule(轮训)
- com.netflix.loadbalancer.RandomRule(随机)
- com.netflix.loadbalancer.RetryRule(先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试)
- WeightedResponseTimeRule (对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择)
- BestAvailableRule (会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务)
- AvailabilityFilteringRule(先过滤掉故障实例,再选择并发较小的实例)
- ZoneAvoidanceRule(默认规则,复合判断server所在区域的性能和server的可用性选择服务器)
修改cloud-consumer-order80
配置注意以下
所以在没有特别声明的情况下不能和@SpringBootApplication的启动类在同一个包因为@SpringBootApplication包含了@ComponentScan的注解
如果我们在启动类特别标注了
@ComponentScan("com.dfp")
则不能在com.dfp的包下
- 新建包com.dfp.myrule
- 新建配置类(不创建默认轮训)
@Configuration
public class MySelfRule {
@Bean
public IRule myRule(){
return new RandomRule();//定义为随机
}
// @Bean
// public IRule myRule(){
// return new RetryRule();//先按照RoundRobinRule的策略获取服务
// }
}
主类添加ribbion注解
选择我们的服务名和规则类
4.4 手写轮训负载均衡代码
springcloud的负载均衡轮训算法原理
在8001 8002端口的controller层添加如下 显示效果
在80端口添加接口获取服务实例信息
/**
* 获取服务实例
*/
public interface LoadBalancer {
ServiceInstance instances(List<ServiceInstance> serviceInstances);
}
在80端口创建轮训算法实体实现上述接口
@Component
public class MyLB implements LoadBalancer{
//
private AtomicInteger atomicInteger=new AtomicInteger(0);
//坐标
private final Integer getAndIncrement(){
Integer current = null;//当前的访问次数
Integer next=null;//下一次访问次数
do {
current=this.atomicInteger.get();
//整型越界重新从0开始
next=current>=2147483647?0:current+1;
}while (!this.atomicInteger.compareAndSet(current,next));
return next;
}
@Override
public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
//得到机器的列表
Integer index=getAndIncrement()%serviceInstances.size();//得到服务器的下标位置
return serviceInstances.get(index);
}
}
在80端口调用
@GetMapping(value = "/consumer/payment/lb")
public String getPaymentLB(){
//获取当前服务的实例
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
if (instances == null || instances.size() <= 0){
//判断是否有效实例
return null;
}
//调用自己写的轮训算法
ServiceInstance serviceInstance = loadBalancer.instances(instances);
URI uri = serviceInstance.getUri();
return restTemplate.getForObject(uri+"/payment/lb",String.class);
}
注释掉负载均衡注解
测试
可以实现轮训
5.OpenFeign服务接口调用
5.1 简介
- Feign和OpenFeign两者区别
5.2新建cloud-consumer-feign-order80
根据我们之前讲的8001 8002 7001 7002的案例修改80端口做演示
- 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 配置信息
server:
port: 80
spring:
application:
name:
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://localhost:7001/eureka,http://www.fupengdeng.top:7002/eureka #如果是集群指向多个地址
#设置feign客户端超时时间openfeign默认支持ribbon
ribbon:
#建立连接超时时间
ReadTimeout: 5000
#建立连接后读取资源超时时间
ConnectTimeout: 5000
设置超时时间避免 时间差问题报错
- 启动类
注意在需要调用其他模块的 本模块的启动类上要添加EnableFeignClients注解
- 调用对外模块接口
接口的方法要和被调用模块的视图层方法一致不用写实体类。我们要显示的指明调用服务的服务名称。
- 视图层业务
先后启动7001 7002 8001 8002 80 端口 测试
并且帮我妈实现负载均衡的轮训效果
5.3 日志监控
日志级别
- 设置日志配置类
package com.dfp.cloud.feign.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import feign.Logger;
@Configuration
public class FeignLogConfig {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
- 修改配置文件
重启80服务访问业务地址多次访问
控制台打印
6.Hystrix断路器
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
6.1 介绍
- 分布式系统面对的问题
复杂的分布式系统多个应用程序依赖关系繁杂,如果有一个依赖服务请求失败,或者过度的占用资源可能导致整个服务系统崩溃,或者说逐步崩溃,我们俗称服务雪崩。
- Hystrix作用
6.3Hystrix的三大理念
服务降级:服务器忙,请稍候再试,不让客户端等待并立刻返回一个友好提示
(触发情况通常有 程序异常、超时、服务熔断、线程池满)
服务熔断;达到最大服务访问后,直接拒绝访问,然后调用服务降级的方法并返回友好提示
服务限流:秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行
6.4 案例演示
场景说明
新建cloud-provider-hystrix-payment8001 模块
继续使用Eureka做服务调用和注册
新建如下方法
@Service
public class PaymentService {
public String pay_ok(Integer id){
return "线程池:"+Thread.currentThread().getName()
+"this id:"+id+"\t正常程序";
}
public String pay_timeOut(Integer id) {
Integer time=3;
try{
TimeUnit.SECONDS.sleep(time);
}catch (Exception e){
e.printStackTrace();
}
return "线程池:"+Thread.currentThread().getName()
+"this id:"+id+"\t异常程序延迟"+time;
}
}
第一个方法是正常
第二个方法沉睡3s缓慢执行
controller调用
@RestController
@Slf4j
public class PaymentController {
@Autowired
private PaymentService paymentService;
@Value("${server.port}")
private String serverPort;
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id){
String result = paymentService.pay_ok(id);
log.info("*******result:"+result);
return result;
}
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id) throws InterruptedException {
String result = paymentService.pay_timeOut(id);
log.info("*******result:"+result);
return result;
}
}
启动类client注解
在配置文件中配置端口等信息 并且注入到eureka服务中心
server:
port: 8001
eureka:
client:
register-with-eureka: true #表识不向注册中心注册自己
fetch-registry: true #表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务
service-url:
# defaultZone: http://eureka7002.com:7002/eureka/ #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://localhost:7001/eureka/
# server:
# enable-self-preservation: false
spring:
application:
name: cloud-provider-hystrix-payment
# eviction-interval-timer-in-ms: 2000
新建cloud/cloud-consumer-feign-hystrix-order80
主类开启feign
配置client调用
视图层调用
@RestController
@Slf4j
public class OrderHyController {
@Autowired
private PaymentClien paymentClien;
@GetMapping("/con/payment/hystrix/ok/{id}")
public String paymentInfo_OK(@PathVariable("id") Integer id){
return paymentClien.paymentInfo_OK(id);
}
@GetMapping("/con/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
return paymentClien.paymentInfo_TimeOut(id);
}
}
测试先后启动 7001 7002 8001 80端口
测试
我们从80端口调用延迟方法和从8001调用延迟方法都会非常缓慢如果这个时候高并发的用户一下进行访问我们的服务器可能面临崩溃的风险。
总结:正因为有上述故障或不佳表现,才有我们的降级/容错/限流等技术诞生
6.5 Hystrix解决方案
- 8001端口自己的服务降级
在启动类添加注解@EnableCircuitBreaker开启服务降级处理
我们在上面的案例讲解中延迟3s进行缓慢处理,我们在这里演示的延迟5秒做访问超时异常
fallbackMethod:出现异常降级处理的方法
我们设置timeoutInxxx就是设置访问的时间在 3s内属于正常时间 超过3s就属于异常需要服务降级处理
更多的参数配置信息参考官网解释
Hystrix/hystrix-contrib/hystrix-javanica at master · Netflix/Hystrix · GitHub
测试
我们多次重启服务器测试超时异常,和程序异常
如果没有设置服务降级直接报错
- 80端口设置服务降级
在配置文件添加
因为我们是在feign调用其他服务使得服务降级所以要在feign开启这个功能
feign:
hystrix:
enabled: true #如果处理自身的容错就开启。开启方式与生产端不一样。
主类添加@EnableHystrix
视图层修改
@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500") //3秒钟以内就是正常的业务逻辑
})
@GetMapping("/con/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id){
return paymentClien.paymentInfo_TimeOut(id);
}
private String paymentTimeOutFallbackMethod( Integer id){
return "消费者80,对付支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,(┬_┬)";
}
测试
这样就可以实现高可用,不管是服务器 80还是服务器8001出问题都可以进行服务降级
6.6 服务降级全局配置
按照上述的方式我们会发现一个方法对应一个服务降级的回调接口会显得系统代码非常的复杂。我们是否有办法进行代码重用呢,对于同一种类型的服务异常是否可以进行统一的处理呢。
这个时候就引入了全局配置的概念。对于优先级较低的较为简单的异常我们可以做统一处理,对于优先级高的做单独处理
- 改造8001端口
@DefaultProperties在类头上添加注解什么全局开启
同样的我们得在需要服务降级的方法上添加@HystrixCommand注解声明开启服务降级
这样就简化了我们的代码了
测试
效果表明特殊设置的服务降级根据方法头上的注解进行配置
如果没有特殊设置的根据类上的注解进行配置
- 改造80端口
回到我的80端口进行分析
这样看起来会不会觉得代码有些不友好业务逻辑和视图层逻辑交叉了
我们也可以通过全局定义的思想解决这个问题降低代码的耦合。
实现我们的降级回调处理方法实现我们对外调用的接口
在接口上显示的什么服务降级回调处理的类
在我们的业务层依然声明了hystrix
测试
我们发现执行的是实现类的方法而不是视图层的服务降级方法,意味着实现类优先级更高
而且(实现80端口也就是调用其他服务的本地服务)进行降级回调有个好处
因为常见的异常方式有 异常、超时、挂机。实现程序高可用。即使8001挂机80端口也可以自己继续进行服务降级。
6.7 服务熔断
- 简介
修改cloud-provider-hystrix-payment8001
在service添加
触发熔断之后会进行服务降级调用服务降级的回调方法
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
@HystrixProperty(name="circuitBreaker.enabled",value = "true"),//是否开启熔断器
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "10"),//请求次数
@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "10000"),//时间范围
@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "60"),//设置失误率 达到之后进行跳闸
})
public String paymentCircuitBreaker(Integer id){
if (id < 0){
throw new RuntimeException("*****id 不能负数");
}
String serialNumber = IdUtil.simpleUUID();
return Thread.currentThread().getName()+"\t"+"调用成功,流水号:"+serialNumber;
}
public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){
return "id 不能负数,请稍候再试,(┬_┬)/~~ id: " +id;
}
在controller添加
/**
* 熔断
*/
@GetMapping("/payment/circuit/{id}")
public String paymentCircuitBreaker(@PathVariable("id") Integer id){
String result = paymentService.paymentCircuitBreaker(id);
log.info("*******result:"+result);
return result;
}
我们设计的场景是 输入的数字不能为负数 ,如果多次输入负数会进行熔断处理
测试
多次输入负数
再次输入正数
但是多次正数点击后恢复正常
- 熔断总结,断路器在什么情况下开始起作用
- 熔断总结,熔断开启的顺序流程
官网解释 先检查范围数量----访问时间周期-----访问成功率-----错误之后恢复成功-----检查成功率
6.8HystrixProperty参数
参数解释
6.9服务监控hystrixDashboard 图像化web界面
新建cloud-consumer-hystrix-dashboard9001
我们使用这个来检测我们的cloud/cloud-provider-hystrix-payment8001服务
搭建9001
添加EnableHystruxDashboard
package com.dfp.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@EnableHystrixDashboard
@SpringBootApplication
public class HystrixDashboardMain9001 {
public static void main(String[] args) {
SpringApplication.run(HystrixDashboardMain9001.class);
}
}
server:
port: 9001
<dependencies>
<!--新增hystrix dashboard-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
注意不要漏了web和actuator依赖 8001端口也是需要的
在8001启动类添加
@Bean
public ServletRegistrationBean getServlet(){
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
启动9001