热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

基于springcloud异步线程池、高并发请求feign的解决方案

这篇文章主要介绍了基于springcloud异步线程池、高并发请求feign的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

ScenTaskTestApplication.java

package com.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author scen
* @version 2018年9月27日 上午11:51:04
*/
@EnableFeignClients
@SpringBootApplication
public class ScenTaskTestApplication {
 public static void main(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

package com.test;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
/**
 * springboot异步线程池配置
 * @author Scen
 * @date 2018/11/7 18:28
 */
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
 
 
 @Override
 public Executor getAsyncExecutor() {
  //定义线程池
  ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
  //核心线程数
  taskExecutor.setCorePoolSize(20);
  //线程池最大线程数
  taskExecutor.setMaxPoolSize(100);
  //线程队列最大线程数
  taskExecutor.setQueueCapacity(10);
  //初始化
  taskExecutor.initialize();
  return taskExecutor;
 }
}

DoTaskClass.java

package com.test;
import com.test.pojo.User;
import com.test.pojo.UserEducation;
import com.test.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * 任务类 定义异步工作任务
 * @author Scen
 * @date 2018/11/7 18:40
 */
@Component
public class DoTaskClass { 
 /**
  * 一个feign的客户端
  */
 private final UserService userService;
 
 @Autowired
 public DoTaskClass(UserService userService) {
  this.userService = userService;
 }
 
 /**
  * 核心任务
  *
  * @param uid
  */
 @Async
 public void dotask(String uid) {
  /**
   * 模拟复杂工作业务(109个线程同时通过feign请求微服务提供者)
   */
  {
   List userEducatiOnByUid= userService.findUserEducationByUid(uid);
   List blackList = userService.getBlackList();
   String userSkilled = userService.getUserSkilled(uid);
   String userFollow = userService.getUserFollow(uid);
   User userById = userService.getUserById(uid);
   List followList = userService.getFollowList(uid);
   int userActivityScore = userService.getUserActivityScore(uid);
  }
//  打印线程名称分辨是否为多线程操作
  System.out.println(Thread.currentThread().getName() + "===任务" + uid + "执行完成===");
 }
}

TestController.java

package com.test;
import com.test.pojo.User;
import com.test.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
 * 测试案例
 * @author Scen
 * @date 2018/11/7 18:10
 */
@RestController
public class TestController {
 
 /**
  * 此处仅用此feign客户端请求微服务获取核心工作所需参数
  */
 private final UserService userService;
 
 /**
  * 核心工作异步算法
  */
 private final DoTaskClass doTaskClass;
 
 @Autowired
 public TestController(DoTaskClass doTaskClass, UserService userService) {
  this.doTaskClass = doTaskClass;
  this.userService = userService;
 } 
 
