热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

.net每隔几秒去请求接口怎么做_「原创」实战|用手写一个骚气的请求合并,演绎底层的真实...

20大进阶架构专题每日送达冬来冬往,越来越喜欢软绵绵的被窝了。厌倦了夏天的酷热,秋天的浮躁,来一首冬天的安静。一、服务器崩溃的思考老板说&

20大进阶架构专题每日送达

1ef0646ff0bb6070df1de2743cf60f70.png
  • 冬来冬往,越来越喜欢软绵绵的被窝了。

  • 厌倦了夏天的酷热,秋天的浮躁,来一首冬天的安静。

一、服务器崩溃的思考

老板说,他要做个现场营销活动,线上线下都要参与推广,这个活动参与人数可能很大哦··· 果然,由于不是我写的代码,所以那天服务器就崩了,崩的时候很安静,写代码的那个人一个人走的,走的时候很安详。

: 当请求量到达百万级时候,为啥会崩溃呢?

8cc49f878d568335f07cafb980e762ea.png45efbc0c5002a80ce82027fc040a3f33.png5c8f4927af73ba9e53ad55d4c80e4637.png

微服务中是通过接口去向服务提供者发起http请求或者rpc(tcp)请求去获取数据,事实上大量请求中,服务端能处理的请求数量有限,服务中充斥着大量的线程,以及数据库等的连接也会被占用完,导致请求响应速度也越来越慢。

:

  • 响应速度和我们的数据层有关系吗?

  • 能不能去添加服务端服务器呢?

  • 如果能减少客户端向服务端的请求就好了?

  • 限流吗?当前场景能限流吗?

  • 每个线程去查询数据,每次都只查询某一个结果,是不是太浪费了?

  • 我们能不能想办法,提升我们系统的调用性能?

二、有人想看请求合并,今天她来了

上面的一些思路可以用加缓存,加MQ的方式去解决。但是缓存有限,MQ是个队列,有限流的效果。那么,如何才能提高系统的调用能力,我们学习一下,请求合并,结果分发。

  • 正常的请求都是一个请求一个线程,到后台触发相关的业务需求,去调用数据获取业务。

  • 当请求合并后,我们要将多个多个请求合并后统一去批量去调用。

大概的设计思路便是如下图所示:

常规请求

a32dc31c2a4d2e9694f5e9af86489b8b.png

请求合并

ddb0c60e31abcbdcb5ce1926b6e1df40.png

说下我们的思路

  • 解决请求调用多,比如调用商品数据,经过的服务多,调用链很长,所以查询数据库的次数也就非常多,数据库连接池很快就被用光,导致很多请求被阻塞,也导致应用整体线程数非常高。虽然通过增加数据库连接池大小可以缓解问题,并且可以通过压力测试,但这治标不治本。

  • 查询商品信息的时候,如果同一商品同一时刻有100个请求,那么其中的99次查询是多余的,可以把100个请求合并成一个真实的后台接口调用,只要控制好线程安全即可。我的想法是使用并发计数器来实现再配合本地缓存,计数器可直接用JDK提供的AtomicInteger,线程安全又提供原子操作。

  • 以获取商品信息为例,每个商品id对应一个计数器,计数器初始值默认是0,当一个请求过来后通过incrementAndGet使计数器自增1并返回自增后的值。当该值等于1,表明该线程在这个时间点上是第一个到达的线程,然后就去调用真实的业务逻辑,在查询到结果后放入到本地缓存中。当该值大于1的时候,表明之前已有线程正在调用业务逻辑,则进入等待状态,并循环的查询本地缓存中是否已有数据可用。获取到结果后都调用decrementAndGet使计数器减1,计数器被减到0的时候就回到了初始状态,并且当减到0(代表最后一个线程)时清除缓存。

  • 那还有在1000次请求中,请求的数据id不同,但是使用的服务接口相同,都是查询商品库的商品id1~1000的数据,都是从表里面查询,queryDataById(dataId),那我也可以合并这些请求,改为批量查询,然后将数据分发返回。思路就是设计每个请求携带一个请求唯一的traceId,有点像链路跟踪的感觉,简单点可以使用查询的id进行最为跟踪id,将请求放入一个队中,使用定时任务,比如每隔10ms去扫描队列,将这些业务合并请求统一去请求数据库层。

  • 此方案有个数据延迟的地方,就是每次循环时的等待状态的时间。因为一次包含多次查库的业务调用,耗时基本都在几十毫秒,甚至是上百毫秒,可以把该等待睡眠设置小一点,比如10毫秒。这样即不会浪费CPU时间,实时性也比较高,但然也可以通过主动唤醒等待线程的方式,这个操作起来就比较复杂些。在这其中还可以添加一些异常处理、超时控制、最大重试次数,最大并发数(超时最大并发数就快速失败)等。

三、开始演练
  • 模拟一个远程调用接口


import org.springframework.stereotype.Service;

import java.util.*;

/**
* 模拟远程调用ShopData接口
* @author Lijing
*/
@Service
public class QueryServiceRemoteCall {

/**
* 调用远程的商品信息查询接口
*
* @param code 商品编码
* @return 返回商品信息,map格式
*/
public HashMap queryShopDataInfoByCode(String code) {
try {
Thread.sleep(50L);
} catch (InterruptedException e) {
e.printStackTrace;
}
HashMap hashMap &#61; new HashMap<>;
hashMap.put("shopDataId



推荐阅读
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
author-avatar
lk神密勇士
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有