当前位置: 首页 > news >正文

云原生之深入解析亿级流量架构之服务限流思路与方法

一、限流思路

① 熔断

  • 系统在设计之初就把熔断措施考虑进去,当系统出现问题时,如果短时间内无法修复,系统要自动做出判断,开启熔断开关,拒绝流量访问,避免大流量对后端的过载请求。
  • 系统也应该能够动态监测后端程序的修复情况,当程序已恢复稳定时,可以关闭熔断开关,恢复正常服务。常见的熔断组件有 Hystrix 以及阿里的 Sentinel,两种互有优缺点,可以根据业务的实际情况进行选择。

在这里插入图片描述

② 服务降级

  • 将系统的所有功能服务进行一个分级,当系统出现问题需要紧急限流时,可将不是那么重要的功能进行降级处理,停止服务,这样可以释放出更多的资源供给核心功能的去用。
  • 例如在电商平台中,如果突发流量激增,可临时将商品评论、积分等非核心功能进行降级,停止这些服务,释放出机器和 CPU 等资源来保障用户正常下单,而这些降级的功能服务可以等整个系统恢复正常后,再来启动,进行补单/补偿处理。除了功能降级以外,还可以采用不直接操作数据库,而全部读缓存、写缓存的方式作为临时降级方案。

③ 延迟处理

  • 这个模式需要在系统的前端设置一个流量缓冲池,将所有的请求全部缓冲进这个池子,不立即处理。然后后端真正的业务处理程序从这个池子中取出请求依次处理,常见的可以用队列模式来实现。
  • 这就相当于用异步的方式去减少了后端的处理压力,但是当流量较大时,后端的处理能力有限,缓冲池里的请求可能处理不及时,会有一定程度延迟。

④ 特权处理

  • 这个模式需要将用户进行分类,通过预设的分类,让系统优先处理需要高保障的用户群体,其它用户群的请求就会延迟处理或者直接不处理。

⑤ 缓存、降级、限流区别

  • 缓存,是用来增加系统吞吐量,提升访问速度提供高并发。
  • 降级,是在系统某些服务组件不可用的时候、流量暴增、资源耗尽等情况下,暂时屏蔽掉出问题的服务,继续提供降级服务,给用户尽可能的友好提示,返回兜底数据,不会影响整体业务流程,待问题解决再重新上线服务
  • 限流,是指在使用缓存和降级无效的场景。比如当达到阈值后限制接口调用频率,访问次数,库存个数等,在出现服务不可用之前,提前把服务降级,只服务好一部分用户。

二、限流的算法

① 计数器算法

  • 简单粗暴,比如指定线程池大小,指定数据库连接池大小、nginx 连接数等,这都属于计数器算法。计数器算法是限流算法里最简单也是最容易实现的一种算法。
  • 举个例子,比如规定对于 A 接口,1 分钟的访问次数不能超过 100 个,那么就可以这么做:在一开始的时候,可以设置一个计数器 counter,每当一个请求过来的时候,counter 就加 1,如果 counter 的值大于 100 并且该请求与第一个请求的间隔时间还在 1 分钟之内,那么说明请求数过多,拒绝访问;如果该请求与第一个请求的间隔时间大于 1 分钟,且 counter 的值还在限流范围内,那么就重置 counter,就是这么简单粗暴。

在这里插入图片描述

② 漏桶算法

  • 漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会超过桶可接纳的容量时直接溢出,可以看出漏桶算法能强行限制数据的传输速率。

在这里插入图片描述

  • 这样做的好处是:
    • 削峰:有大量流量进入时,会发生溢出,从而限流保护服务可用;
    • 缓冲:不至于直接请求到服务器,缓冲压力,消费速度固定,计算性能固定。

③ 令牌桶算法

  • 令牌桶与漏桶相似,不同的是令牌桶桶中放了一些令牌,服务请求到达后,要获取令牌之后才会得到服务。举个例子,我们平时去食堂吃饭,都是在食堂内窗口前排队的,这就好比是漏桶算法,大量的人员聚集在食堂内窗口外,以一定的速度享受服务,如果涌进来的人太多,食堂装不下了,可能就有一部分人站到食堂外了,这就没有享受到食堂的服务,称之为溢出,溢出可以继续请求,也就是继续排队,那么这样有什么问题呢?
  • 如果这时候有特殊情况,如有些赶时间的志愿者啦、或者高三要高考啦,这种情况就是突发情况,如果也用漏桶算法那也得慢慢排队,这也就没有解决我们的需求,对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。如下图所示,令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。

