阿里面试:页面调10 个上游接口,如何做高并发?

说在前面

在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易的面试资格,遇到很多很重要的面试题:

一个页面要调100 个上游接口,如何优化?

一个场景题,一个页面中,需要通过调用下游系统的很多很多个接口来获取数据,请问最优的高并发设计方案?

就在昨天, 一个小伙伴面试阿里, 遇到这道题:

场景题:一次要调10 个上游接口,如何做高并发?

小伙伴 没有回答好,导致面试挂了,来求助尼恩,如何才能回答得很漂亮, 让面试官刮目相看、口水直流。

尼恩提示:并发调用的知识,既是面试的核心知识,又是开发的核心知识。

所以,尼恩给大家做一下系统化、体系化的梳理,使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

当然,这道面试题,以及参考答案,也会收入咱们的 《尼恩Java面试宝典PDF》V114版本PDF集群,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

最新《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请关注本公众号【技术自由圈】获取,后台回复:领电子书

文章目录

    • 说在前面
    • 正确、最佳的答题姿势
    • 全链路如何拆分后,进行优化和改造呢?
    • 多层次如何拆分后,进行优化和改造呢?
    • 多维度优化和改造,主要有哪些呢?
    • 业务线程,IO线程,如何进行优化和改造呢?
    • 网络传输维度,如何进行优化和改造呢?
    • 方案一实操
      • 方案一性能基线测试
    • 方案二实操:
      • 方案二性能基线测试
    • 方案三实操:
      • 方案三性能基线测试
    • 说在最后
    • 推荐阅读

正确、最佳的答题姿势

尼恩给大家梳理一下正确、最佳的答题姿势。有了这个姿势,面试官自然爱到 “不能自已、口水直流”

页面调10 个上游接口,如何做高并发?

首先, 告诉面试官, 解决这个问题,需要 全链路、多层次、多维度进行 优化和改造

全链路如何拆分后,进行优化和改造呢?

庖丁解牛,但是也不需要太复杂,可以把简单的把全链路拆分如下:

  • 接受下游请求环节
  • 上游请求分裂后入列环节
  • 执行上游调用环节
  • 上游结果聚合和响应环节

多层次如何拆分后,进行优化和改造呢?

核心的措施是:异步化, 但是,要分层进行异步化

可以简单的, 把用户的api调用解耦为三层, 如下图所示:

  • 应用层:编程模型的异步化
  • 框架层:IO线程的异步化
  • OS层: IO模型的异步化

解耦之后,再庖丁解牛,一层一层的进行异步化架构。

如何实现全链路异步,知识非常多,具体请参见尼恩的《全链路异步,让你的 SpringCloud 性能优化10倍+》、《NIO学习圣经》等深度文章。

建议大家把以上这些文章,作为作为一个体系来学习。

多维度优化和改造,主要有哪些呢?

其实有很多, 但是主要聚焦的点是:

业务线程,IO线程,如何进行优化和改造呢?

前面已经庖丁解牛,但是也不需要太复杂,可以把简单的把全链路拆分如下:

  • 接受下游请求环节
  • 上游请求分裂后入列环节
  • 执行上游调用环节
  • 上游结果聚合和响应环节

第二个环节涉及到了 业务线程池,第三个环节设计到了 IO线程池

都需要合理的设置线程池的大小、拒绝策略。 并且结合不同的框架和组件,结合自己的业务场景实现异步。

比如:

方案一: 使用 CompletableFuture (自定义业务线程池) + httpClient (池化同步io框架) + CountDownLatch闭锁(聚合结果)

方案二: CloseableHttpAsyncClient(池化异步io框架) + CountDownLatch闭锁(聚合结果)

方案三: 自研Netty 异步IO框架+ CountDownLatch闭锁(聚合结果)

网络传输维度,如何进行优化和改造呢?

核心就是两点:

  • 连接复用
  • 多路复用

首先看 连接复用。 也就是 短链接,变成长连接

http1.0协议头里可以设置Connection:Keep-Alive。在header里设置Keep-Alive可以在一定时间内复用连接,具体复用时间的长短可以由服务器控制,一般在15s左右。

到http1.1之后Connection的默认值就是Keep-Alive,如果要关闭连接复用需要显式的设置Connection:Close。

多路复用代替原来的序列和阻塞机制。所有就是请求的都是通过一个 TCP 连接并发完成。

因为在多路复用之前所有的传输是基于基础文本的,在多路复用中是基于二进制数据帧的传输、消息、流,所以可以做到乱序的传输。

多路复用对同一域名下所有请求都是基于流,所以不存在同域并行的阻塞。

多路复用复用场景,多次请求如下图:

http2.0

