乐趣区

关于intellij-idea:SpringClub05feign-声明式客户端

一、feign 申明式客户端接口

微服务利用中,ribbon 和 hystrix 总是同时呈现,feign 整合了两者,并提供了 申明式消费者 客户端

  • 用 feign 代替 hystrix+ribbon

1. 新建 sp09-feign 我的项目

2. 增加依赖

<?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.2.1.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.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <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.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-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>

3. 批改 application.yml 文建

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

4. 主程序增加 @EnableFeignClients注解

package cn.tedu.sp09;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class Sp09FeignApplication {public static void main(String[] args) {SpringApplication.run(Sp09FeignApplication.class, args);
    }
}

5. 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);

5.1 ItemFeignService

package cn.tedu.sp09.service;
import java.util.List;
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 cn.tedu.sp01.pojo.Item;
import cn.tedu.web.util.JsonResult;
@FeignClient("item-service")
public interface ItemFeignService {@GetMapping("/{orderId}")
    JsonResult<List<Item>> getItems(@PathVariable String orderId);
    @PostMapping("/decreaseNumber")
    JsonResult decreaseNumber(@RequestBody List<Item> items);
}

5.2 UserFeignService

  • 留神, 如果申请参数名与办法参数名不同,@RequestParam不能省略, 并且要指定申请参数名:
    @RequestParam("score") Integer s
package cn.tedu.sp09.service;
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;
import cn.tedu.sp01.pojo.User;
import cn.tedu.web.util.JsonResult;
@FeignClient("user-service")
public interface UserFeignService {@GetMapping("/{userId}")
    JsonResult<User> getUser(@PathVariable Integer userId);
    // 拼接门路 /{userId}/score?score= 新增积分
    @GetMapping("/{userId}/score") 
    JsonResult addScore(@PathVariable Integer userId, @RequestParam Integer score);

5.3 OrderFeignService

package cn.tedu.sp09.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import cn.tedu.sp01.pojo.Order;
import cn.tedu.web.util.JsonResult;
@FeignClient("order-service")
public interface OrderFeignService {@GetMapping("/{orderId}")
    JsonResult<Order> getOrder(@PathVariable String orderId);
    @GetMapping("/")
    JsonResult addOrder();}

5.4 FeignController

package cn.tedu.sp09.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.web.bind.annotation.RestController;
import cn.tedu.sp01.pojo.Item;
import cn.tedu.sp01.pojo.Order;
import cn.tedu.sp01.pojo.User;
import cn.tedu.sp09.service.ItemFeignService;
import cn.tedu.sp09.service.OrderFeignService;
import cn.tedu.sp09.service.UserFeignService;
import cn.tedu.web.util.JsonResult;
@RestController
public class FeignController {
    @Autowired
    private ItemFeignService itemService;
    @Autowired
    private UserFeignService userService;
    @Autowired
    private OrderFeignService orderService;
    @GetMapping("/item-service/{orderId}")
    public JsonResult<List<Item>> getItems(@PathVariable String orderId) {return itemService.getItems(orderId);
    }
    @PostMapping("/item-service/decreaseNumber")
    public JsonResult decreaseNumber(@RequestBody List<Item> items) {return itemService.decreaseNumber(items);
    }
    @GetMapping("/user-service/{userId}")
    public JsonResult<User> getUser(@PathVariable Integer userId) {return userService.getUser(userId);
    }
    @GetMapping("/user-service/{userId}/score") 
    public JsonResult addScore(@PathVariable Integer userId, Integer score) {return userService.addScore(userId, score);
    }
    @GetMapping("/order-service/{orderId}")
    public JsonResult<Order> getOrder(@PathVariable String orderId) {return orderService.getOrder(orderId);
    }
    @GetMapping("/order-service")
    public JsonResult addOrder() {return orderService.addOrder();
    }
}

6. 启动服务,并拜访测试

  • http://eureka1:2001
  • http://localhost:3001/item-service/35
  • http://localhost:3001/item-service/decreaseNumber
    应用 postman,POST 发送以下格局数据:
    [{"id":1, "name":"abc", "number":23},{"id":2, "name":"def", "number":11}]
  • 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/

二、feign + ribbon 负载平衡和重试

  • 无需额定配置,feign 默认已启用了 ribbon 负载平衡和重试机制。能够通过配置对参数进行调整

重试的默认配置参数:

ConnectTimeout=1000
ReadTimeout=1000
MaxAutoRetries=0
MaxAutoRetriesNextServer=1

1.application.yml 配置 ribbon 超时和重试