 /**
  * 手动触发工作
  * @throws InterruptedException
  */
 @RequestMapping("/test")
 public void task() throws InterruptedException {
  /*
   取到1000个要执行任务的必备参数
   */
  List userList = userService.findAllLite(1, 1000);
  for (int i = 0; i 

相关线程池、超时时间等数量和大小按实际业务配置

补充:SpringCloud关于@FeignClient和Hystrix集成对http线程池监控问题

@FeignClient可以作为Http代理访问其他微服务节点,可以用apache的httpclient替换@FeignClient原生的URLConnection请求方式,以达到让http请求走Http线程池的目的。

而@FeignClient和hystrix集成之后,在hystrix dashboard上可以监控到 @FeignClient 中接口调用情况和 @FeignClient 中httpclient中线程池使用状况。

下面是demo的示例:

1、@FeignClient的接口代码如下:

@FeignClient(value="service-A", fallback=ServiceClientHystrix.class)
public interface ServiceClient { 
 @RequestMapping(method = RequestMethod.GET, value = "/add/{id}")
 String add(@PathVariable("id") Integer id);
}

2、ServiceClientHystrix.java

@Component
public class ServiceClientHystrix implements ServiceClient{
 @Override
 public String add(Integer id) {
  return "add value from ServiceClientHystrix";
 }
}

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

启动服务后用测试用例连续调用接口测试,用hystrix dashboard

监控得到下图监控效果:

去掉hystrix.threadpool.服务实例ID.参数配置后,再次用测试用例调用接口得到监控如下图:

PoolSize的大小取决于hystrix.threadpool.服务实例ID.coreSize大小设置

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。


推荐阅读
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 本文总结了一次针对大厂Java研发岗位的面试经历,探讨了面试中常见的问题及其背后的原因,并分享了一些实用的面试准备资料。 ... [详细]
  • 龙蜥社区开发者访谈:技术生涯的三次蜕变 | 第3期
    龙蜥社区的开发者们通过自己的实践和经验,推动着开源技术的发展。本期「龙蜥开发者说」聚焦于一位资深开发者的三次技术转型,分享他在龙蜥社区的成长故事。 ... [详细]
  • Go从入门到精通系列视频之go编程语言密码学哈希算法(二) ... [详细]
  • 为助力科研人员提升数据处理与图形展示能力,活动家携手北京市计算中心推出2017年R语言数据可视化研讨会。详情及注册信息请点击链接查看。 ... [详细]
  • 本文详细介绍了在 Ubuntu 16.04 系统上安装和配置 PostgreSQL 数据库的方法,包括如何设置监听地址、启用密码加密、更改默认用户密码以及调整客户端访问控制。 ... [详细]
  • 在OpenCV 3.1.0中实现SIFT与SURF特征检测
    本文介绍如何在OpenCV 3.1.0版本中通过Python 2.7环境使用SIFT和SURF算法进行图像特征点检测。由于这些高级功能在OpenCV 3.0.0及更高版本中被移至额外的contrib模块,因此需要特别处理才能正常使用。 ... [详细]
  • 张正友相机标定算法解析:无需棋盘格
    本文深入探讨了张正友教授于1998年提出的单平面标定技术,该方法结合了传统标定与自标定的优势,通过简易的棋盘格实现了高效准确的相机标定。 ... [详细]
  • 使用 MATLAB 将高光谱数据集转换为伪彩色 CIE 图像
    本文介绍了一种方法,通过 MATLAB 将高光谱数据集的每个维度的图像转换为伪彩色 CIE 图像。用户只需指定波段即可完成转换。 ... [详细]
  • 精选10款Python框架助力并行与分布式机器学习
    随着神经网络模型的不断深化和复杂化,训练这些模型变得愈发具有挑战性,不仅需要处理大量的权重,还必须克服内存限制等问题。本文将介绍10款优秀的Python框架,帮助开发者高效地实现分布式和并行化的深度学习模型训练。 ... [详细]
  • Windows操作系统提供了Encrypting File System (EFS)作为内置的数据加密工具,特别适用于对NTFS分区上的文件和文件夹进行加密处理。本文将详细介绍如何使用EFS加密文件夹,以及加密过程中的注意事项。 ... [详细]
  • Android与JUnit集成测试实践
    本文探讨了如何在Android项目中集成JUnit进行单元测试,并详细介绍了修改AndroidManifest.xml文件以支持测试的方法。 ... [详细]
  • 深入解析WebP图片格式及其应用
    随着互联网技术的发展,无论是PC端还是移动端,图片数据流量占据了很大比重。尤其在高分辨率屏幕普及的背景下,如何在保证图片质量的同时减少文件大小,成为了亟待解决的问题。本文将详细介绍Google推出的WebP图片格式,探讨其在实际项目中的应用及优化策略。 ... [详细]
  • 菜鸟物流用户增长部现正大规模招聘P6及以上级别的JAVA工程师,提供年后入职选项。 ... [详细]
  • 深入解析层次聚类算法
    本文详细介绍了层次聚类算法的基本原理,包括其通过构建层次结构来分类样本的特点,以及自底向上(凝聚)和自顶向下(分裂)两种主要的聚类策略。文章还探讨了不同距离度量方法对聚类效果的影响,并提供了具体的参数设置指导。 ... [详细]
author-avatar
lovely蓝衣13
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有