在这里插入图片描述

  • 令牌桶好处就是,如果某一瞬间访问量剧增或者有突发情况,可以通过改变桶中令牌数量来改变连接数,就好比那个食堂排队吃饭的问题,如果现在不是直接去窗口排队,而是先来楼外拿饭票然后再去排队,那么有高三的学生时可以将增加饭票数量或者优先将令牌给高三的学生,这样比漏桶算法更加灵活。

三、限流的方法

① 并发限流

  • 简单来说就是设置系统阈值总的 QPS 个数,这些也挺常见的,就拿 Tomcat 来说,很多参数就是出于这个考虑。例如:配置的 acceptCount 设置响应连接数,maxConnections 设置瞬时最大连接数,maxThreads 设置最大线程数,并发限流体现在下面几个方面:
    • 限制总并发数(如数据库连接池、线程池);
    • 限制瞬时并发数(nginx 的 limit_conn 模块,用来限制瞬时并发连接数);
    • 限制时间窗口内的平均速率(如 Guava 的 RateLimiter、nginx 的 limit_req 模块,限制每秒的平均速率);
    • 其他的还有限制远程接口调用速率、限制 MQ 的消费速率;
    • 另外还可以根据网络连接数、网络流量、CPU 或内存负载等来限流。
  • 有了并发限流,就意味着在处理高并发的时候多了一种保护机制,不用担心瞬间流量导致系统挂掉或雪崩,最终做到有损服务而不是不服务;但是限流需要评估好,不能乱用,否则一些正常流量出现一些奇怪的问题而导致用户体验很差造成用户流失。

② 接口限流

  • 接口限流分为两个部分,一是限制一段时间内接口调用次数,参照前面限流算法的计数器算法,二是设置滑动时间窗口算法。
  • 接口总数:控制一段时间内接口被调用的总数量,可以参考前面的计数器算法,不再赘述。
  • 接口时间窗口:固定时间窗口算法(也就是前面提到的计数器算法)的问题是统计区间太大,限流不够精确,而且在第二个统计区间时没有考虑与前一个统计区间的关系与影响(第一个区间后半段 + 第二个区间前半段也是一分钟)。为了解决上面提到的临界问题,可以尝试把每个统计区间分为更小的统计区间,更精确的统计计数。

在这里插入图片描述

  • 在上面的例子中,假设 QPS 可以接受 100 次查询/秒,前一分钟前 40 秒访问很低,后 20 秒突增,并且这个持续了一段时间,直到第二分钟的第 40 秒才开始降下来,根据前面的计数方法,前一秒的 QPS 为 94,后一秒的 QPS 为 92,那么没有超过设定参数。但是在中间区域,QPS 达到了 142,这明显超过了允许的服务请求数目,因此固定窗口计数器不太可靠,需要滑动窗口计数器。
  • 计数器算法其实就是固定窗口算法,只是它没有对时间窗口做进一步地划分,所以只有 1 格;由此可见,当滑动窗口的格子划分的越多,也就是将秒精确到毫秒或者纳秒,那么滑动窗口的滚动就越平滑,限流的统计就会越精确。需要注意的是,消耗的空间就越多。

四、限流实现

① guava 实现

  • 引入包:
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>28.1-jre</version>
</dependency>
  • 核心代码:
LoadingCache<Long, AtomicLong> counter = CacheBuilder.newBuilder().expireAfterWrite(2, TimeUnit.SECONDS).build(new CacheLoader<Long, AtomicLong>() {@Overridepublic AtomicLong load(Long secend) throws Exception {// TODO Auto-generated method stubreturn new AtomicLong(0);}});
counter.get(1l).incrementAndGet();

② 令牌桶实现

  • 稳定模式(SmoothBursty:令牌生成速度恒定):
public static void main(String[] args) {// RateLimiter.create(2)每秒产生的令牌数RateLimiter limiter = RateLimiter.create(2);// limiter.acquire() 阻塞的方式获取令牌System.out.println(limiter.acquire());;try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(limiter.acquire());;System.out.println(limiter.acquire());;System.out.println(limiter.acquire());;System.out.println(limiter.acquire());;System.out.println(limiter.acquire());;System.out.println(limiter.acquire());;
}
  • RateLimiter.create(2):容量和突发量,令牌桶算法允许将一段时间内没有消费的令牌暂存到令牌桶中,用来突发消费。
  • 渐进模式(SmoothWarmingUp:令牌生成速度缓慢提升直到维持在一个稳定值):
// 平滑限流,从冷启动速率(满的)到平均消费速率的时间间隔
RateLimiter limiter = RateLimiter.create(2,1000l,TimeUnit.MILLISECONDS);
System.out.println(limiter.acquire());;
try {Thread.sleep(2000);
} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();
}
System.out.println(limiter.acquire());;
System.out.println(limiter.acquire());;
System.out.println(limiter.acquire());;
System.out.println(limiter.acquire());;System.out.println(limiter.acquire());;
System.out.println(limiter.acquire());;
  • 超时:
boolean tryAcquire = limiter.tryAcquire(Duration.ofMillis(11));
  • 在 timeout 时间内是否能够获得令牌,异步执行。

③ 分布式系统限流

  • Nginx + Lua 实现,可以使用 resty.lock 保持原子特性,请求之间不会产生锁的重入,使用 lua_shared_dict 存储数据:
local locks = require "resty.lock"local function acquire()local lock =locks:new("locks")local elapsed, err =lock:lock("limit_key") --互斥锁 保证原子特性local limit_counter =ngx.shared.limit_counter --计数器local key = "ip:" ..os.time()local limit = 5 --限流大小local current =limit_counter:get(key)if current ~= nil and current + 1> limit then --如果超出限流大小lock:unlock()return 0endif current == nil thenlimit_counter:set(key, 1, 1) --第一次需要设置过期时间,设置key的值为1--过期时间为1elselimit_counter:incr(key, 1) --第二次开始加1即可endlock:unlock()return 1
end
ngx.print(acquire())

相关文章:

云原生之深入解析亿级流量架构之服务限流思路与方法

一、限流思路 ① 熔断 系统在设计之初就把熔断措施考虑进去&#xff0c;当系统出现问题时&#xff0c;如果短时间内无法修复&#xff0c;系统要自动做出判断&#xff0c;开启熔断开关&#xff0c;拒绝流量访问&#xff0c;避免大流量对后端的过载请求。系统也应该能够动态监测…...

【Python炫酷系列】祝考研的友友们金榜题名吖(完整代码)

文章目录 环境需求完整代码详细分析系列文章环境需求 python3.11.4及以上版本PyCharm Community Edition 2023.2.5pyinstaller6.2.0(可选,这个库用于打包,使程序没有python环境也可以运行,如果想发给好朋友的话需要这个库哦~)【注】 python环境搭建请见:https://want595.…...

KL散度、CrossEntropy详解

文章目录 0. 概述1. 信息量1.1 定义1.2 性质1.3 例子2. 熵 Entropy2.1 定义2.2 公式2.3 例子3. 交叉熵 Cross Entropy3.1 定义3.2 公式3.3 例子4. KL 散度(相对熵)4.1 公式...

【算法】红黑树

一、红黑树介绍 红黑树是一种自平衡二叉查找树&#xff0c;是在计算机科学中用到的一种数据结构&#xff0c;典型的用途是实现关联数组。 红黑树是在1972年由Rudolf Bayer发明的&#xff0c;当时被称为平衡二叉B树&#xff08;symmetric binary B-trees&#xff09;。后来&am…...

2023楚慧杯 WEB方向 部分:(

1、eaaeval 查看源码能看见账号&#xff1a;username169&#xff0c;密码&#xff1a;password196提交这个用户密码可以跳转到页面/dhwiaoubfeuobgeobg.php 通过dirsearch目录爆破可以得到www.zip <?php class Flag{public $a;public $b;public function __construct(){…...

STM32 CAN多节点组网项目实操 挖坑与填坑记录2

系列文章&#xff0c;持续探索CAN多节点通讯&#xff0c; 上一篇文章链接&#xff1a; STM32 CAN多节点组网项目实操 挖坑与填坑记录-CSDN博客文章浏览阅读120次。CAN线性组网项目开发过程中遇到的数据丢包问题&#xff0c;并尝试解决的记录和推测分析。开发了一个多节点线性…...

Flink 数据类型 TypeInformation信息

Flink流应用程序处理的是以数据对象表示的事件流。所以在Flink内部&#xff0c;我么需要能够处理这些对象。它们需要被序列化和反序列化&#xff0c;以便通过网络传送它们&#xff1b;或者从状态后端、检查点和保存点读取它们。为了有效地做到这一点&#xff0c;Flink需要明确知…...

基于python的leetcode算法介绍之递归

文章目录 零 算法介绍一 简单示例 辗转相除法Leetcode例题与思路[509. 斐波那契数](https://leetcode.cn/problems/fibonacci-number/)解题思路&#xff1a;题解&#xff1a; [206. 反转链表](https://leetcode.cn/problems/reverse-linked-list/)解题思路&#xff1a;题解&…...

2023年度佳作:AIGC、AGI、GhatGPT、人工智能大语言模型的崛起与挑战

目录 前言 01 《ChatGPT 驱动软件开发》 内容简介 02 《ChatGPT原理与实战》 内容简介 03 《神经网络与深度学习》 04 《AIGC重塑教育》 内容简介 05 《通用人工智能》 目  录 前言 2023年是人工智能大语言模型大爆发的一年&#xff0c;一些概念和英文缩写也在这一…...

Axure的交互以及情形的介绍

一. 交互 1.1 交互概述 通俗来讲就是&#xff0c;谁用了什么方法做了什么事情&#xff0c;主体"谁"对应的就是axure中的元件&#xff0c;"什么方法"对应的就是交互事件&#xff0c;比如单击事件、双击事件&#xff0c;"什么事情"对应的就是交互…...

【MATLAB第84期】基于MATLAB的波形叠加极限学习机SW-ELM代理模型的sobol全局敏感性分析法应用

【MATLAB第84期】基于MATLAB的波形叠加极限学习机SW-ELM代理模型的sobol全局敏感性分析法应用 前言 跟往期sobol区别&#xff1a; 1.sobol计算依赖于验证集样本&#xff0c;无需定义变量上下限。 2.SW-ELM自带激活函数&#xff0c;计算具有phi&#xff08;x&#xff09;e^x激…...

米游社区表情包整合网站源码

源码介绍 米游社表情包整合网站源码&#xff0c;来自Github大佬的项目&#xff0c;包含米游兔123枚&#xff0c;米游社 玩家12枚&#xff0c;崩坏 星穹铁道112枚&#xff0c;绝区零218枚&#xff0c;NAP32枚&#xff0c;崩坏RPG62枚&#xff0c;崩坏3-1282枚&#xff0c;原神 …...

easyexcel调用公共导出方法导出数据

easyexcel备忘 Slf4j public class ConditionDownloadUtil {//扫描在xboot 包下所有IService 接口的子类, 每次启动服务后, 重新扫描public final static Class[] classesExtendsIService ClassUtil.scanPackageBySuper("cn.exrick.xboot", IService.class).toArra…...

C语言插入排序算法及代码

一、原理 在待排序的数组里&#xff0c;从数组的第二个数字开始&#xff0c;通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入。 二、代码部分 #include<stdio.h> #include<stdlib.h> int ma…...

2023年中国法拍房用户画像和数据分析

法拍房主要平台 法拍房主要平台有3家&#xff0c;分别是阿里、京东和北交互联平台。目前官方认定纳入网络司法拍卖的平台共有7家&#xff0c;其中阿里资产司法拍卖平台的挂拍量最大。 阿里法拍房 阿里法拍房数据显示2017年&#xff0c;全国法拍房9000套&#xff1b;2018年&a…...

Android 清除临时文件,清空缓存

python 代码&#xff1a; import os import shutil import tracebackdef delete_folder(path):if os.path.exists(path):print(f"删除文件夹: {path}")shutil.rmtree(path)print("删除完成")def delete_file(path):if os.path.exists(path):print(f"删…...

Guava限流神器:RateLimiter使用指南

1. 引言 可能有些小伙伴听到“限流”这个词就觉得头大&#xff0c;感觉像是一个既复杂又枯燥的话题。别急&#xff0c;小黑今天就要用轻松易懂的方式&#xff0c;带咱们一探RateLimiter的究竟。 想象一下&#xff0c;当你去超市排队结账时&#xff0c;如果收银台开得越多&…...

【六大排序详解】开篇 :插入排序 与 希尔排序

插入排序 与 希尔排序 六大排序之二 插入排序 与 希尔排序1 排序1.1排序的概念 2 插入排序2.1 插入排序原理2.2 排序步骤2.3 代码实现 3 希尔排序3.1 希尔排序原理3.2 排序步骤3.3 代码实现 4 时间复杂度分析 Thanks♪(&#xff65;ω&#xff65;)&#xff89;下一篇文章见&am…...

凸优化问题求解

这里写目录标题 1. 线性规划基本定理2.单纯形法2.1 转轴运算 3. 内点法3.1 线性规划的内点法 1. 线性规划基本定理 首先我们指出&#xff0c;线性规划均可等价地化成如下标准形式 { min ⁡ c T x , s . t A x b , x ⪰ 0 , \begin{align}\begin{cases}\min~c^Tx,\\\mathrm{s.…...

文件操作入门指南

目录 一、为什么使用文件 二、什么是文件 2.1 程序文件 2.2 数据文件 2.3 文件名 三、文件的打开和关闭 3.1 文件指针 3.2 文件的打开和关闭 四、文件的顺序读写 ​编辑 &#x1f33b;深入理解 “流”&#xff1a; &#x1f342;文件的顺序读写函数介绍&#xff1a; …...

Axure之交互与情节与一些实例

目录 一.交互与情节简介 二.ERP登录页到主页的跳转 三.ERP的菜单跳转到各个页面的跳转 四.省市联动 五.手机下拉加载 今天就到这里了&#xff0c;希望帮到你哦&#xff01;&#xff01;&#xff01; 一.交互与情节简介 "交互"通常指的是人与人、人与计算机或物体…...

【数据库设计和SQL基础语法】--连接与联接--多表查询与子查询基础(二)

一、子查询基础 1.1 子查询概述 子查询是指在一个查询语句内部嵌套另一个查询语句的过程。子查询可以嵌套在 SELECT、FROM、WHERE 或 HAVING 子句中&#xff0c;用于从数据库中检索数据或执行其他操作。子查询通常返回一个结果集&#xff0c;该结果集可以被包含它的主查询使用…...

Android studio中导入opencv库

具体opencv库的导入流程参考链接&#xff1a;Android Studio开发之路 &#xff08;五&#xff09;导入OpenCV以及报错解决 一、出现的错误&#xff1a;NullPointerException: Cannot invoke “java.io.File.toPath()” because “this.mySdkLocation” is null 解决办法&#…...

Linux(1)_基础知识

第一部分 一、Linux系统概述 创始人&#xff1a;芬兰大学大一的学生写的Linux内核&#xff0c;李纳斯托瓦兹。 Linux时unix的类系统&#xff1b; 特点&#xff1a;多用户 多线程的操作系统&#xff1b; 开源操作系统&#xff1b; 开源项目&#xff1a;操作系统&#xff0c;应用…...

网络相关面试题

简述 TCP 连接的过程&#xff08;淘系&#xff09; 参考答案&#xff1a; TCP 协议通过三次握手建立可靠的点对点连接&#xff0c;具体过程是&#xff1a; 首先服务器进入监听状态&#xff0c;然后即可处理连接 第一次握手&#xff1a;建立连接时&#xff0c;客户端发送 syn 包…...

Vue2面试题:说一下对跨域的理解?

http请求分为两大类&#xff1a;普通http请求&#xff08;如百度请求&#xff09;和ajax请求&#xff08;跨域是出现在ajax请求&#xff09; 同源策略&#xff1a;在浏览器发起ajax请求时&#xff0c;当前的网址和被请求的网址协议、域名、端口号必须完全一致&#xff0c;目的是…...

Axure中如何使用交互样式交互事件交互动作情形

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《产品经理如何画泳道图&流程图》 ⛺️ 越努力 &#xff0c;越幸运 目录 一、Axure中交互样式 1、什么是交互样式&#xff1f; 2、交互样式的作用&#xff1f; 3、Axure中如何…...

1112. 迷宫(DFS之连通性模型)

1112. 迷宫 - AcWing题库 一天Extense在森林里探险的时候不小心走入了一个迷宫&#xff0c;迷宫可以看成是由 n∗n 的格点组成&#xff0c;每个格点只有2种状态&#xff0c;.和#&#xff0c;前者表示可以通行后者表示不能通行。 同时当Extense处在某个格点时&#xff0c;他只…...

飞天使-k8s知识点1-kubernetes架构简述

文章目录 名词功能要点 k8s核心要素CNCF 云原生框架简介k8s组建介绍 名词 CI 持续集成, 自动化构建和测试&#xff1a;通过使用自动化构建工具和自动化测试套件&#xff0c;持续集成可以帮助开发人员自动构建和测试他们的代码。这样可以快速检测到潜在的问题&#xff0c;并及早…...

linux中deadline调度原理与代码注释

简介 deadline调度是比rt调度更高优先级的调度&#xff0c;它没有依赖于优先级的概念&#xff0c;而是给了每个实时任务一定的调度时间&#xff0c;这样的好处是&#xff1a;使多个实时任务场景的时间分配更合理&#xff0c;不让一些实时任务因为优先级低而饿死。deadline调度…...

防邪办网站建设方案文档/windows优化大师好不好

转自&#xff1a;http://www.dearda.com/index.php/archives/380 之前我发布的《SharePoint备份与还原》一文初步探讨了使用SharePoint管理中心备份与还原站点的方法。但是在我实际部署的过程中发现用管理中心做还原并不可靠&#xff01;&#xff08;PS&#xff1a;微软的备份与…...

郑州建设企业网站/百度关键词优化软件网站

随机梯度下降&#xff08;Stochastic gradient descent&#xff09;和 批量梯度下降&#xff08;Batch gradient descent &#xff09;的公式对比、实现对比 分类&#xff1a; 梯度下降 最优化2013-05-25 21:21 22978人阅读 评论(16) 收藏 举报梯度下降最优化迭代梯度下降&…...

重庆网站建设注意事项/快排seo

接上一篇 WPF多进程UI探索&#xff08;Like Chrome&#xff09; 找到了相对较靠谱的跨进程传递WPFUI的方法&#xff0c;本篇将对WPF多进程UI框架进行设计。 功能性需求 一个主进程作为宿主&#xff0c;承载多个子进程的UI每个子进程相互独立&#xff0c;互不影响主进程和子进程…...

什么是网站流量优化/软文发稿平台有哪些

文章目录1. 编码与调制编码调制1. 编码与调制 基带信号&#xff1a;将数字信号1和0直接用两种不同的电压表示&#xff0c;再送到数字信道上去传输&#xff08;基带传输) 宽带信号&#xff1a;将基带信号进行调制后形成的频分复用模拟信号&#xff0c;再传送到模拟信道上去传输…...

公司做网站那个网站好/百度排名服务

前段有时间研究的时候&#xff0c;上不去&#xff0c;现在忙成这样&#xff0c;它又能上了&#xff0c;能上也没时间关注了。转载于:https://www.cnblogs.com/junuh/archive/2009/06/15/1503469.html...

百度做网站为什么上阿里云备案/旺道seo优化软件

简单的示例&#xff1a; makefile文件&#xff1a; LOCAL_PATH:$(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE:test-jniLOCAL_SRC_FILES : test-jni.cinclude $(BUILD_SHARED_LIBRARY) 如果有多个文件&#xff0c;可能有所不同吧&#xff0c;尚未尝试。 头文件&#xff1a;…...