主頁 >  其他 > 超詳細講解Kafka消費者,讓你看完就懂!(概念、訊息接收)

超詳細講解Kafka消費者,讓你看完就懂!(概念、訊息接收)

2020-12-11 12:01:11 其他

目錄

  • 第1章 消費者詳解
    • 1.1 概念入門
      • 1.1.1 消費者和消費組
    • 1.2 訊息接收
      • 1.2.1 必要引數設定
      • 1.2.2 訂閱主題和磁區
      • 1.2.2 反序列化
      • 1.2.3 位移提交
      • 1.2.4 指定位移消費
      • 1.2.4 再均衡監聽器
      • 1.2.5 消費者攔截器
      • 1.2.6 消費者引數補充
    • 總結

第1章 消費者詳解

tips 學完這一章你可以、
深入學習Kafka資料消費大致流程
如何創建并使用Kafka消費者
Kafka消費者常用配置

1.1 概念入門

1.1.1 消費者和消費組

Kafka消費者是消費組的一部分,當多個消費者形成一個消費組來消費主題時,每個消費者會收到不同磁區的訊息,假設有一個T1主題,該主題有4個磁區;同時我們有一個消費組G1,這個消費組只有一個消費者C1,那么消費者C1將會收到這4個磁區的訊息,如下所示:
在這里插入圖片描述

Kafka一個很重要的特性就是,只需寫入一次訊息,可以支持任意多的應用讀取這個訊息,換句話說,每個應用都可以讀到全量的訊息,為了使得每個應用都能讀到全量訊息,應用需要有不同的消費組,對于上面的例子,假如我們新增了一個新的消費組G2,而這個消費組有兩個消費者,那么會是這樣的:
在這里插入圖片描述

1.2 訊息接收

見代碼庫:com.heima.kafka.chapter3.KafkaConsumerAnalysis

1.2.1 必要引數設定

KafkaConsumer實體中引數眾多,后續會深入講解
public static Properties initConfig() { 
Properties props = new Properties(); 
// 與KafkaProducer中設定保持一致 
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); 
// 必填引數,該引數和KafkaProducer中的相同,制定連接Kafka集群所需的broker地址清 單,可以設定一個或者多個 
props.put("bootstrap.servers", brokerList); 
// 消費者隸屬于的消費組,默認為空,如果設定為空,則會拋出例外,這個引數要設定成具有一 定業務含義的名稱 
props.put("group.id", groupId); 
// 指定KafkaConsumer對應的客戶端ID,默認為空,如果不設定KafkaConsumer會自動生成 一個非空字串 
props.put("client.id", "consumer.client.id.demo"); 
return props; 
}

1.2.2 訂閱主題和磁區

創建完消費者后我們便可以訂閱主題了,只需要通過呼叫subscribe()方法即可,這個方法接收一個主題串列

KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); 
consumer.subscribe(Arrays.asList(topic));

另外,我們也可以使用正則運算式來匹配多個主題,而且訂閱之后如果又有匹配的新主題,那么這個消費組會立即對其進行消費,正則運算式在連接Kafka與其他系統時非常有用,比如訂閱所有的測驗主題:

consumer.subscribe(Pattern.compile("heima*"));

指定訂閱的磁區

// 指定訂閱的磁區 
consumer.assign(Arrays.asList(new TopicPartition("topic0701", 0)));

1.2.2 反序列化

// 與KafkaProducer中設定保持一致 
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); 
// 必填引數,

1.2.3 位移提交

對于Kafka中的磁區而言,它的每條訊息都有唯一的offset,用來表示訊息在磁區中的位置,當我們呼叫poll()時,該方法會回傳我們沒有消費的訊息,當訊息從broker回傳消費者時,broker并不跟蹤這些訊息是否被消費者接收到;Kafka讓消費者自身來管理消費的位移,并向消費者提供更新位移的介面,這種更新位移方式稱為提交(commit),

重復消費
在這里插入圖片描述

訊息丟失
在這里插入圖片描述

