Hystrix 支付微服务构建
新建 cloud-provider-hystrix-payment8001
1.pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>msclound</artifactId><groupId>com.atguigu.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-provider-hystrix-payment8001</artifactId><dependencies><!--hystrix--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency><!--eureka client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><groupId>com.atguigu.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</version></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><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties></project>
2.application.yml
server:port: 8003spring:application:name: cloud-provider-hystrix-paymenteureka:client:register-with-eureka: truefetch-registry: trueservice-url:#defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eurekadefaultZone: http://eureka7001.com:7001/eureka
3.主启动类
package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@EnableEurekaClient@SpringBootApplicationpublic class PaymentHystrixMain8001 {public static void main(String[] args) {SpringApplication.run(PaymentHystrixMain8001.class,args);}}
4.业务类
(1)PaymentService
package com.atguigu.springcloud.service;import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;@Servicepublic class PaymentService {/*** 正常访问,一切 OK* @param id* @return*/public String paymentInfo_OK(Integer id){return "线程池:"+Thread.currentThread().getName()+"paymentInfo_OK,id:"+id+"\t"+":-)";}/*** 超时访问,演示降级* @param id* @return*/public String paymentInfo_TimeOut(Integer id){try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}return "线程池:"+Thread.currentThread().getName()+"paymentInfo_TimeOut,id:"+id+"\t"+":-(,耗费 3 秒";}}
(2)PaymentController
package com.atguigu.springcloud.controller;import com.atguigu.springcloud.service.PaymentService;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@Slf4j@RestControllerpublic class PaymentController {@Resourceprivate PaymentService paymentService;@Value("${server.port}")private String serverPort;@GetMapping("/payment/hystrix/ok/{id}")public String paymentInfo_OK(@PathVariable("id") Integer id){String result = paymentService.paymentInfo_OK(id);log.info("*******result:"+result);return result;}@GetMapping("/payment/hystrix/timeout/{id}")public String paymentInfo_TimeOut(@PathVariable("id") Integer id){String result = paymentService.paymentInfo_TimeOut(id);log.info("*******result:"+result);return result;}}
测试
● 启动 cloud-eureka-server7001
● 启动 cloud-provider-hystrix-payment8001
浏览器访问:http://localhost:8003/payment/hystrix/ok/31
返回结果:
线程池:http-nio-8003-exec-1paymentInfo_OK,id:31 :-)
浏览器访问:http://localhost:8003/payment/hystrix/timeout/31
返回结果:
线程池:http-nio-8003-exec-3paymentInfo_TimeOut,id:31 :-(,耗费 3 秒
以上述为根基平台,从正确->错误->降级熔断->恢复
JMeter 高并发压测后卡顿
上述在非高并发情形下,还能勉强满足
下面使用 Jmeter 压测测试
开启 Jmeter,来 20000 个并发压死 8001,20000 个请求都去访问 paymentInfo_TimeOut 服务
1.测试计划中右键添加 - 线程 - 线程组(线程组 payment2020,线程数:200,线程数:100,其他参数默认)
2.刚刚新建线程组 payment2020,右键它 - 添加 - 取样器 - Http请求 - 路径,输入 http://localhost:8003/payment/hystrix/timeout/31
3.点击绿色三角形图标启动。
启动后,可以看到后端控制台开始疯狂打印日志
*******result:线程池:http-nio-8003-exec-33paymentInfo_TimeOut,id:31 :-(,耗费 3 秒*******result:线程池:http-nio-8003-exec-99paymentInfo_TimeOut,id:31 :-(,耗费 3 秒*******result:线程池:http-nio-8003-exec-83paymentInfo_TimeOut,id:31 :-(,耗费 3 秒*******result:线程池:http-nio-8003-exec-35paymentInfo_TimeOut,id:31 :-(,耗费 3 秒*******result:线程池:http-nio-8003-exec-81paymentInfo_TimeOut,id:31 :-(,耗费 3 秒
这个时候,浏览器输入 http://localhost:8003/payment/hystrix/ok/31
本来秒出的结果也需要几秒才出来
原因:tomcat 的默认的工作线程数被打满了,没有多余的线程来分解压力和处理。
Jmeter 压测结论
上面还是服务提供者 8001 自己测试,假如此时外部的消费者 80 也来访问,那消费者只能干等,最终导致消费端 80 不满意,服务端 8001 直接被拖慢。