Spring Cloud与Docker微服务架构实战简单学习笔记(三)

Spring Cloud与Docker微服务架构实战简单学习笔记(三)

1. 服务消费者整合Feign

1.1 引入依赖包

SpringCloud2.0以后引入以下包:

		<!-- 添加Feign依赖 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
			<version>2.1.1.RELEASE</version>
		</dependency>

1.2 新建FeignClient接口

@FeignClient(name = "microservice-simple-provider-user")
public interface UserFeignClient {
	
	@GetMapping(value="/user/{id}")
	public UserEntity findByIdFeign(@PathVariable("id") int id);
}

1.3 修改controller,使用Feign调用

	@Autowired
	private UserFeignClient userFeignClient;
	
	@GetMapping("/user/feign/{id}")
	public UserEntity findByIdFeign(@PathVariable int id) {
		return userFeignClient.findByIdFeign(id);
	}

1.4 启动类加注解

在启动类上加@EnableFeignClients注解,开启Feign Client功能。
在这里插入图片描述

2. Hystrix实现容错(断路器)

断路器可理解为对容易导致错误的操作的代理。
这种代理能够统计一段时间内调用失败的次数,并决定是正常请求依赖的服务还是直接放回。

断路器可以实现快速失败,如果它在一段时间内检测到许多类似的错误(例如超时),就会在之后的一段时间内,强迫对该服务的调用快速失败,即不再请求所依赖的服务。

断路器也可以自动诊断依赖的服务是否已经恢复正常。

断路器状态转换图

在这里插入图片描述

2.1 Hystrix简介

Hystrix是一个实现了超时机制和断路器模式的工具类库。
在这里插入图片描述
在这里插入图片描述

3 如何整合Hystrix

3.1 添加依赖包

		<!-- 添加Hystrix依赖 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
			<version>2.1.1.RELEASE</version>
		</dependency>

3.2 启动类加注解

	@EnableHystrix

3.3 修改Controller

让方法“findByIdFeign”具备容错能力,并为它添加一个回退方法“findByIdFeignFallback”,这两个方法具有相同的参数和返回值。

	@HystrixCommand(fallbackMethod = "findByIdFeignFallback")
	@GetMapping("/user/feign/{id}")
	public UserEntity findByIdFeign(@PathVariable int id) {
		return userFeignClient.findByIdFeign(id);
	}
	
	public UserEntity findByIdFeignFallback(int id) {
		UserEntity user = new UserEntity();
		user.setId(-1l);
		user.setAge(20);
		user.setUsername("account-1");
		user.setName("默认用户");
		user.setBalance(new BigDecimal(9999));
		return user;
	}

3.4 验证

先正常启动user1、user2,访问“http://localhost:8032/movie/user/feign/2”可正常返回id=2的用户信息。
停掉user1或user2,再访问,可以看到能获取到“默认用户”的信息。

4. Hystrix线程隔离策略与传播上下文

Hystrix隔离策略有两种:
1.线程隔离(THREAD):使用该方式,HystrixCommand将会在单独的线程上执行,并发请求受线程池中的线程数量限制。
2.信号量隔离(SEMAPHORE):使用该方式,HystrixCommand将会在调用线程上执行,开销相对较小,并发请求受到信号量个数的限制。

Hystrix中默认并且推荐使用线程隔离,因为这种方式,除了网络超时以外,还有一个额外的保护层。

一般来说,只有当调用负载非常高时,(例如每个实例每秒调用数百次)才需要使用信号量隔离,因为这种场景下使用thread开销会比较高。 信号量隔离一般仅适用于非网络调用的隔离。

可以使用“execution.isolation.strategy”属性指定隔离策略:

	@HystrixCommand(fallbackMethod = "findByIdFeignFallback",
					commandProperties = {
							@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
					})
	public UserEntity findByIdFeign(@PathVariable int id) {
		return userFeignClient.findByIdFeign(id);
	}

在这里插入图片描述

5. Feign整合Hystrix

前面是使用注解@HystrixCommand的fallbackMethod属性实现回退的。然而,Feign是以接口形式工作的,它没有方法体,前面讲解的方式显然不适用于Feign。