自動提交
這種方式讓消費者來管理位移,應用本身不需要顯式操作,當我們將enable.auto.commit設定為true,
那么消費者會在poll方法呼叫后每隔5秒(由auto.commit.interval.ms指定)提交一次位移,和很多其他操作一樣,自動提交也是由poll()方法來驅動的;在呼叫poll()時,消費者判斷是否到達提交時間,如果是則提交上一次poll回傳的最大位移,

需要注意到,這種方式可能會導致訊息重復消費,假如,某個消費者poll訊息后,應用正在處理訊息,在3秒后Kafka進行了重平衡,那么由于沒有更新位移導致重平衡后這部分訊息重復消費,

同步提交

見代碼庫:com.heima.kafka.chapter3.CheckOffsetAndCommit

public static Properties initConfig() { 
Properties props = new Properties(); props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, brokerList); props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); 
// 手動提交開啟 props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false); return props; 
}
while (true) {
ConsumerRecords<String, String> records = consumer.poll(1000); 
if (records.isEmpty()) { 
break; 
}
List<ConsumerRecord<String, String>> partitionRecords = records.records(tp); 
lastConsumedOffset = partitionRecords.get(partitionRecords.size() - 1).offset();
consumer.commitSync();//同步提交消費位移 }

異步提交
手動提交有一個缺點,那就是當發起提交呼叫時應用會阻塞,當然我們可以減少手動提交的頻率,但這個會增加訊息重復的概率(和自動提交一樣),另外一個解決辦法是,使用異步提交的API,

見代碼:com.heima.kafka.chapter3.OffsetCommitAsyncCallback

但是異步提交也有個缺點,那就是如果服務器回傳提交失敗,異步提交不會進行重試,相比較起來,同步提交會進行重試直到成功或者最后拋出例外給應用,異步提交沒有實作重試是因為,如果同時存在多個異步提交,進行重試可能會導致位移覆寫,舉個例子,假如我們發起了一個異步提commitA,此時的提交位移為2000,隨后又發起了一個異步提交commitB且位移3000;commitA提交失敗但commitB提交成功,此時commitA進行重試并成功的話,會將實際上將已經提交的位移從3000回滾到2000,導致訊息重復消費,

異步回呼

try { 
while (running.get()) { 
ConsumerRecords<String, String> records = consumer.poll(1000); 
for (ConsumerRecord<String, String> record : records) { 
//do some logical processing. 
}
// 異步回呼 
consumer.commitAsync(new OffsetCommitCallback() { 
@Override 
public void onComplete(Map<TopicPartition, 
OffsetAndMetadata> offsets, 
Exception exception) {
if(exception==null){
System.out.println(offsets);
}else {log.error("fail to commit offsets {}", offsets, 
exception);
}
}
});
}
} finally {
consumer.close();
}

1.2.4 指定位移消費

到目前為止,我們知道訊息的拉取是根據poll()方法中的邏輯來處理的,但是這個方法對于普通開發人
員來說就是個黑盒處理,無法精確掌握其消費的起始位置,
seek()方法正好提供了這個功能,讓我們得以追蹤以前的消費或者回溯消費,
見代碼庫:com.heima.kafka.chapter3.SeekDemo

/*** 
指定位移消費 
*/ 
public class SeekDemo extends ConsumerClientConfig { 
public static void main(String[] args) { 
Properties props = initConfig(); 
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); consumer.subscribe(Arrays.asList(topic)); 
// timeout引數設定多少合適?太短會使磁區分配失敗,太長又有可能造成一些不必要的等待 
consumer.poll(Duration.ofMillis(2000)); 
// 獲取消費者所分配到的磁區 
Set<TopicPartition> assignment = consumer.assignment(); System.out.println(assignment); 
for (TopicPartition tp : assignment) { 
// 引數partition表示磁區,offset表示指定從磁區的哪個位置開始消費
 consumer.seek(tp, 10); 
} 
// consumer.seek(new TopicPartition(topic,0),10); 
while (true) { 
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000)); 
//consume the record. 
for (ConsumerRecord<String, String> record : records) { System.out.println(record.offset() + ":" + record.value()); 
} 
} 
}

