基于springcloud异步线程池、高并发请求feign的解决方案
ScenTaskTestApplication.java
packagecom.test; importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; importorg.springframework.cloud.openfeign.EnableFeignClients; /** *@authorscen *@version2018年9月27日上午11:51:04 */ @EnableFeignClients @SpringBootApplication publicclassScenTaskTestApplication{ publicstaticvoidmain(String[]args){ SpringApplication.run(ScenTaskTestApplication.class,args); } }
application.properties
spring.application.name=scen-task-test server.port=9009 feign.hystrix.enabled=true #熔断器失败的个数==进入熔断器的请求达到1000时服务降级(之后的请求直接进入熔断器) hystrix.command.default.circuitBreaker.requestVolumeThreshold=1000 #回退最大线程数 hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests=50 #核心线程池数量 hystrix.threadpool.default.coreSize=130 #请求处理的超时时间 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=100000 ribbon.ReadTimeout=120000 #请求连接的超时时间 ribbon.ConnectTimeout=130000 eureka.instance.instance-id=${spring.application.name}:${spring.application.instance_id:${server.port}} eureka.instance.preferIpAddress=true eureka.client.service-url.defaultZone=http://127.0.0.1:9000/eureka logging.level.com.test.user.service=debug logging.level.org.springframework.boot=debug logging.level.custom=info
AsyncConfig.java
packagecom.test; importorg.springframework.context.annotation.Configuration; importorg.springframework.scheduling.annotation.AsyncConfigurer; importorg.springframework.scheduling.annotation.EnableAsync; importorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; importjava.util.concurrent.Executor; /** *springboot异步线程池配置 *@authorScen *@date2018/11/718:28 */ @Configuration @EnableAsync publicclassAsyncConfigimplementsAsyncConfigurer{ @Override publicExecutorgetAsyncExecutor(){ //定义线程池 ThreadPoolTaskExecutortaskExecutor=newThreadPoolTaskExecutor(); //核心线程数 taskExecutor.setCorePoolSize(20); //线程池最大线程数 taskExecutor.setMaxPoolSize(100); //线程队列最大线程数 taskExecutor.setQueueCapacity(10); //初始化 taskExecutor.initialize(); returntaskExecutor; } }
DoTaskClass.java
packagecom.test; importcom.test.pojo.User; importcom.test.pojo.UserEducation; importcom.test.user.service.UserService; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.scheduling.annotation.Async; importorg.springframework.stereotype.Component; importjava.util.List; /** *任务类定义异步工作任务 *@authorScen *@date2018/11/718:40 */ @Component publicclassDoTaskClass{ /** *一个feign的客户端 */ privatefinalUserServiceuserService; @Autowired publicDoTaskClass(UserServiceuserService){ this.userService=userService; } /** *核心任务 * *@paramuid */ @Async publicvoiddotask(Stringuid){ /** *模拟复杂工作业务(109个线程同时通过feign请求微服务提供者) */ { ListuserEducationByUid=userService.findUserEducationByUid(uid); List blackList=userService.getBlackList(); StringuserSkilled=userService.getUserSkilled(uid); StringuserFollow=userService.getUserFollow(uid); UseruserById=userService.getUserById(uid); List followList=userService.getFollowList(uid); intuserActivityScore=userService.getUserActivityScore(uid); } //打印线程名称分辨是否为多线程操作 System.out.println(Thread.currentThread().getName()+"===任务"+uid+"执行完成==="); } }
TestController.java
packagecom.test; importcom.test.pojo.User; importcom.test.user.service.UserService; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.RestController; importjava.util.List; /** *测试案例 *@authorScen *@date2018/11/718:10 */ @RestController publicclassTestController{ /** *此处仅用此feign客户端请求微服务获取核心工作所需参数 */ privatefinalUserServiceuserService; /** *核心工作异步算法 */ privatefinalDoTaskClassdoTaskClass; @Autowired publicTestController(DoTaskClassdoTaskClass,UserServiceuserService){ this.doTaskClass=doTaskClass; this.userService=userService; } /** *手动触发工作 *@throwsInterruptedException */ @RequestMapping("/test") publicvoidtask()throwsInterruptedException{ /* 取到1000个要执行任务的必备参数 */ ListuserList=userService.findAllLite(1,1000); for(inti=0;i 相关线程池、超时时间等数量和大小按实际业务配置
补充:SpringCloud关于@FeignClient和Hystrix集成对http线程池监控问题
@FeignClient可以作为Http代理访问其他微服务节点,可以用apache的httpclient替换@FeignClient原生的URLConnection请求方式,以达到让http请求走Http线程池的目的。
而@FeignClient和hystrix集成之后,在hystrixdashboard上可以监控到@FeignClient中接口调用情况和@FeignClient中httpclient中线程池使用状况。
下面是demo的示例:
1、@FeignClient的接口代码如下:
@FeignClient(value="service-A",fallback=ServiceClientHystrix.class) publicinterfaceServiceClient{ @RequestMapping(method=RequestMethod.GET,value="/add/{id}") Stringadd(@PathVariable("id")Integerid); }2、ServiceClientHystrix.java
@Component publicclassServiceClientHystriximplementsServiceClient{ @Override publicStringadd(Integerid){ return"addvaluefromServiceClientHystrix"; } }3、关于@FeignClient和hystrix
集成后,Http线程池配置如下:
hystrix.threadpool.服务实例ID.参数
例如设置httpclient的线程池最大线程数量
hystrix.threadpool.service-A.coreSize=20//默认是hystrix.threadpool.default.coreSize=10 hystrix.threadpool.service-A.maximumSize=20//默认是hystrix.threadpool.default.maximumSize=10启动服务后用测试用例连续调用接口测试,用hystrixdashboard
监控得到下图监控效果:
去掉hystrix.threadpool.服务实例ID.参数配置后,再次用测试用例调用接口得到监控如下图:
PoolSize的大小取决于hystrix.threadpool.服务实例ID.coreSize大小设置
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。