尼恩提示:由于http1.2 目前普及度不够,一般还是考虑 http1.1连接复用

方案一实操

使用 CompletableFuture (自定义业务线程池) + httpClient (池化同步io框架) + CountDownLatch闭锁(聚合结果)

static final HttpClient httpClient = HttpClientBuilder.create().build();@Benchmark
@Test
public void HttpClient() {List<String> apis = Arrays.asList("http://192.168.56.121/echo?i=1","http://192.168.56.121/echo?i=2","http://192.168.56.121/echo?i=3");CountDownLatch latch = new CountDownLatch(apis.size());Map<String, String> results = new ConcurrentHashMap<>();for (String api : apis) {CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {HttpResponse response = null;try {response = httpClient.execute(new HttpGet(api));} catch (IOException e) {return null;}if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {try {return EntityUtils.toString(response.getEntity());} catch (Exception e) {log.error("error", e);throw new RuntimeException(e);}}return null;});future.whenComplete((result, throwable) -> {latch.countDown();results.put(api, result);});}try {latch.await(10000000, TimeUnit.MILLISECONDS);} catch (Exception e) {log.error("error", e);//            throw new RuntimeException(e);}//        System.out.println(results.toString());
}

方案一性能基线测试

这里使用linux + jmh 框架,完成性能基线测试

达到 5000qps

方案二实操:

方案二:CloseableHttpAsyncClient(池化异步io框架) + CountDownLatch闭锁(聚合结果)

这里去掉了业务线程池。 提升了性能