增加判斷是否分配到了磁區,見代碼庫:com.heima.kafka.chapter3.SeekDemoAssignment

public static void main(String[] args) { 
Properties props = initConfig();
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); 
consumer.subscribe(Arrays.asList(topic)); 
long start = System.currentTimeMillis(); 
Set<TopicPartition> assignment = new HashSet<>(); 
while (assignment.size() == 0) { 
consumer.poll(Duration.ofMillis(100));
 assignment = consumer.assignment(); 
 }long end = System.currentTimeMillis(); 
 System.out.println(end - start); 
 System.out.println(assignment); 
 for (TopicPartition tp : assignment) { 
 consumer.seek(tp, 10); 
 }
 while (true) { 
 ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000)); 
 //consume the record.
 for (ConsumerRecord<String, String> record : records) { System.out.println(record.offset() + ":" + record.value()); 
 } 
 } 
 }
  • 指定從磁區末尾開始消費 ,見代碼庫:com.heima.kafka.chapter3.SeekToEnd
// 指定從磁區末尾開始消費 
Map<TopicPartition, Long> offsets = consumer.endOffsets(assignment); 
for (TopicPartition tp : assignment) { 
consumer.seek(tp, offsets.get(tp));
 }
  • 演示位移越界操作,修改代碼如下:
for (TopicPartition tp : assignment) { 
//consumer.seek(tp, offsets.get(tp)); 
consumer.seek(tp, offsets.get(tp) + 1); 
}

會通過auto.offset.reset引數的默認值將位置重置,效果如下:

INFO [Consumer clientId=consumer-1, groupId=group.heima] Fetch offset 1 is out 
of range for partition heima-0, resetting offset 
(org.apache.kafka.clients.consumer.internals.Fetcher:967) 
INFO [Consumer clientId=consumer-1, groupId=group.heima] Fetch offset 10 is out 
of range for partition heima-1, resetting offset
(org.apache.kafka.clients.consumer.internals.Fetcher:967) 
INFO [Consumer clientId=consumer-1, groupId=group.heima] Resetting offset for
partition heima-0 to offset 0. 
(org.apache.kafka.clients.consumer.internals.Fetcher:583) 
INFO [Consumer clientId=consumer-1, groupId=group.heima] Resetting offset for 
partition heima-1 to offset 9. 
(org.apache.kafka.clients.consumer.internals.Fetcher:583)

1.2.4 再均衡監聽器

再均衡是指磁區的所屬從一個消費者轉移到另外一個消費者的行為,它為消費組具備了高可用性和伸縮性提供了保障,使得我們既方便又安全地洗掉消費組內的消費者或者往消費組內添加消費者,不過再均衡發生期間,消費者是無法拉取訊息的,
見代碼庫:com.heima.kafka.chapter3.CommitSyncInRebalance

public static void main(String[] args) { 
Properties props = initConfig(); 
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); 
Map<TopicPartition, OffsetAndMetadata> currentOffsets = new HashMap<>(); 
consumer.subscribe(Arrays.asList(topic),newConsumerRebalanceListener() { 
@Override 
public void onPartitionsRevoked(Collection<TopicPartition> 
partitions) { 
// 勁量避免重復消費 
consumer.commitSync(currentOffsets); 
}@Override 
public void onPartitionsAssigned(Collection<TopicPartition> partitions) { 
//do nothing. 
}
 }); 
 try {
 while (isRunning.get()) { 
 ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000)); 
 for (ConsumerRecord<String, String> record : records) { System.out.println(record.offset() + ":" + record.value()); 
 // 異步提交消費位移,在發生再均衡動作之前可以通過再均衡監聽器的 onPartitionsRevoked回呼執行commitSync方法同步提交位移, currentOffsets.put(new TopicPartition(record.topic(), 
 record.partition()), 
 new OffsetAndMetadata(record.offset() + 1)); }consumer.commitAsync(currentOffsets, null); 
 }
 } finally { 
 consumer.close(); }
  }

