88--spring cloud (Turbine聚合监控)
目录
order-service 调用商品库存服务和用户服务
修改 sp04-orderservice 项目,添加 feign,调用 item service 和 user service
pom.xml
添加三个依赖
openFeign
hystrix
actuator
<?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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.tedu</groupId>
<artifactId>sp04-orderservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sp04-orderservice</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>
<dependency>
<groupId>cn.tedu</groupId>
<artifactId>sp01-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
application.yml
spring:
application:
name: order-service
server:
port: 8201
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
feign:
hystrix:
enabled: true
management:
endpoints:
web:
exposure:
include: hystrix.stream
主程序
添加启动的配置注解
package cn.tedu.sp04;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients //启动feign客户端
@EnableDiscoveryClient //发现注册
@EnableCircuitBreaker //使用断路器
@SpringBootApplication
public class Sp04OrderserviceApplication {
public static void main(String[] args) {
SpringApplication.run(Sp04OrderserviceApplication.class, args);
}
}
ItemFeignClient
package cn.tedu.sp04.order.feign;
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",fallback = ItemFeignClientFB.class)
public interface ItemFeignClient {
@GetMapping("/{orderId}")
JsonResult<List<Item>> getItems(@PathVariable String orderId);
@PostMapping("/decreaseNumber")
JsonResult decrease(@RequestBody List<Item> items);
}
UserFeignClient
package cn.tedu.sp04.order.feign;
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.RequestParam;
@FeignClient(name = "user-service",fallback =UserFeignClientFB.class )
public interface UserFeignClient {
@GetMapping("/{userId}")
JsonResult<User> getUser(Integer userId);
@GetMapping("/{userId}/score")
JsonResult addScore(@PathVariable Integer userId,@RequestParam Integer score);
}
ItemFeignClientFB
添加降级类,实现声明式客户端接口
package cn.tedu.sp04.order.feign;
import cn.tedu.sp01.pojo.Item;
import cn.tedu.web.util.JsonResult;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class ItemFeignClientFB implements ItemFeignClient {
@Override
public JsonResult<List<Item>> getItems(String orderId) {
//模拟返回缓存数据
if (Math.random()<0.5){
List<Item> items = new ArrayList<>();
items.add(new Item(1,"缓存1",1));
items.add(new Item(2,"缓存2",8));
items.add(new Item(3,"缓存3",5));
items.add(new Item(4,"缓存4",6));
return JsonResult.ok().data(items);
}
return JsonResult.err().msg("调用商品服务,获取订单商品列表失败");
}
@Override
public JsonResult decrease(List<Item> items) {
return JsonResult.err().msg("调用商品服务,减少库存失败");
}
}
UserFeignClientFB
添加降级类,实现声明式客户端接口
package cn.tedu.sp04.order.feign;
import cn.tedu.sp01.pojo.User;
import cn.tedu.web.util.JsonResult;
import org.springframework.stereotype.Component;
@Component
public class UserFeignClientFB implements UserFeignClient {
@Override
public JsonResult<User> getUser(Integer userId) {
//添加模拟缓存
if (Math.random()<0.5){
User user = new User(userId, "用户名" + userId, "密码" + userId);
return JsonResult.ok().data(user);
}
return JsonResult.err().msg("调用用户服务,获取用户信息失败");
}
@Override
public JsonResult addScore(Integer userId, Integer score) {
return JsonResult.err().msg("调用用户服务,新增积分失败");
}
}
OrderServiceImpl
注入声明式客户端接口,实现远程服务端调用
package cn.tedu.sp04.order.service;
import cn.tedu.sp01.pojo.Item;
import cn.tedu.sp01.pojo.Order;
import cn.tedu.sp01.pojo.User;
import cn.tedu.sp01.service.OrderService;
import cn.tedu.sp04.order.feign.ItemFeignClient;
import cn.tedu.sp04.order.feign.UserFeignClient;
import cn.tedu.web.util.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
//注入声明式客户端接口
@Autowired
private UserFeignClient userFeignClient;
@Autowired
private ItemFeignClient itemFeignClient;
@Override
public Order getOrder(String orderId) {
//TODO: 调用user-service获取用户信息
JsonResult<User> user = userFeignClient.getUser(7);
//TODO: 调用item-service获取商品信息
JsonResult<List<Item>> items = itemFeignClient.getItems(orderId);
log.info("获取订单,orderId = "+orderId);
Order order = new Order();
order.setId(orderId);
order.setUser(user.getData());
order.setItems(items.getData());
return order;
}
@Override
public void addOrder(Order order) {
//TODO : 新订单中购买的商品,减少商品库存
itemFeignClient.decrease(order.getItems());
//TODO: 增加用户的积分
userFeignClient.addScore(order.getUser().getId(),1000);
log.info("保存订单:"+order);
}
}
order-service 配置启动参数,启动两台服务器
--server.port=8201
--server.port=8202
测试
- 根据orderid,获取订单
http://localhost:8201/123
http://localhost:8202/123 - 保存订单
http://localhost:8201/
http://localhost:8202/
hystrix dashboard 监控 order service 断路器
启动
- 访问 http://localhost:4001/hystrix ,填入 order service 的断路器监控路径,启动监控
- http://localhost:8201/actuator/hystrix.stream
- http://localhost:8202/actuator/hystrix.stream
hystrix + turbine 集群聚合监控
hystrix dashboard 一次只能监控一个服务实例,使用 turbine 可以汇集监控信息
,将聚合后的信息提供给 hystrix dashboard 来集中展示和监控
创建项目
添加依赖在pom.xml
Turbine
,Eureka Discovery Client
<?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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.tedu</groupId>
<artifactId>sp10-turbine</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sp10-turbine</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</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>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
spring:
application:
name: turbin
server:
port: 5001
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka, http://eureka2:2002/eureka
turbine:
app-config: order-service
cluster-name-expression: new String("default")
主程序
添加注解@EnableTurbine
package cn.tedu.sp10;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.turbine.EnableTurbine;
@EnableTurbine
@SpringBootApplication
public class Sp10TurbineApplication {
public static void main(String[] args) {
SpringApplication.run(Sp10TurbineApplication.class, args);
}
}
测试
- 8201服务器产生监控数据:
http://localhost:8201/abc123
http://localhost:8201/ - 8202服务器产生监控数据:
http://localhost:8202/abc123
http://localhost:8202/ - turbine 监控路径
http://localhost:5001/turbine.stream - 在 hystrix dashboard 中填入turbine 监控路径,开启监控
http://localhost:4001/hystrix - turbine聚合了order-service两台服务器的hystrix监控信息