diff --git a/labx-23/labx-23-scn-hystrix-dashboard-turbine/pom.xml b/labx-23/labx-23-scn-hystrix-dashboard-turbine/pom.xml new file mode 100644 index 00000000..15e4f806 --- /dev/null +++ b/labx-23/labx-23-scn-hystrix-dashboard-turbine/pom.xml @@ -0,0 +1,74 @@ + + + + labx-23 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-23-scn-hystrix-dashboard-turbine + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-netflix-hystrix + + + + org.springframework.cloud + spring-cloud-starter-netflix-hystrix-dashboard + + + + org.springframework.cloud + spring-cloud-starter-netflix-turbine + + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + + diff --git a/labx-23/labx-23-scn-hystrix-dashboard-turbine/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/HystrixDashboardApplication.java b/labx-23/labx-23-scn-hystrix-dashboard-turbine/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/HystrixDashboardApplication.java new file mode 100644 index 00000000..e2a4e01b --- /dev/null +++ b/labx-23/labx-23-scn-hystrix-dashboard-turbine/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/HystrixDashboardApplication.java @@ -0,0 +1,17 @@ +package cn.iocoder.springcloud.labx23.hystrixdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; +import org.springframework.cloud.netflix.turbine.EnableTurbine; + +@SpringBootApplication +@EnableHystrixDashboard +@EnableTurbine +public class HystrixDashboardApplication { + + public static void main(String[] args) { + SpringApplication.run(HystrixDashboardApplication.class, args); + } + +} diff --git a/labx-23/labx-23-scn-hystrix-dashboard-turbine/src/main/resources/application.yml b/labx-23/labx-23-scn-hystrix-dashboard-turbine/src/main/resources/application.yml new file mode 100644 index 00000000..f235f2ac --- /dev/null +++ b/labx-23/labx-23-scn-hystrix-dashboard-turbine/src/main/resources/application.yml @@ -0,0 +1,16 @@ +server: + port: 9090 + +spring: + application: + name: hystrix-dashboard + +eureka: + client: + service-url: + defaultZone: http://127.0.0.1:8761/eureka/ # Eureka-Server 地址 + +turbine: + app-config: hystrix-demo + combine-host-port: true + cluster-name-expression: new String('default') diff --git a/labx-23/labx-23-scn-hystrix-demo01-cluster/pom.xml b/labx-23/labx-23-scn-hystrix-demo01-cluster/pom.xml new file mode 100644 index 00000000..f2b08653 --- /dev/null +++ b/labx-23/labx-23-scn-hystrix-demo01-cluster/pom.xml @@ -0,0 +1,70 @@ + + + + labx-23 + cn.iocoder.springboot.labs + 1.0-SNAPSHOT + + 4.0.0 + + labx-23-scn-hystrix-demo01-cluster + + + 1.8 + 1.8 + 2.2.4.RELEASE + Hoxton.SR1 + + + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + pom + import + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.cloud + spring-cloud-starter-netflix-hystrix + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + + diff --git a/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/DemoApplication.java b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/DemoApplication.java new file mode 100644 index 00000000..5620feaa --- /dev/null +++ b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/DemoApplication.java @@ -0,0 +1,22 @@ +package cn.iocoder.springcloud.labx23.hystrixdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; +import org.springframework.context.annotation.Bean; +import org.springframework.web.client.RestTemplate; + +@SpringBootApplication +@EnableCircuitBreaker // 声明开启断路器 +public class DemoApplication { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } + +} diff --git a/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/controller/CacheDemoController.java b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/controller/CacheDemoController.java new file mode 100644 index 00000000..8af86c48 --- /dev/null +++ b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/controller/CacheDemoController.java @@ -0,0 +1,33 @@ +package cn.iocoder.springcloud.labx23.hystrixdemo.controller; + +import cn.iocoder.springcloud.labx23.hystrixdemo.service.CacheDemoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/cache-demo") +public class CacheDemoController { + + @Autowired + private CacheDemoService cacheDemoService; + + @GetMapping("/get_user") + public String getUser(@RequestParam("id") Integer id) { + String userA = cacheDemoService.getUser(id); + String userB = cacheDemoService.getUser(id); + String userC = cacheDemoService.getUser(id); + return userC; + } + + @GetMapping("/update_user") + public String updateUser(@RequestParam("id") Integer id) { + String userA = cacheDemoService.getUser(id); + cacheDemoService.updateUser(id); + String userC = cacheDemoService.getUser(id); + return userC; + } + +} diff --git a/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/controller/CollapserDemoController.java b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/controller/CollapserDemoController.java new file mode 100644 index 00000000..df3bac8a --- /dev/null +++ b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/controller/CollapserDemoController.java @@ -0,0 +1,46 @@ +package cn.iocoder.springcloud.labx23.hystrixdemo.controller; + +import cn.iocoder.springcloud.labx23.hystrixdemo.service.CollapserDemoService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +@RestController +@RequestMapping("/collapser-demo") +public class CollapserDemoController { + + private Logger logger = LoggerFactory.getLogger(CollapserDemoController.class); + + @Autowired + private CollapserDemoService collapserDemoService; + + @GetMapping("/test") + public void test() throws ExecutionException, InterruptedException { + logger.info("[test][准备获取用户信息]"); + Future user01 = collapserDemoService.getUserFuture(1); + Future user02 = collapserDemoService.getUserFuture(2); + logger.info("[test][提交获取用户信息]"); + + logger.info("[test][user({}) 的结果为({})]", 1, user01.get()); + logger.info("[test][user({}) 的结果为({})]", 2, user02.get()); + } + + + @GetMapping("/test_02") + public void test02() throws ExecutionException, InterruptedException { + logger.info("[test][准备获取用户信息]"); + Future user01 = collapserDemoService.getUserFuture(2); + Future user02 = collapserDemoService.getUserFuture(1); + logger.info("[test][提交获取用户信息]"); + + logger.info("[test][user({}) 的结果为({})]", 1, user01.get()); + logger.info("[test][user({}) 的结果为({})]", 2, user02.get()); + } + +} diff --git a/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/controller/DemoController.java b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/controller/DemoController.java new file mode 100644 index 00000000..47db0bf2 --- /dev/null +++ b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/controller/DemoController.java @@ -0,0 +1,35 @@ +package cn.iocoder.springcloud.labx23.hystrixdemo.controller; + +import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; +import org.apache.commons.lang.exception.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@RestController +@RequestMapping("/demo") +public class DemoController { + + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private RestTemplate restTemplate; + + @GetMapping("/get_user") + @HystrixCommand(fallbackMethod = "getUserFallback") + public String getUser(@RequestParam("id") Integer id) { + logger.info("[getUser][准备调用 user-service 获取用户({})详情]", id); + return restTemplate.getForEntity("http://127.0.0.1:18080/user/get?id=" + id, String.class).getBody(); + } + + public String getUserFallback(Integer id, Throwable throwable) { + logger.info("[getUserFallback][id({}) exception({})]", id, ExceptionUtils.getRootCauseMessage(throwable)); + return "mock:User:" + id; + } + +} diff --git a/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/filter/HystrixRequestContextFilter.java b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/filter/HystrixRequestContextFilter.java new file mode 100644 index 00000000..99b73260 --- /dev/null +++ b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/filter/HystrixRequestContextFilter.java @@ -0,0 +1,28 @@ +package cn.iocoder.springcloud.labx23.hystrixdemo.filter; + +import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext; +import org.springframework.stereotype.Component; + +import javax.servlet.*; +import javax.servlet.annotation.WebFilter; +import java.io.IOException; + +@Component +@WebFilter(urlPatterns = "/") +public class HystrixRequestContextFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + // 初始化 HystrixRequestContext + HystrixRequestContext context = HystrixRequestContext.initializeContext(); + // 继续过滤器 + try { + chain.doFilter(request, response); + } finally { + // 销毁 HystrixRequestContext + context.close(); + } + } + +} diff --git a/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/service/CacheDemoService.java b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/service/CacheDemoService.java new file mode 100644 index 00000000..0241062d --- /dev/null +++ b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/service/CacheDemoService.java @@ -0,0 +1,43 @@ +package cn.iocoder.springcloud.labx23.hystrixdemo.service; + +import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; +import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheRemove; +import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult; +import org.apache.commons.lang.exception.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +@Service +public class CacheDemoService { + + private Logger logger = LoggerFactory.getLogger(CacheDemoService.class); + + @Autowired + private RestTemplate restTemplate; + + @HystrixCommand(fallbackMethod = "getUserFallback") + @CacheResult(cacheKeyMethod = "genGetUserCacheKey") + public String getUser(Integer id) { + logger.info("[getUser][准备调用 user-service 获取用户({})详情]", id); + return restTemplate.getForEntity("http://127.0.0.1:18080/user/get?id=" + id, String.class).getBody(); + } + + @HystrixCommand + @CacheRemove(commandKey = "getUser", cacheKeyMethod = "genGetUserCacheKey") + public void updateUser(Integer id) { + logger.info("[updateUser][更新用户({})详情]", id); + } + + public String getUserFallback(Integer id, Throwable throwable) { + logger.info("[getUserFallback][id({}) exception({})]", id, ExceptionUtils.getRootCauseMessage(throwable)); + return "mock:User:" + id; + } + + public String genGetUserCacheKey(Integer id) { + return "USER_" + id; + } + +} diff --git a/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/service/CollapserDemoService.java b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/service/CollapserDemoService.java new file mode 100644 index 00000000..4006bd49 --- /dev/null +++ b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/java/cn/iocoder/springcloud/labx23/hystrixdemo/service/CollapserDemoService.java @@ -0,0 +1,44 @@ +package cn.iocoder.springcloud.labx23.hystrixdemo.service; + +import com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser; +import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; +import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Future; + +@Service +public class CollapserDemoService { + + private Logger logger = LoggerFactory.getLogger(CollapserDemoService.class); + + @Autowired + private RestTemplate restTemplate; + + @HystrixCollapser( + batchMethod = "getUsers", + collapserProperties = { + @HystrixProperty(name = "timerDelayInMilliseconds", value = "10000") // 演示,所以设置的时间较长 + } + ) + public Future getUserFuture(Integer id) { + throw new RuntimeException("This method body should not be executed"); + } + + @HystrixCommand + public List getUsers(List ids) { + logger.info("[getUsers][准备调用 user-service 获取多个用户({})详情]", ids); + String[] users = restTemplate.getForEntity("http://127.0.0.1:18080/user/batch_get?ids=" + StringUtils.join(ids, ',') + , String[].class).getBody(); + return users == null || users.length == 0 ? Collections.emptyList() : Arrays.asList(users); + } + +} diff --git a/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/resources/application.yml b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/resources/application.yml new file mode 100644 index 00000000..f63f8bf1 --- /dev/null +++ b/labx-23/labx-23-scn-hystrix-demo01-cluster/src/main/resources/application.yml @@ -0,0 +1,14 @@ +management: + endpoints: + web: + exposure: + include: 'hystrix.stream' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。 + +spring: + application: + name: hystrix-demo # 应用名 + +eureka: + client: + service-url: + defaultZone: http://127.0.0.1:8761/eureka/ # Eureka-Server 地址 diff --git a/labx-23/pom.xml b/labx-23/pom.xml index 1a613762..e92a0edb 100644 --- a/labx-23/pom.xml +++ b/labx-23/pom.xml @@ -12,11 +12,15 @@ labx-23 pom - labx-23-scn-hystrix-demo01 labx-23-user-service + labx-23-scn-hystrix-demo01 + labx-23-scn-hystrix-actuator labx-23-scn-hystrix-dashboard + + labx-23-scn-hystrix-demo01-cluster + labx-23-scn-hystrix-dashboard-turbine diff --git a/pom.xml b/pom.xml index e22d68f1..b0837dbd 100644 --- a/pom.xml +++ b/pom.xml @@ -90,9 +90,7 @@ - - - + labx-22 labx-23