1.2.5 消費者攔截器

之前章節講了生產者攔截器,對應的消費者也有相應的攔截器概念,消費者攔截器主要是在消費到訊息或者在提交消費位移時進行的一些定制化的操作,

使用場景
對消費訊息設定一個有效期的屬性,如果某條訊息在既定的時間視窗內無法到達,那就視為無效,不需要再被處理,
見代碼庫:com.heima.kafka.chapter3.ConsumerInterceptorTTL

public ConsumerRecords<String, String> onConsume(ConsumerRecords<String, String> 
records) {
System.out.println("before:" + records); 
long now = System.currentTimeMillis(); 
Map<TopicPartition, List<ConsumerRecord<String, String>>> newRecords = new HashMap<>(); 
for (TopicPartition tp : records.partitions()) { 
List<ConsumerRecord<String, String>> tpRecords = 
records.records(tp); 
List<ConsumerRecord<String, String>> newTpRecords = new ArrayList<> (); 
for (ConsumerRecord<String, String> record : tpRecords) { 
if (now - record.timestamp() < EXPIRE_INTERVAL) { newTpRecords.add(record); 
}
 }
 if (!newTpRecords.isEmpty()) { 
 newRecords.put(tp, newTpRecords); 
 } 
 }
 return new ConsumerRecords<>(newRecords);
  }

實作自定義攔截器之后,需要在KafkaConsumer中配置指定這個攔截器,如下

// 指定消費者攔截器 props.put(ConsumerConfig.INTERCEPTOR_CLASSES_CONFIG,ConsumerInterceptorTTL.class .getName());

效果演示
發送端同時發送兩條訊息,其中一條修改timestamp的值來使其變得超時,如下:
com.heima.kafka.chapter3.ProducerFastStart

ProducerRecord<String, String> record = new ProducerRecord<>(topic, "Kafka-demo- 
001", "hello, Kafka!"); ProducerRecord<String, String> 
record2 = new ProducerRecord<>(topic, 0, System.currentTimeMillis() - 10 * 1000, 
"Kafka-demo-001", "hello, Kafka!->超時");

啟動消費端運行如下,只收到了未超時的訊息:
在這里插入圖片描述

1.2.6 消費者引數補充

fetch.min.bytes
這個引數允許消費者指定從broker讀取訊息時最小的資料量,當消費者從broker讀取訊息時,如果資料量小于這個閾值,broker會等待直到有足夠的資料,然后才回傳給消費者,對于寫入量不高的主題來說,這個引數可以減少broker和消費者的壓力,因為減少了往返的時間,而對于有大量消費者的主題來說,則可以明顯減輕broker壓力,

fetch.max.wait.ms
上面的fetch.min.bytes引數指定了消費者讀取的最小資料量,而這個引數則指定了消費者讀取時最長等待時間,從而避免長時間阻塞,這個引數默認為500ms,

max.partition.fetch.bytes
這個引數指定了每個磁區回傳的最多位元組數,默認為1M,也就是說,KafkaConsumer.poll()回傳記錄串列時,每個磁區的記錄位元組數最多為1M,如果一個主題有20個磁區,同時有5個消費者,那么每個消費者需要4M的空間來處理訊息,實際情況中,我們需要設定更多的空間,這樣當存在消費者宕機時,其他消費者可以承擔更多的磁區.

max.poll.records
這個引數控制一個poll()呼叫回傳的記錄數,這個可以用來控制應用在拉取回圈中的處理資料量,

總結

本章主要講解了消費者和消費組的概念,以及如何正確的使用KafkaConsumer,其中重點講解了引數的配置,訂閱、反序列化、位移提交、再均衡、攔截器等知識點,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/233113.html

標籤:其他

上一篇:win10安裝CAD+CASS程序中出現的錯誤問題及解決辦法集錦

下一篇:遺傳演算法詳解與改良遺傳演算法

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more