  • 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. 启动服务,拜访测试

http://localhost:3001/item-service/35

三、feign + hystrix 降级

feign 默认没有启用 hystrix,增加配置,启用 hystrix

1. application.yml 增加配置

feign:
  hystrix:
    enabled: true

启用 hystrix 后,拜访服务
http://localhost:3001/item-service/35
默认 1 秒会疾速失败,没有降级办法时,会显示白板页

1.1 能够增加配置,临时减小降级超时工夫,以便后续对降级进行测试

feign:
  hystrix:
    enabled: true
    
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 500

2. 指定降级类

近程调用失败, 会执行降级类中的代码

2.1 ItemFeignService

@FeignClient(name="item-service", fallback = ItemFeignServiceFB.class)
public interface ItemFeignService {

2.2 UserFeignService

@FeignClient(name="user-service", fallback = UserFeignServiceFB.class)
public interface UserFeignService {

2.3 OrderFeignService

@FeignClient(name="order-service",fallback = OrderFeignServiceFB.class)
public interface OrderFeignService {

2.4 降级类

降级类须要实现近程接口

2.4.1 ItemFeignServiceFB

package cn.tedu.sp09.service;
import java.util.List;
import org.springframework.stereotype.Component;
import cn.tedu.sp01.pojo.Item;
import cn.tedu.web.util.JsonResult;
@Component
public class ItemFeignServiceFB implements ItemFeignService {
    @Override
    public JsonResult<List<Item>> getItems(String orderId) {return JsonResult.err("无奈获取订单商品列表");
    }
    @Override
    public JsonResult decreaseNumber(List<Item> items) {return JsonResult.err("无奈批改商品库存");
    }
}

2.4.2UserFeignServiceFB

package cn.tedu.sp09.service;
import org.springframework.stereotype.Component;
import cn.tedu.sp01.pojo.User;
import cn.tedu.web.util.JsonResult;
@Component
public class UserFeignServiceFB implements UserFeignService {
    @Override
    public JsonResult<User> getUser(Integer userId) {return JsonResult.err("无奈获取用户信息");
    }
    @Override
    public JsonResult addScore(Integer userId, Integer score) {return JsonResult.err("无奈减少用户积分");
    }

}

2.4.3 OrderFeignServiceFB

package cn.tedu.sp09.service;
import org.springframework.stereotype.Component;
import cn.tedu.sp01.pojo.Order;
import cn.tedu.web.util.JsonResult;
@Component
public class OrderFeignServiceFB implements OrderFeignService {
    @Override
    public JsonResult<Order> getOrder(String orderId) {return JsonResult.err("无奈获取商品订单");
    }
    @Override
    public JsonResult addOrder() {return JsonResult.err("无奈保留订单");
    }
}

3. 启动服务,拜访测试

http://localhost:3001/item-service/35

四、feign + hystrix 监控和熔断测试

1.pom.xml 增加 hystrix 起步依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2. 主程序增加 @EnableCircuitBreaker

package cn.tedu.sp09;
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;
@EnableCircuitBreaker
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class Sp09FeignApplication {public static void main(String[] args) {SpringApplication.run(Sp09FeignApplication.class, args);
    }
}

3. 配置 actuator 依赖

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

4. application.yml 裸露 hystrix.stream 监控端点

management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream

5. 启动服务,查看监控端点

http://localhost:3001/actuator

5.1 hystrix dashboard

启动 hystrix dashboard 服务,填入 feign 监控门路,开启监控
拜访 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/

5.2 熔断测试

  • 用 ab 工具,以并发 50 次,来发送 20000 个申请
ab -n 20000 -c 50 http://localhost:3001/item-service/35 
  • 断路器状态为 Open,所有申请会被短路,间接降级执行 fallback 办法

五、order service 调用商品库存服务和用户服务

批改 sp04-orderservice 我的项目,增加 feign,调用 item service 和 user service

1. 增加依赖

  • actuator
  • feign
  • hystrix
<?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.2.1.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>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>
                spring-cloud-starter-netflix-eureka-client
            </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>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</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.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

2. 批改 application.yml 文件