事实上,Feign已默认整合了Hystrix,只要Hystrix在项目的classPath中,Feign默认就会用断路器包裹所有方法。

5.1 FeignClient上添加fallback属性

注意:fallback上配的是class

@FeignClient(name = "microservice-simple-provider-user", fallback = UserFeignClientFallback.class)
public interface UserFeignClient {
	
	@GetMapping(value="/user/{id}")
	public UserEntity findByIdFeign(@PathVariable("id") int id);
}

5.2 新建FeignClient的实现类

@Component
public class UserFeignClientFallback implements UserFeignClient {

	@Override
	public UserEntity findByIdFeign(int id) {
		UserEntity user = new UserEntity();
		user.setId(-1l);
		user.setAge(20);
		user.setUsername("account-1");
		user.setName("默认用户(feign接口注解)");
		user.setBalance(new BigDecimal(9999));
		return user;
	}

}

5.3 为Feign开启Hystrix

默认情况下,feign是不启动hystrix功能,需要我们启动此功能,通过以下配置:

feign.hystrix.enabled=true

如果没有开启,则会报错:
This application has no explicit mapping for /error, so you are seeing this as a fallback.

整合完成,可以测试验证。

.

6. 通过Fallback Factory检查回退原因

很多场景下,需要了解回退的原因,可使用注解@FeignClient的fallbackFactory属性。

6.1 FeignClient上添加fallbackFactory属性

@FeignClient(name = "microservice-simple-provider-user", fallbackFactory = UserFeignClientFallbackFactory.class)
public interface UserFeignClient {
	
	@GetMapping(value="/user/{id}")
	public UserEntity findByIdFeign(@PathVariable("id") int id);
}

6.2 新建FallbackFactory的实现类

@Component
public class UserFeignClientFallbackFactory implements FallbackFactory<UserFeignClient>{
	
	private static final Logger log = LoggerFactory.getLogger(UserFeignClientFallbackFactory.class);

	@Override
	public UserFeignClient create(Throwable cause) {
		
		return new UserFeignClient() {
			
			@Override
			public UserEntity findByIdFeign(int id) {
				// 日志最好放在各个fallback方法中,不要直接放在create方法中
				// 否则在引用启动时,就会打印该日志
				
				UserFeignClientFallbackFactory.log.error("=========== fallback reason is :", cause);

				UserEntity user = new UserEntity();
				user.setId(-1l);
				user.setAge(20);
				user.setUsername("account-1");
				user.setName("默认用户(打印fallback原因)");
				user.setBalance(new BigDecimal(9999));
				
				return user;
			}
		};
		
	}

}

6.3 注意的问题

fallback属性 和 fallbackFactory不要同时存在(虽然不报错),同时存在的话fallbackFactory不生效,不会打印日志。

7. Hystrix的监控

除了实现容错外,Hystrix还提供了近乎实时的监控。
HystrixCommand和HystrixObservableCommand在执行时,会生成执行结果和运行指标,比如:每秒执行的请求数、成功数等。

使用Hystrix的模块“hystrix-metrics-event-stream”,就可将这些监控的指标信息以“text/event-stream”的格式暴露给外部系统。

spring-cloud-starter-hystrix已包含该模块,在此基础上,只需要添加“spring-boot-starter-actuator”,就可以使用“/hystrix.stream”端点获取Hystrix的监控信息了。

7.1 添加依赖包

		<!-- 添加Actuator监控依赖 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>

7.2 启动类加方法

低版本的直接访问:http://localhost:8032/hystrix.stream
高版本的在启动类中添加下列方法,再访问:http://localhost:8032/hystrix.stream,即可。

	/**
	 * 低版本直接启动即可使用 http://ip:port/hystrix.stream 查看监控信息 
	 * 高版本需要添加本方法方可使用 http://ip:port/hystix.stream 查看监控信息
	 * 
	 * @return
	 */
	@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;
	}

7.3 Feign项目的Hystrix监控(还未测试成功)

添加依赖:

		<!-- 添加Hystrix依赖 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
			<version>2.1.1.RELEASE</version>
		</dependency>

启动类加注解“@EnableCircuitBreaker”:

@EnableCircuitBreaker

8. 使用Hystrix Dashboard可视化监控数据

要保证http://localhost:8032/hystrix.stream可用,Hystrix Dashboard只是把它可视化。

8.1 添加依赖包spring-cloud-starter-netflix-hystrix-dashboard


		<!-- 添加Hystrix可视化监控依赖 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
			<version>2.1.2.RELEASE</version>
		</dependency>

8.2 启动类添加注解@EnableHystrixDashboard

@EnableHystrixDashboard

8.3 测试,看效果

访问http://localhost:8032/hystrix,进入Hystrix Dashboard主页:
在这里插入图片描述

红框处填值,title可以随便写,然后点击按钮“Monitor Stream”:
在这里插入图片描述

8.4 Hystrix Dashboard指标解释

在这里插入图片描述

在这里插入图片描述

8.5 Hystrix Dashboard如何注册到Eureka Server上,有什么好处(待补)

9. 使用Turbine聚合监控数据

前文使用“/hystrix.stream”端点监控单个微服务实例。
Turbine是一个聚合Hystrix监控数据的工具,他可将所有相关/hystrix.stream端点的数据聚合到一个组合的/turbine.stream中,从而让集群的监控更加方便。

引入Turbine后,架构图如下:
在这里插入图片描述

9.1 新建一个项目“microservice-simple-turbine”专门做聚合监控

依赖包:
		<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>
			<version>2.1.0.RELEASE</version>
		</dependency>

		<!-- 添加turbine依赖 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
			<version>2.1.2.RELEASE</version>
		</dependency>
配置项: 注意看配置项的描述
server.port=2031

spring.application.name=microservice-simple-turbine

eureka.client.serviceUrl.defaultZone=http://hht:123456@localhost:8761/eureka/,http://hht:123456@localhost:8762/eureka/
eureka.client.instance.prefer-ip-address=true

#指定要监控的微服务名称,用逗号分隔
turbine.app-config=microservice-simple-consumer-movie,microservice-simple-consumer-books
#指定集群名称 
turbine.cluster-name-expression="default"
#表示同一主机上的服务通过host和port的组合来进行区分,默认情况下是使用host来区分,这样会使本地调试有问题
turbine.combine-host-port=true
#springboot2.0,默认路径不是/hystrix.stream,而turbine默认路径是这个,所以要修改一下
turbine.instanceUrlSuffix=/hystrix.stream
启动类: 加注解 @EnableTurbine
@EnableTurbine
@SpringBootApplication
public class TurbineApplication 
{
    public static void main( String[] args )
    {
        SpringApplication.run(TurbineApplication.class, args);
    }
    
}
测试:http://localhost:2031/turbine.stream

在这里插入图片描述

9.2 用Hystrix Dashboard让监控数据可视化

上文中在microservice-simple-consumer-movie中整合了Dashboard,其实没必要这么做(movie、books里可以删除)。
不用再每个微服务里整合Hystrix Dashboard,只需要新建一个项目整合就可以了,或者和turbine做在一起。

本列就是做在turbine里。

添加依赖包:spring-cloud-starter-netflix-hystrix-dashboard

		<!-- 添加Hystrix Dashboard仪表盘监控依赖 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
			<version>2.1.2.RELEASE</version>
		</dependency>
启动类加注解: @EnableHystrixDashboard
@EnableTurbine
@EnableHystrixDashboard
@SpringBootApplication
public class TurbineApplication 
{
    public static void main( String[] args )
    {
        SpringApplication.run(TurbineApplication.class, args);
    }
    
}
测试: http://localhost:2031/hystrix

在打开的页面中输入: http://localhost:2031/turbine.stream, 可以看到2个监控信息。
在这里插入图片描述

10. 使用消息中间件RabbitMQ收集数据(待补)

一些场景下,前文的方式无法正常工作(例如微服务和Turbine网络不通),此时,可借助消息中间件实现数据收集。

各个微服务将Hystrix Command的监控数据发送至消息中间件,Turbine消费消息中间件中的数据。

本例,新建2个工程来演示:
microservice-simple-consumer-food
microservice-simple-turbine-RabbitMQ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值