【java】Spring Cloud --Spring Cloud Alibaba RocketMq 异步通信实现
文章目录
- 介绍
- RocketMQ特点
- Spring Cloud Stream
- Window搭建部署RocketMQ
- 下载
- 启动NameServer服务
- 启动Broker服务
- 示例
- 创建 RocketMQ 消息生产者
- 创建 RocketMQ 消息消费者
- 使用示例
- 示例关联项目
- 运行示例测试
介绍
RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务,广泛应用于多个领域,包括异步通信解耦、企业解决方案、金融支付、电信、电子商务、快递物流、广告营销、社交、即时通信、移动应用、手游、视频、物联网、车联网等。
RocketMQ 是阿里巴巴在2012年开源的分布式消息中间件,目前已经捐赠给 Apache 软件基金会,并于2017年9月25日成为 Apache 的顶级项目。作为经历过多次阿里巴巴双十一这种“超级工程”的洗礼并有稳定出色表现的国产中间件,以其高性能、低延时和高可靠等特性近年来已经也被越来越多的国内企业使用。
RocketMQ特点
- 是一个队列模型的消息中间件,具有高性能、高可靠、高实时、分布式等特点
- Producer、Consumer、队列都可以分布式
- Producer 向一些队列轮流发送消息,队列集合称为 Topic,Consumer 如果做广播消费,则一个 Consumer 实例消费这个 Topic 对应的所有队列,如果做集群消费,则多个 Consumer 实例平均消费这个 Topic 对应的队列集合
- 能够保证严格的消息顺序
- 支持拉(pull)和推(push)两种消息模式
- 高效的订阅者水平扩展能力
- 实时的消息订阅机制
- 亿级消息堆积能力
- 支持多种消息协议,如 JMS、OpenMessaging 等
- 较少的依赖
Spring Cloud Stream
Spring Cloud Stream 是一个构建消息驱动微服务的框架。
Spring Cloud Stream 提供了消息中间件配置的统一抽象,推出了 pub/sub,consumer groups,semantics,stateful partition 这些统一的模型支持。
Spring Cloud Stream 核心构件有:Binders、Bindings和Message,应用程序通过 inputs 或者 outputs 来与 binder 交互,通过我们配置来 binding ,而 binder 负责与中间件交互,Message为数据交换的统一数据规范格式。
-
Binding: 包括 Input Binding 和 Output Binding。
Binding 在消息中间件与应用程序提供的 Provider 和 Consumer 之间提供了一个桥梁,实现了开发者只需使用应用程序的 Provider 或 Consumer 生产或消费数据即可,屏蔽了开发者与底层消息中间件的接触。 -
Binder: 跟外部消息中间件集成的组件,用来创建 Binding,各消息中间件都有自己的 Binder 实现。
比如 Kafka 的实现 KafkaMessageChannelBinder,RabbitMQ 的实现 RabbitMessageChannelBinder 以及 RocketMQ 的实现 RocketMQMessageChannelBinder。 -
Message:是 Spring Framework 中的一个模块,其作用就是统一消息的编程模型。
比如消息 Messaging 对应的模型就包括一个消息体 Payload 和消息头 Header。
spring-cloud-stream 官网
Window搭建部署RocketMQ
下载
当前最新版本为4.6.0
下载出来解压到:D:\rocketmq 目录,目录最好不要带空格和太深,否则服务运行可能会报错
启动NameServer服务
在启动之前需要配置系统环境,不然会报错。
Please set the ROCKETMQ_HOME variable in your environment!
系统环境变量名:ROCKETMQ_HOME
根据你解压的目录配置环境变量,比如我的变量值为:D:\rocketmq
进入window命令窗口,进入D:\rocketmq\bin目录下,执行
start mqnamesrv.cmd
如上则NameServer启动成功。使用期间,窗口不要关闭。
启动Broker服务
进入bin目录下,输入
start mqbroker.cmd -n localhost:9876
如上的 ip+port 是rocketmq的服务地址和端口。
运行如上命令,可能会报如下错误。找不到或无法加载主类
如果出此情况,打开bin–>runbroker.cmd,修改%CLASSPATH%成"%CLASSPATH%"
保存再次执行如上命令。执行成功后,提示boot success 代表成功。
示例
本示例实现三种消息的发布以及订阅接收。
创建 RocketMQ 消息生产者
创建 ali-rocketmq-producer 工程,端口为:28081
- pom.xml添加依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>cloud-alibaba</artifactId><groupId>com.easy</groupId><version>1.0.0</version></parent><modelVersion>4.0.0</modelVersion><artifactId>ali-rocketmq-producer</artifactId><packaging>jar</packaging><dependencies><!--rocketmq依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-stream-rocketmq</artifactId></dependency><!--web依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
- 配置 Output 的 Binding 信息并配合 @EnableBinding 注解使其生效
application.yml配置
server:port: 28081spring:application:name: ali-rocketmq-producercloud:stream:rocketmq:binder:# RocketMQ 服务器地址name-server: 127.0.0.1:9876bindings:output1: {destination: test-topic1, content-type: application/json}output2: {destination: test-topic2, content-type: application/json}management:endpoints:web:exposure:include: '*'endpoint:health:show-details: always
ArProduceApplication.java
@SpringBootApplication
@EnableBinding({MySource.class})
public class ArProduceApplication {public static void main(String[] args) {SpringApplication.run(ArProduceApplication.class, args);}
}
- 消息生产者服务
MySource.java
package com.easy.arProduce;import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;public interface MySource {@Output("output1")MessageChannel output1();@Output("output2")MessageChannel output2();
}
SenderService.java
package com.easy.arProduce;import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.MimeTypeUtils;@Service
public class SenderService {@Autowiredprivate MySource source;/*** 发送字符串** @param msg*/public void send(String msg) {Message message = MessageBuilder.withPayload(msg).build();source.output1().send(message);}/*** 发送带tag的字符串** @param msg* @param tag*/public void sendWithTags(String msg, String tag) {Message message = MessageBuilder.withPayload(msg).setHeader(RocketMQHeaders.TAGS, tag).build();source.output1().send(message);}/*** 发送对象** @param msg* @param tag* @param <T>*/public <T> void sendObject(T msg, String tag) {Message message = MessageBuilder.withPayload(msg).setHeader(RocketMQHeaders.TAGS, tag).setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON).build();source.output2().send(message);}
}
编写 TestController.java 控制器方便测试
package com.easy.arProduce;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping(value = "test")
public class TestController {@AutowiredSenderService senderService;@RequestMapping(value = "/send", method = RequestMethod.GET)public String send(String msg) {senderService.send(msg);return "字符串消息发送成功!";}@RequestMapping(value = "/sendWithTags", method = RequestMethod.GET)public String sendWithTags(String msg) {senderService.sendWithTags(msg, "tagStr");return "带tag字符串消息发送成功!";}@RequestMapping(value = "/sendObject", method = RequestMethod.GET)public String sendObject(int index) {senderService.sendObject(new Foo(index, "foo"), "tagObj");return "Object对象消息发送成功!";}
}
创建 RocketMQ 消息消费者
创建 ali-rocketmq-consumer 工程,端口为:28082
- pom.xml添加依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>cloud-alibaba</artifactId><groupId>com.easy</groupId><version>1.0.0</version></parent><modelVersion>4.0.0</modelVersion><artifactId>ali-rocketmq-consumer</artifactId><packaging>jar</packaging><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-stream-rocketmq</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
-配置 Input 的 Binding 信息并配合 @EnableBinding 注解使其生效
application.yml配置
server:port: 28082spring:application:name: ali-rocketmq-consumercloud:stream:rocketmq:binder:name-server: 127.0.0.1:9876 #rocketmq 服务地址bindings:input1: {consumer.orderly: true} #是否排序input2: {consumer.tags: tagStr} #订阅 带tag值为tagStr的字符串input3: {consumer.tags: tagObj} #订阅 带tag值为tabObj的字符串bindings:input1: {destination: test-topic1, content-type: text/plain, group: test-group1, consumer.maxAttempts: 1}input2: {destination: test-topic1, content-type: application/plain, group: test-group2, consumer.maxAttempts: 1}input3: {destination: test-topic2, content-type: application/plain, group: test-group3, consumer.maxAttempts: 1}management:endpoints:web:exposure:include: '*'endpoint:health:show-details: always
ArConsumerApplication.java
package com.easy.arConsumer;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.stream.annotation.EnableBinding;@SpringBootApplication
@EnableBinding({MySource.class})
public class ArConsumerApplication {public static void main(String[] args) {SpringApplication.run(ArConsumerApplication.class, args);}
}
- 消息消费者服务
MySource.java
package com.easy.arConsumer;import org.springframework.cloud.stream.annotation.Input;
import org.springframework.messaging.SubscribableChannel;public interface MySource {@Input("input1")SubscribableChannel input1();@Input("input2")SubscribableChannel input2();@Input("input3")SubscribableChannel input3();
}
ReceiveService.java
package com.easy.arConsumer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Service;@Service
@Slf4j
public class ReceiveService {@StreamListener("input1")public void receiveInput1(String receiveMsg) {log.info("input1 接收到了消息:" + receiveMsg);}@StreamListener("input2")public void receiveInput2(String receiveMsg) {log.info("input2 接收到了消息:" + receiveMsg);}@StreamListener("input3")public void receiveInput3(@Payload Foo foo) {log.info("input3 接收到了消息:" + foo);}
}
使用示例
示例关联项目
本示例我们创建了两个项目实现
-
ali-rocketmq-producer:RocketMQ 消息服务生产者,服务名:ali-rocketmq-producer,端口:28081
-
ali-rocketmq-consumer:RocketMQ 消息服务消费者,服务名:ali-rocketmq-producer,端口:28082
运行示例测试
首先要启动ali-rocketmq-producer服务及ali-rocketmq-consumer服务
- 访问消息服务生产者地址: http://localhost:28081/test/send?msg=yuntian
查看服务消费者控制台,输出
2019-12-04 15:37:47.859 INFO 6356 --- [MessageThread_1] com.easy.arConsumer.ReceiveService : input1 接收到了消息:yuntian
2019-12-04 15:37:47.859 INFO 6356 --- [MessageThread_1] s.b.r.c.RocketMQListenerBindingContainer : consume C0A8096E200818B4AAC212CDA70E0014 cost: 1 ms
表示字符串消费成功被input1消费了
- 访问消息服务生产者地址: http://localhost:28081/test/sendWithTags?msg=tagyuntian
查看服务消费者控制台,输出
2019-12-04 15:38:09.586 INFO 6356 --- [MessageThread_1] com.easy.arConsumer.ReceiveService : input2 接收到了消息:tagyuntian
2019-12-04 15:38:09.592 INFO 6356 --- [MessageThread_1] com.easy.arConsumer.ReceiveService : input1 接收到了消息:tagyuntian
2019-12-04 15:38:09.592 INFO 6356 --- [MessageThread_1] s.b.r.c.RocketMQListenerBindingContainer : consume C0A8096E200818B4AAC212CDFCD30015 cost: 6 ms
表示带tag的字符串成功被input2和input1消费了,因为input1也订阅了test-topic1,并且没有我们没有加tag过滤,默认表示接收所有消息,所以也能成功接收tagyuntian字符串
- 访问消息服务生产者地址: http://localhost:28081/test/sendObject?index=1
查看服务消费者控制台,输出
2019-12-04 15:41:15.285 INFO 6356 --- [MessageThread_1] com.easy.arConsumer.ReceiveService : input3 接收到了消息:Foo{id=1, bar='foo'}
表示input3成功接收到了tag带tagObj的对象消息了,而input1却没有输出消息,这是因为sendObject发布的消息走的是test-topic2消息管道,所以不会发布给input1及input2订阅者
相关文章:
【java】Spring Cloud --Spring Cloud Alibaba RocketMq 异步通信实现
文章目录介绍RocketMQ特点Spring Cloud StreamWindow搭建部署RocketMQ下载启动NameServer服务启动Broker服务示例创建 RocketMQ 消息生产者创建 RocketMQ 消息消费者使用示例示例关联项目运行示例测试介绍 RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集…...
玫瑰花变蚊子血,自动化无痕浏览器对比测试,新贵PlayWright Vs 老牌Selenium,基于Python3.10
也许每一个男子全都有过这样的两个女人,至少两个。娶了红玫瑰,久而久之,红的变了墙上的一抹蚊子血,白的还是床前明月光;娶了白玫瑰,白的便是衣服上沾的一粒饭黏子,红的却是心口上一颗朱砂痣。–…...
Spring Cloud入门篇 Hello World | Spring Cloud 1
一、专栏说明 Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如:服务发现/注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。 本文主要介绍Spring C…...
C++学习笔记-数据结构
结构 是C中另一种用户自定义的可用数据类型,允许存储不同类型的数据项。 C/C 数组允许定义可存储相同类型数据项的变量,但是结构是 C 中另一种用户自定义的可用的数据类型,它允许存储不同类型的数据项。 结构用于表示一条记录,假…...
【C++的OpenCV】第五课-OpenCV图像常用操作(二):OpenCV的基本绘图、平滑滤波(模糊)处理
让我们继续一、OpenCV基本绘图1.1 OpenCV关于绘图的操作1.1.1 cv::Point()1.1.2 cv::Scalar()1.1.3 cv::line()画线1.1.4 cv::rectangle()画矩形1.1.5 cv::circle()画圆二、图像的平滑滤波处理2.1 概念2.2 OpenCV关于图像模糊的操作2.2.1 常用滤波器的分类2.2.2 各种滤波方法具…...
[SSD固态硬盘技术 19] 谁是数据的守护神? 盘内RAID1/RAID5图文详解_盘内数据冗余保护
版权声明: 付费作品,禁止转载前言提到冗余保护,最容易想到的就是RAID(Redundant Arrays of Independent Disks) , 独立冗余磁盘阵列。它是一种把多块独立的物理硬盘按不同方式组合形成一个硬盘组,以此提供比单个硬盘更高的存储性能…...
linux相对于windows环境为啥相对来说更加具有安全性
linux相对于windows环境为啥相对来说更加具有安全性 文章目录linux相对于windows环境为啥相对来说更加具有安全性前言一、linux不需要防病毒软件1.1Linux 桌面的恶意软件很少见1.2Linux 的软件安装更安全1.3Linux 保护自己免受恶意软件的侵害1.4杀毒效果存疑1.5Linux 良好的安全…...
iOS开发笔记之九十七——关于Restful API的一些总结
*****阅读完此文,大概需要3分钟******一、什么是 Restful API?Restful(Representational State Transfer表现层状态转换)是目前最流行的接口设计规范。Restful API 是一种设计风格(是设计风格而不是标准)&a…...
Linux系统Nginx下载和安装
文章目录golang学习面试网站Linux启动nginx参考Linux启动nginx版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/weixin_36755535/article/details/110…...
交叉编译 acl
交叉编译 acl 概述 访问控制列表(Access Control Lists,ACL)是应用在路由器接口的指令列表。在 Linux 系统中,ACL 用于设定用户针对文件的权限,而不是在交换路由器中用来控制数据访问的功能(类似于防火墙…...
wait/notify方法 等待唤醒机制
线程正在运行,调用这个线程的wait()方法,这个线程就会进入一个集合进行等待(这个集合的线程不会争抢cpu),此时线程的状态就是waiting 当有线程调用notify()方法的时候,就会从集合中挑选一个线程进入到排队队列里面 notifyAll就是…...
c++笔记之构造函数中的default作用
一、 举例: class Student {int ID;std::string sName; };Student s1; Student s2(s1); 在不定义任何构造函数的情况下,Student对象能定义成功,因为编译器会默认为我们设置几个构造函数,多的不说了,就说最简单的两个: (1) Student s1; 这个就是会调用编译器为我们…...
【代码随想录二刷】Day24-回溯-C++
代码随想录二刷Day24 今日任务 理论基础 77.组合 语言:C 理论基础 解决的问题 ① 组合问题:不考虑顺序 ② 切割问题 ③ 子集问题 ④ 排列问题:考虑顺序 ⑤ 棋盘问题:N皇后,解数独回溯法三部曲 ① 回溯函数模板返回…...
Kubernetes中YAML 文件简介
我们在安装 kubernetes 集群的时候使用了一些 YAML 文件来创建相关的资源,但是对 YAML 文件还是非常陌生。所以我们先来简单看一看 YAML 文件是如何工作的,并使用 YAML 文件来定义一个 kubernetes pod,然后再来定义一个 kubernetes deploymen…...
骨传导耳机是怎么发声的,骨传导耳机值得入手嘛
现在市面上除了我们平时比较常见的有线耳机、头戴耳机、真无线耳机,近两年还涌现出了一种有着黑科技之称的特别耳机——骨传导耳机,并且因其在运动场景下的优势过于明显而得到了众多运动爱好者的大力追捧。那么今天我们就来聊聊这款所谓的黑科技骨传导耳…...
会声会影2023官方新功能介绍
深入简单直观的视频编辑!使用 Corel VideoStudio会声会影2023,将您最美好的时刻和生活体验变成令人惊叹的电影,这是一款有趣且直观的视频编辑器,包含高级工具和高级效果。从自定义标题和过渡,到 Mask Creator、Color G…...
vue:pdf.js使用细节/隐藏按钮/设置、获取当前页码/记录阅读进度/切换语言(国际化)
需求描述 在网页中预览pdf时,希望实现3点需求:1、隐藏一些功能按钮(比如下载);2、打开pdf时自动定位到最后浏览的页(记录阅读进度);3、实现国际化(在代码中更改pdf插件使…...
RocketMQ实现延迟队列精确到秒级实现
前言篇:为了节约成本,决定通过自研来改造rocketmq,添加任意时间延迟的延时队列,开源版本的rocketmq只有支持18个等级的延迟时间,其实对于大部分的功能是够用了的,但是以前的项目,全部都是使用了…...
线性数据结构:数组 Array
一、前言数组是数据结构还是数据类型?数组只是个名称,它可以描述一组操作,也可以命名这组操作。数组的数据操作,是通过 idx->val 的方式来处理。它不是具体要求内存上要存储着连续的数据才叫数组,而是说,…...
大数据开发-Hive
1、hive简介 hive是基于Hadoop的一个数据仓库工具,用于分析数据的。可以将结构化数据文件映射为一张数据库表,并提供类SQL查询功能 注:hive-SQL or HQL or类SQL 和标准SQL还是有一点点区别的 本质是SQL转换为MapReduce程序 用途࿱…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
【Ftrace 专栏】Ftrace 参考博文
ftrace、perf、bcc、bpftrace、ply、simple_perf的使用Ftrace 基本用法Linux 利用 ftrace 分析内核调用如何利用ftrace精确跟踪特定进程调度信息使用 ftrace 进行追踪延迟Linux-培训笔记-ftracehttps://www.kernel.org/doc/html/v4.18/trace/events.htmlhttps://blog.csdn.net/…...