  • ribbon 重试和 hystrix 超时这里没有设置,采纳了默认值
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

3. 主程序增加 @EnableFeignClients 注解

package cn.tedu.sp04;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
//@EnableDiscoveryClient
//@SpringBootApplication
@EnableFeignClients
@SpringCloudApplication
public class Sp04OrderserviceApplication {public static void main(String[] args) {SpringApplication.run(Sp04OrderserviceApplication.class, args);
    }
}

4. 指定降级类

4.1 ItemFeignService

package cn.tedu.sp04.order.feignclient;
import java.util.List;
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 cn.tedu.sp01.pojo.Item;
import cn.tedu.web.util.JsonResult;
@FeignClient(name="item-service", fallback = ItemFeignServiceFB.class)
public interface ItemFeignService {@GetMapping("/{orderId}")
    JsonResult<List<Item>> getItems(@PathVariable String orderId);
    @PostMapping("/decreaseNumber")
    JsonResult decreaseNumber(@RequestBody List<Item> items);
}

4.2 UserFeignService

package cn.tedu.sp04.order.feignclient;
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;
import cn.tedu.sp01.pojo.User;
import cn.tedu.web.util.JsonResult;
@FeignClient(name="user-service", fallback = UserFeignServiceFB.class)
public interface UserFeignService {@GetMapping("/{userId}")
    JsonResult<User> getUser(@PathVariable Integer userId);
    @GetMapping("/{userId}/score") 
    JsonResult addScore(@PathVariable Integer userId, @RequestParam Integer score);
}

4.3ItemFeignServiceFB

  • 获取商品列表的降级办法,模仿应用缓存数据
package cn.tedu.sp04.order.feignclient;
import java.util.Arrays;
import java.util.List;
import org.springframework.stereotype.Component;
import cn.tedu.sp01.pojo.Item;
import cn.tedu.web.util.JsonResult;
@Component
public class ItemFeignServiceFB implements ItemFeignService {
    @Override
    public JsonResult<List<Item>> getItems(String orderId) {if(Math.random()<0.5) {return JsonResult.ok().data(Arrays.asList(new Item[] {new Item(1,"缓存 aaa",2),
                        new Item(2,"缓存 bbb",1),
                        new Item(3,"缓存 ccc",3),
                        new Item(4,"缓存 ddd",1),
                        new Item(5,"缓存 eee",5)
                })
            );
        }
        return JsonResult.err("无奈获取订单商品列表");
    }
    @Override
    public JsonResult decreaseNumber(List<Item> items) {return JsonResult.err("无奈批改商品库存");
    }
}

5. 降级类

5.1 UserFeignServiceFB

  • 获取用户信息的降级办法,模仿应用缓存数据
package cn.tedu.sp04.order.feignclient;
import org.springframework.stereotype.Component;
import cn.tedu.sp01.pojo.User;
import cn.tedu.web.util.JsonResult;
@Component
public class UserFeignServiceFB implements UserFeignService {
    @Override
    public JsonResult<User> getUser(Integer userId) {if(Math.random()<0.4) {return JsonResult.ok(new User(userId, "缓存 name"+userId, "缓存 pwd"+userId));
        }
        return JsonResult.err("无奈获取用户信息");
    }
    @Override
    public JsonResult addScore(Integer userId, Integer score) {return JsonResult.err("无奈减少用户积分");
    }
}

5.2 OrderServiceImpl

package cn.tedu.sp04.order.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.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.feignclient.ItemFeignService;
import cn.tedu.sp04.order.feignclient.UserFeignService;
import cn.tedu.web.util.JsonResult;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private ItemFeignService itemService;
    @Autowired
    private UserFeignService userService;
    @Override
    public Order getOrder(String orderId) {
        // 调用 user-service 获取用户信息
        JsonResult<User> user = userService.getUser(7);
        // 调用 item-service 获取商品信息
        JsonResult<List<Item>> items = itemService.getItems(orderId);
        Order order = new Order();
        order.setId(orderId);
        order.setUser(user.getData());
        order.setItems(items.getData());
        return order;
    }
    @Override
    public void addOrder(Order order) {
        // 调用 item-service 缩小商品库存
        itemService.decreaseNumber(order.getItems());
        
        //TODO: 调用 user-service 减少用户积分
        userService.addScore(7, 100);
        log.info("保留订单:"+order);
    }
}

6. order-service 配置启动参数, 启动两台服务器

  • --server.port=8201
  • --server.port=8202

7. 启动服务,拜访测试

  • 依据 orderid,获取订单
    http://localhost:8201/123abc
    http://localhost:8202/123abc
  • 保留订单
    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 来集中展现和监控

1. 新建 sp10-turbine 我的项目

2. 增加依赖

<?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.2.1.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.RELEASE</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>

3. 批改 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")` 

4. 主程序

增加 @EnableTurbine@EnableDiscoveryClient 注解

package cn.tedu.sp10;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.turbine.EnableTurbine;
@EnableTurbine
@EnableDiscoveryClient
@SpringBootApplication
public class Sp10TurbineApplication {public static void main(String[] args) {SpringApplication.run(Sp10TurbineApplication.class, args);
    }
}

5. 拜访测试

  • 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 监控信息

退出移动版