@Benchmark
@Test
public void HttpAsyncClient() {List<String> urls = Arrays.asList("http://192.168.56.121/echo?i=1","http://192.168.56.121/echo?i=2","http://192.168.56.121/echo?i=3");CountDownLatch latch = new CountDownLatch(urls.size());Map<String, String> results = new ConcurrentHashMap<>();for (int i = 0; i < urls.size(); i++) {final String url = urls.get(i);Future<HttpResponse> f0 = asyncClient.execute(new HttpGet(url), new FutureCallback<HttpResponse>() {public void completed(HttpResponse response) {latch.countDown();if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {try {String result = EntityUtils.toString(response.getEntity());results.put(url, result);} catch (IOException e) {log.error("error", e);//                            throw new RuntimeException(e);}}}public void failed(Exception ex) {latch.countDown();log.error("error", ex);//                    ex.printStackTrace();}public void cancelled() {latch.countDown();}});}try {latch.await(10000000, TimeUnit.MILLISECONDS);} catch (InterruptedException e) {throw new RuntimeException(e);}//        System.out.println("results = " + results);
}

方案二性能基线测试

这里使用linux + jmh 框架,完成性能基线测试

达到 4300qps

理论上性能会更优,但是,看上去性能更差。

why?

具体原因,尼恩还在思考, 有写眉目, 具体可以来技术自由圈社群交流。

方案三实操:

方案三: 自研Netty 异步IO框架+ CountDownLatch闭锁(聚合结果)

尼恩在网上找了一个 生产环境上的 qps达到 9000的 自研Netty 异步IO框架

完成了实验

@Benchmark
@Test
public void nettyGet() {//        setup();List<String> urls = Arrays.asList("/echo?i=1","/echo?i=2","/echo?i=3");CountDownLatch latch = new CountDownLatch(urls.size());Map<Integer, Object> results = new ConcurrentHashMap<>();ReqOptions options = new ReqOptions(TypeReference.from(String.class));for (int i = 0; i < urls.size(); i++) {int finalI = i;longConnHttpClient.getAsync("/echo?i=" + i, options, response -> {Object content = response.content();results.put(finalI, content);latch.countDown();}, e -> {e.printStackTrace();latch.countDown();});}try {latch.await(10000000, TimeUnit.MILLISECONDS);} catch (InterruptedException e) {throw new RuntimeException(e);}//        System.out.println("results = " + results);}

方案三性能基线测试

这里使用linux + jmh 框架,完成性能基线测试

第一次个版本,性能就 300 ops

尼恩都晕了

进行优化之后,第二次验证, 也就4300qps, 但是,看上去性能也很差。

不用jmh进行基线测试, 达到 6000多qps,这下明白了。

为啥 技术越高明,性能反而不高呢?

还有有原因的,当然目前来看,具体的原因尼恩也是猜测,不能大放厥词。

具体的原因,尼恩还需要再做实验验证一下,确认之后再发布。

但是,目前没时间了,在录制《10Wqps netty网关架构与实操》, 所以,这里做个遗留问题,后面录个视频说吧。

说在最后

异步调用面试题,是非常常见的面试题。

以上的内容,如果大家能对答如流,如数家珍,基本上 面试官会被你 震惊到、吸引到。

在面试之前,建议大家系统化的刷一波 5000页《尼恩Java面试宝典PDF》,并且在刷题过程中,如果有啥问题,大家可以来 找 40岁老架构师尼恩交流。

最终,让面试官爱到 “不能自已、口水直流”。offer, 也就来了。

推荐阅读

《百亿级访问量,如何做缓存架构设计》

《多级缓存 架构设计》

《消息推送 架构设计》

《阿里2面:你们部署多少节点?1000W并发,当如何部署?》

《美团2面:5个9高可用99.999%,如何实现?》

《网易一面:单节点2000Wtps,Kafka怎么做的?》

《字节一面:事务补偿和事务重试,关系是什么?》

《网易一面:25Wqps高吞吐写Mysql,100W数据4秒写完,如何实现?》

《亿级短视频,如何架构?》

《炸裂,靠“吹牛”过京东一面,月薪40K》

《太猛了,靠“吹牛”过顺丰一面,月薪30K》

《炸裂了…京东一面索命40问,过了就50W+》

《问麻了…阿里一面索命27问,过了就60W+》

《百度狂问3小时,大厂offer到手,小伙真狠!》

《饿了么太狠:面个高级Java,抖这多硬活、狠活》

《字节狂问一小时,小伙offer到手,太狠了!》

《收个滴滴Offer:从小伙三面经历,看看需要学点啥?》

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》PDF,请到下面公号【技术自由圈】取↓↓↓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/151195.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI工程化—— 如何让AI在企业多快好省的落地?

作为计算机科学的一个重要领域&#xff0c;机器学习也是目前人工智能领域非常活跃的分支之一。机器学习通过分析海量数据、总结规律&#xff0c;帮助人们解决众多实际问题。随着机器学习技术的发展&#xff0c;越来越多的企业将机器学习技术作为核心竞争力&#xff0c;并运用在…

python读取vivo手机截图,将满屏图片文件移动别的路径

问题之初 python读取vivo手机截图&#xff0c; 将满屏图片文件移动别的路径好多这样的图片&#xff0c;占用手机大量的内存&#xff0c;食之无味弃之可惜&#xff01;那么会复制粘贴&#x1f440;代码的我们我们今天就把这些图片筛选清理掉。 这段代码 原有逻辑的基础上&…

智能井盖传感器:城市安全卫士

随着城市人口的不断增加和城市基础设施的不断发展&#xff0c;井盖作为城市道路和排水系统的重要组成部分&#xff0c;承担着确保城市安全和便利性的关键角色。然而&#xff0c;井盖在日常使用中常常面临倾斜、水浸和翻转等问题&#xff0c;这些问题可能导致交通阻塞、行人坠井…

边坡安全监测系统的功能优势

随着科技的进步&#xff0c;边坡安全监测系统在各种工程项目中发挥着越来越重要的作用。这款系统通过实时监测垂直、水平位移数据&#xff0c;以折线图的方式显示在监控平台中&#xff0c;为工程人员提供了直观、便捷的监控工具&#xff0c;从而能够及时掌握边坡稳定状况&#…

Altium Designer培训 | 4 - 原理图创建篇

元件的放置 器件的复制及对齐 导线及NetLabel的添加 Value值的核对 封装的统一管理 原理图的编译设置及检查

tomcat安装,创建web后端项目,部署项目过程

1&#xff0c;安装服务器&#xff0c;使用 Apache免费提供的服务器TomCat&#xff0c;注意JDK版本。 TomCat官方站点 文件解压目录。 启动服务器&#xff1a;bin目录下点击startup.bat&#xff0c;出现小黑框&#xff0c;浏览器默认访问http://127.0.0.1:8080/ 关闭服务器&…

正点原子嵌入式linux驱动开发——Linux内核顶层Makefile详解

之前的几篇学习笔记重点讲解了如何移植uboot到STM32MP157开发板上&#xff0c;从本章就开始学习如何移植Linux内核。 同uboot一样&#xff0c;在具体移植之前&#xff0c;先来学习一下Linux内核的顶层Makefile文件&#xff0c;因为顶层 Makefile控制着Linux内核的编译流程。 L…

提取歌曲伴奏?用对软件一键帮你搞定~

相信大家经常想获取某首歌曲的伴奏&#xff0c;但是不知从何下手&#xff0c;今天这篇教程给大家分享一个超神奇软件&#xff0c;一键提取歌曲伴奏&#xff01; 第一步&#xff1a;打开【音分轨】APP&#xff0c;进入首页点击【人声分离】 第二步&#xff1a;选择导入方式&…

C++ -- 学习系列 关联式容器 set 与 map

一 关联式容器是什么&#xff1f; c 中有两种容器类型&#xff1a;关联式容器与序列式容器&#xff08;顺序容器&#xff09; 关联式中的容器是按照关键字来存储与访问的&#xff0c;序列式容器&#xff08;顺序容器&#xff09;则是元素在容器中的相对位置来存储与访问的。…

开发过程教学——交友小程序

交友小程序 1. 我的基本信息2. 我的人脉2.1 我的关注2.2 我的粉丝 3. 我的视频4. 我的相册 特别注意&#xff1a;由于小程序分包限制2M以内&#xff0c;所以要注意图片和视频的处理。 1. 我的基本信息 数据库表&#xff1a; 我的基本信息我的登录退出记录我的登录状态&#x…

运营商sdwan优缺点及sdwan服务商优势

SD-WAN(软件定义广域网)作为一种重要的网络解决方案&#xff0c;已经受到了广泛的关注和采用。然而&#xff0c; 无论是由传统运营商提供的SD-WAN还是专门的SD-WAN服务提供商&#xff0c;都存在各自的优缺点。 运营商提供的SD-WAN的缺点&#xff1a; 1. 有限的灵活性&#xf…

Kubernetes概述架构与工作流程简述

文章目录 Kubernetes概述Kubernetes优势Kubernetes 集群组件控制平面组件Node 组件 Kubernetes工作流程下期预告 Kubernetes概述 Kubernetes 是一个可移植、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;可促进声明式配置和自动化。 Kubernetes 拥…

如何提升爬虫IP使用效率?精打细算的方法分享

在进行爬虫数据采集时&#xff0c;爬虫IP是不可或缺的工具。然而&#xff0c;爬虫IP的费用可能是一个爬虫项目的重要开支之一。为了帮助您节省爬虫IP经费&#xff0c;本文将分享一些经济高效的方法&#xff0c;让您在使用爬虫IP时更加节约成本&#xff0c;提高经济效益。 一、优…

gitlab登录出现的Invalid login or password问题

前提 我是在一个项目里创建的gitlab账号&#xff0c;想在别的项目里登录或者官网登录发现怎么都登陆不上 原因 在GitLab中&#xff0c;有两种不同的账号类型&#xff1a;项目账号和个人账号&#xff08;官网账号&#xff09;。 项目账号&#xff1a;项目账号是在特定GitLab…

ubuntu 设置x11vnc服务

Ubuntu 18.04 设置x11vnc服务 自带的vino-server也可以用但是不好用&#xff0c;在ubuntu论坛上看见推荐的x11vnc&#xff08;ubuntu关于vnc的帮助页面&#xff09;&#xff0c;使用设置一下&#xff0c;结果发现有一些坑需要填&#xff0c;所以写下来方便下次使用 转载请说明…

云服务仿真:完全模拟 AWS 服务的本地体验 | 开源日报 No.45

localstack/localstack Stars: 48.7k License: NOASSERTION LocalStack 是一个云服务仿真器&#xff0c;可以在您的笔记本电脑或 CI 环境中以单个容器运行。它提供了一个易于使用的测试/模拟框架&#xff0c;用于开发云应用程序。主要功能包括&#xff1a; 在本地机器上完全…

Java——StringBuffer类常用操作示例

Java——StringBuffer类常用操作 package com.yushifu.javaAPI;import java.sql.SQLOutput;//StringBuffer类&#xff08;字符串缓冲区&#xff09; //StringBuffer类与String的区别————StringBuffer的内容和长度都是可以改的 //StringBuffer类似于一个字符容器&#xff0…

通过ElementUi在Vue搭建的项目中实现CRUD

&#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Vue》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一定基础的程序员&#xff0c;这个专栏…

Linux设备驱动的精髓在哪?为何感觉写驱动就像写八股文?

Linux设备驱动的精髓在哪&#xff1f;为何感觉写驱动就像写八股文&#xff1f; 话题背景&#xff1a;随着互联网尤其是移动互联网的发展&#xff0c;Android手机操作系统得到了广泛应用&#xff0c;而Android系统是基于Linux系统开发的。另外&#xff0c;大数据、云计算等技术也…

国庆出游远程实测:ToDesk 、TeamViewer、AnyDesk远程控制软件稳定性

ToDesk 、TeamViewer、AnyDesk远程控制软件稳定性 【前言】【实测软件】【测试环境】【实操体验】1. 软件安装2. 登录速度3. 文件传输4. 操作延迟5. 画面清晰度6. 安全防护 【本文小结】 【前言】 随着科技的不断发展&#xff0c;远程控制软件已成为我们生活中不可或缺的一部分…