主頁 >  其他 > 分布式協調服務——zookeeper

分布式協調服務——zookeeper

2022-01-05 21:08:56 其他

分布式協調服務——zookeeper

圖片

1 : zookeeper 概述:

1.1 : zookeeper簡介:

zookeeper是一個分布式的, 開源的分布式應用程式協調服務,是對Google的Chubby組件的開源實作,為Hadoop和HBase的運行提供了相應的服務.他是一個為分布式應用提供一致性服務的軟體,提供的功能包括:配置維護(使得集群中的機器可以共享配置資訊中的那些公共的部分);命名服務(是指通過指定的名字來獲取資環或者服務的地址,以及提供者的資訊,利用zookeeper可以很容易的創建一個全域的路徑,而這個路徑就可以作為一個名字,可以指向集群中的機器,提供的服務的地址,遠程物件等);分布式同步(可以使得集群中各個節點具有相同的系統狀態);組服務(通過zookeeper的短暫節點的特征,來監控每個應用程式的上線和下線)等,他是用java語言來撰寫,通過Zab協議來保證節點的一致性,zookeeper的目標就是封裝好復雜容易出錯的關鍵服務,將簡單易用的介面和性能高效,功能穩定的提供給用戶,

1.2:zookeeper的特點:

  1. 最終一致性:客戶端無論連接到哪個server,展示給他的都是同一個視圖,這就是zookeeper的重要特點之一,
  2. 可靠性:zookeeper具有簡單,健壯,良好的性能,如果一條訊息被一臺服務器接收,那么它將會被所有的服務器所接收,
  3. 實時性:zookeeper將保證客戶端將在一個時間間隔范圍內,獲得服務器的更新訊息或者服務器的失敗訊息,但是由于網路延時等原因,zookeeper不能保證兩個客戶端能同時得到剛剛更新的資料,如果需要最新的資料,那么就需要在讀資料之前呼叫syne( )介面,
  4. 等待無關:慢的或者失效的客戶端不得干預快速的客戶端的請求,這就是的每個客戶端都能夠有效的等待,
  5. 原子性:對zookeeper的更新要么全部成功,要么全部失敗,沒有中間狀態,
  6. 順序性:它包括全域有序和偏序兩種,全域有序(服務端)就是如果一臺服務器上訊息A在訊息B之前發送,則在所有server上訊息A都將在訊息B前被發布,偏序(客戶端)是指,如果一個訊息B在訊息A后被同一個發送者發布,A必將排在B前面.

1.3:zookeeper的基本架構

zookeeper服務自身組成一個集群(2n+1個節點,允許哪個節點失效),zookeeper服務具有三個角色,一個是Leader,一個是Follower,一個是Observer,

  • Leader :為客戶端提供讀寫服務,并維護集群狀態,它是由集群選舉所產生的;

  • Follower :為客戶端提供讀寫服務,并定期向 Leader 匯報自己的節點狀態,同時也參與寫操作“過半寫成功”的策略和 Leader 的選舉;

  • Observer :為客戶端提供讀寫服務,并定期向 Leader 匯報自己的節點狀態,但不參與寫操作“過半寫成功”的策略和 Leader 的選舉,因此 Observer 可以在不影響寫性能的情況下提升集群的讀性能,

  • 下圖就是zookeeper的架構圖:
    image-20211211175151511

客戶端(Client)可以選擇連接到zookeeper集群中的每個服務端(server),并且每個服務端的資料完全相同,每個從節點都需要與主節點進行通信,并同步主節點上更新的資料,

對于zookeeper集群來說,zookeeper只要超過一般數量的服務端可用,那么zookeeper整體服務就是可用的,

1.4:zookeeper的作業原理:

zookeeper的核心原理就是原子廣播,該原子廣播就是對zookeeper集群上所有主機資料包,通過這個機制保證了各個服務端之前的資料同步,那么實作這個機制在zookeeper中有一個內部協議(Zab協議),這個協議有兩種模式,一個是恢復模式,一個是廣播模式,

當服務啟動或者是在主節點崩潰之后,Zab協議就進入了恢復模式,當主節點再次被選舉出來,且大多數服務端完成了和主節點的狀態同步之后,恢復模式就結束了,狀態同步保證了主節點和服務端具有相同的系統狀態,一旦主節點已經和多數的從節點(也就是服務節點)進行了狀態同步之后,他就可以開始廣播訊息即進入到了廣播模式,

在廣播模式下,服務端會接收客戶端的請求,所有的寫請求都被轉發給leader,再有leader將更新廣播給follower節點,當半數以上的follower完成資料寫請求之后,leader才會提交這個更新,然后客戶端才會收到一個更新成功的回應,

2:zookeeper安裝配置:

Zookeeper集群搭建指的是ZooKeeper分布式模式安裝,通常由2n+1臺server組成,這是因為為了保證Leader選舉(基于Paxos演算法的實作)能過得到多數的支持,所以ZooKeeper集群的數量一般為奇數,

Zookeeper運行需要java環境,所以需要提前安裝jdk,對于安裝leader+follower模式的集群,大致程序如下:

  • 配置主機名稱到IP地址映射配置
  • 修改ZooKeeper組態檔
  • 遠程復制分發安裝檔案
  • 設定myid
  • 啟動ZooKeeper集群

如果要想使用Observer模式,可在對應節點的組態檔添加如下配置:

peerType=observer

其次,必須在組態檔指定哪些節點被指定為Observer,如:

server.1:node1:2181:3181:observer

這里,我們安裝的是leader+follower模式

主機規劃:

服務器IP主機名myid的值
192.168.88.161node11
192.168.88.162node22
192.168.88.163node33

地址規劃:

軟體名地址
zookeeper-3.4.6.tar.gz/export/softwate
zookeeper-3.4.6/export/servers
zookeeper資料路徑/export/servers/zookeeper-3.4.6/zkdatas

2.1:第一步:下載zookeeeper的壓縮包,

下載網址如下http://archive.apache.org/dist/zookeeper/

我們在這個網址下載我們使用的zk版本為3.4.6

下載完成之后,上傳到我們的linux的/export/software路徑下準備進行安裝

2.2:第二步:解壓

在node1主機上,解壓zookeeper的壓縮包到/export/server路徑下去,然后準備進行安裝

tar -zxvf zookeeper-3.4.6.tar.gz -C /export/servers/

3. 第三步:修改組態檔

在node1主機上,修改組態檔

cd /export/servers/zookeeper-3.4.6/conf/
cp zoo_sample.cfg  zoo.cfg
vi zoo.cfg

修改以下內容

# The number of milliseconds of each tick
# 這個時間是zookeeper服務器之間或者服務器與客戶端之間維持心跳的時間機制
tickTime=2000

# The number of ticks that the initial 
# synchronization phase can take
# 配置zookeeper接收客戶端初始化連接時最長能忍受多少個心跳時間間隔數
initLimit=10

# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
# leader和follower之間發送訊息,請求和應答時間長度
syncLimit=5

# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
# 資料目錄,需要提前創建
dataDir=/export/servers/zookeeper-3.4.6/zkdatas

# 日志目錄,也需要提前創建
dataLogDir=/export/servers/zookeeper-3.4.6/zkLogs

# the port at which the clients will connect
# 訪問埠號
clientPort=2181

# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
# 在dataDir中保留快照的數量
autopurge.snapRetainCount=3

# Purge task interval in hours
# Set to "0" to disable auto purge feature
# 設定清除任務間隔
autopurge.purgeInterval=1

# zookeeper cluster properties

# 設定每個節點上的服務
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888

4. 第四步:添加myid配置

在node1主機的/export/server/zookeeper-3.4.6/zkdatas/這個路徑下創建一個檔案,檔案名為myid ,檔案內容為1

echo 1 > /export/servers/zookeeper-3.4.6/zkdatas/myid

5. 第五步:安裝包分發并修改myid的值

在node1主機上,將安裝包分發到其他機器

第一臺機器上面執行以下兩個命令

scp -r /export/servers/zookeeper-3.4.6 node2:$PWD
scp -r /export/servers/zookeeper-3.4.6 node3:$PWD

第二臺機器上修改myid的值為2

echo 2 > /export/servers/zookeeper-3.4.6/zkdatas/myid

第三臺機器上修改myid的值為3

echo 3 > /export/servers/zookeeper-3.4.6/zkdatas/myid

6. 第六步:三臺機器啟動zookeeper服務

三臺機器分別啟動zookeeper服務

這個命令三臺機器都要執行

/export/servers/zookeeper-3.4.6/bin/zkServer.sh start

三臺主機分別查看啟動狀態

/export/servers/zookeeper-3.4.6/bin/zkServer.sh  status

image-20211212115525120
在這里插入圖片描述image-20211212115621726

3:zookeeper資料模型:

zookeeper維護這一個樹狀層次結構,樹中的節點被稱之為znode,znode可以用來存盤資料,并且有一個與之相關聯的ACL(Access Control List:訪問控制串列,用于控制資源的訪問權限),zookeeper被設計用來實作協調服務(通常使用小資料檔案),而不適用于大容量資料存盤,因此一個znode能存盤的資料被限制在1MB以內,znode的樹狀結構如下圖所示:

在這里插入圖片描述

圖中的每個節點稱為一個Znode, 每個Znode由3部分組成:
ZooKeeper的資料模型,在結構上和標準檔案系統的非常相似,擁有一個層次的命名空間,都是采用樹形層次結構,ZooKeeper樹中的每個節點被稱為—Znode,和檔案系統的目錄樹一樣,ZooKeeper樹中的每個節點可以擁有子節點,但也有不同之處:

  1. Znode兼具檔案和目錄兩種特點,既像檔案一樣維護著資料、元資訊、ACL、時間戳等資料結構,又像目錄一樣可以作為路徑標識的一部分,并可以具有子znode,用戶對znode具有增、刪、改、查等操作(權限允許的情況下),

  2. Znode具有原子性操作,讀操作將獲取與節點相關的所有資料,寫操作也將替換掉節點的所有資料,另外,每一個節點都擁有自己的ACL(訪問控制串列),這個串列規定了用戶的權限,即限定了特定用戶對目標節點可以執行的操作,

  3. Znode存盤資料大小有限制,ZooKeeper雖然可以關聯一些資料,但并沒有被設計為常規的資料庫或者大資料存盤,相反的是,它用來管理調度資料,比如分布式應用中的組態檔資訊、狀態資訊、匯集位置等等,這些資料的共同特性就是它們都是很小的資料,通常以KB為大小單位,ZooKeeper的服務器和客戶端都被設計為嚴格檢查并限制每個Znode的資料大小至多1M,當時常規使用中應該遠小于此值,

  4. Znode通過路徑參考,如同Unix中的檔案路徑,路徑必須是絕對的,因此他們必須由斜杠字符來開頭,除此以外,他們必須是唯一的,也就是說每一個路徑只有一個表示,因此這些路徑不能改變,在ZooKeeper中,路徑由Unicode字串組成,并且有一些限制,字串"/zookeeper"用以保存管理資訊,比如關鍵配額資訊,
    ① stat:此為狀態資訊, 描述該Znode的版本, 權限等資訊
    ② data:與該Znode關聯的資料
    ③ children:該Znode下的子節點

    znode是客戶端訪問的zookeeper的主要物體,

4、Zookeeper節點型別:

Znode有兩種,分別為臨時節點和永久節點,

節點的型別在創建時即被確定,并且不能改變,

  • 臨時節點:該節點的生命周期依賴于創建它們的會話,一旦會話結束,臨時節點將被自動洗掉,當然可以也可以手動洗掉,臨時節點不允許擁有子節點,
  • 永久節點:該節點的生命周期不依賴于會話,并且只有在客戶端顯示執行洗掉操作的時候,他們才能被洗掉,

Znode還有一個序列化的特性,如果創建的時候指定的話,該Znode的名字后面會自動追加一個不斷增加的序列號,序列號對于此節點的父節點來說是唯一的,這樣便會記錄每個子節點創建的先后順序,它的格式為“%10d”(10位數字,沒有數值的數位用0補充,例如“0000000001”),

image-20211211193910307
這樣便會存在四種型別的Znode節點,分別對應:
PERSISTENT:永久節點
EPHEMERAL:臨時節點
PERSISTENT_SEQUENTIAL:永久節點、序列化
EPHEMERAL_SEQUENTIAL:臨時節點、序列化

5:zookeeper Watcher (監聽機制)

ZooKeeper提供了分布式資料發布/訂閱功能,一個典型的發布/訂閱模型系統定義了一種一對多的訂閱關系,能讓多個訂閱者同時監聽某一個主題物件,當這個主題物件自身狀態變化時,會通知所有訂閱者,使他們能夠做出相應的處理,

ZooKeeper中,引入了Watcher機制來實作這種分布式的通知功能,ZooKeeper允許客戶端向服務端注冊一個Watcher監聽,當服務端的一些事件觸發了這個Watcher,那么就會向指定客戶端發送一個事件通知來實作分布式的通知功能,

觸發事件種類很多,如:節點創建,節點洗掉,節點改變,子節點改變等,

總的來說可以概括Watcher為以下三個程序:客戶端向服務端注冊Watcher、服務端事件發生觸發Watcher、客戶端回呼Watcher得到觸發事件情況

1) Watch機制特點

一次性觸發

事件發生觸發監聽,一個watcher event就會被發送到設定監聽的客戶端,這種效果是一次性的,后續再次發生同樣的事件,不會再次觸發,

事件封裝

ZooKeeper使用WatchedEvent物件來封裝服務端事件并傳遞,

WatchedEvent包含了每一個事件的三個基本屬性:
通知狀態(keeperState),事件型別(EventType)和節點路徑(path)
event 異步發送
watcher的通知事件從服務端發送到客戶端是異步的,

先注冊再觸發

Zookeeper中的watch機制,必須客戶端先去服務端注冊監聽,這樣事件發送才會觸發監聽,通知給客戶端,

2) 通知狀態和事件型別

同一個事件型別在不同的通知狀態中代表的含義有所不同,下表列舉了常見的通知狀態和事件型別,

事件封裝: Watcher 得到的事件是被封裝過的, 包括三個內容 keeperState, eventType, path

KeeperState (通知狀態)EventType (事件型別)觸發條件說明
None連接成功
SyncConnectedNodeCreatedZnode被創建此時處于連接狀態
SyncConnectedNodeDeletedZnode被洗掉此時處于連接狀態
SyncConnectedNodeDataChangedZnode資料被改變此時處于連接狀態
SyncConnectedNodeChildChangedZnode的子Znode資料被改變此時處于連接狀態
DisconnectedNone客戶端和服務端斷開連接此時客戶端和服務器處于斷開連接狀態
ExpiredNone會話超時會收到一個SessionExpiredExceptio
AuthFailedNone權限驗證失敗會收到一個AuthFailedException

其中連接狀態事件(type=None, path=null)不需要客戶端注冊,客戶端只要有需要直接處理就行了,

3) Shell 客戶端設定watcher

設定節點資料變動監聽:
image-20211212141708944
通過另一個客戶端更改節點資料:
image-20211212141721071
此時設定監聽的節點收到通知:
在這里插入圖片描述

6、ZooKeeper的shell操作

1. 客戶端連接

運行 zkCli.sh –server ip 進入命令列工具,

cd /export/servers/zookeeper-3.4.6/bin
./zkCli.sh -server node1:2181  

2. shell基本操作

1) 創建節點:

格式:

 create [-s][-e] path data acl

其中,-s 表示創建一個序列化節點

? -e 表示創建一個臨時節點

? 啥也不加表示創建了一個永久節點

? acl:權限控制

創建永久節點:

create /aaa 123456

創建臨時節點

create -e /linshijiedian 123456

創建永久序列化節點

create -s /abc 123

創建臨時序列化節點

create -s -e /fff 123345

2) 讀取節點

與讀取相關的命令有 ls 命令和 get 命令,ls和ls2 命令可以列出 Zookeeper 指定節點下的所有子節點,只能查看指定節點下的第一級的所有子節點;get 命令可以獲取 Zookeeper 指定節點的資料內容和屬性資訊,

格式:

ls path [watch]
get path [watch]
ls2 path [watch]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-RcgLN6PI-1641199684803)(http://www.honghuboyuan.top//image-20211212141158612.png)]

dataVersion:資料版本號,每次對節點進行set操作,dataVersion的值都會增加1(即使設定的是相同的資料),可有效避免了資料更新時出現的先后順序問題,

cversion :子節點的版本號,當znode的子節點有變化時,cversion 的值就會增加1,

cZxid :Znode創建的事務id,

mZxid :Znode被修改的事務id,即每次對znode的修改都會更新mZxid,

對于zk來說,每次的變化都會產生一個唯一的事務id,zxid(ZooKeeper Transaction Id),通過zxid,可以確定更新操作的先后順序,例如,如果zxid1小于zxid2,說明zxid1操作先于zxid2發生,zxid對于整個zk都是唯一的,即使操作的是不同的znode,

ctime:節點創建時的時間戳.

mtime:節點最新一次更新發生時的時間戳.

ephemeralOwner:如果該節點為臨時節點, ephemeralOwner值表示與該節點系結的session id. 如果不是, ephemeralOwner值為0.

在client和server通信之前,首先需要建立連接,該連接稱為session,連接建立后,如果發生連接超時、授權失敗,或者顯式關閉連接,連接便處于CLOSED狀態, 此時session結束,

3) 更新索引

格式:

set path data [version]

data 就是要更新的新內容,version 表示資料版本

image-20211212143238620

4) 洗掉節點

格式:

 delete path [version]

若洗掉節點存在子節點,那么無法洗掉該節點,必須先洗掉子節點,再洗掉父節點

rmr path: 可以遞回洗掉節點,

5) 對節點進行限制: quota

格式1:

setquota -n|-b val path

-n:表示子節點的最大個數

-b:表示資料值的最大長度

val:子節點最大個數或資料值的最大長度

path:節點路徑

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-vhGovpl9-1641199684806)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20211212143643334.png)]

格式2: listquota path : 列出指定節點的 quota

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-deOayTfA-1641199684808)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20211212143652474.png)]
子節點個數為 2,資料長度-1 表示沒限制

注意: 在實際操作的時候, 雖然設定了最大的節點數后,依然可以在整個節點下添加多個子節點, 只是會在zookeeper中的日志檔案中記錄一下警告資訊[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-UEvy8xOK-1641199684810)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20211212143708410.png)]
格式3: delquota [-n|-b] path : 洗掉 quota

6) 其他命令:

history: 列出命令歷史
在這里插入圖片描述
redo:該命令可以重新執行指定命令編號的歷史命令,命令編號可以通過

7、ZooKeeper Java API操作

這里操作Zookeeper的JavaAPI使用的是一套zookeeper客戶端框架 Curator ,解決了很多Zookeeper客戶端非常底層的細節開發作業 ,

Curator包含了幾個包:

curator-framework:對zookeeper的底層api的一些封裝

curator-recipes:封裝了一些高級特性,如:Cache事件監聽、選舉、分布式鎖、分布式計數器等

Maven依賴(使用curator的版本:2.12.0,對應Zookeeper的版本為:3.4.x,如果跨版本會有兼容性問題,很有可能導致節點操作失敗):

1. 引入maven坐標

<dependencies>
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.12.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.12.0</version>
        </dependency>

        <dependency>
            <groupId>com.google.collections</groupId>
            <artifactId>google-collections</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.25</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- java編譯插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

java 操作zookeeper的相關操作:

package com.lixufei.zookeeper;


import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.junit.Test;

/**
 * @Author lixufei
 * @Date 2021/12/12 15:03
 * @Version 1.0
 */
public class ZookeeperTest{

    /**
     * 使用java操縱zookeeper,創建節點
     */
    @Test
    public void createZnode() throws Exception {
        // 創建java操作zookeeper的客戶端物件
        String connectString = "192.168.88.161:2181,192.168.88.162:2181,192.168.88.163:2181";
        ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework zookeeperClient = CuratorFrameworkFactory.newClient(connectString, retryPolicy);

        // 啟動客戶端
        zookeeperClient.start();

        // 執行相關的操作
        /**
         * CreateMode.PERSISTENT:永久節點
         * CreateMode.PERSISTENT_SEQUENTIAL:永久序列化節點
         * CreateMode.EPHEMERAL:臨時節點
         * CreateMode.EPHEMERAL_SEQUENTIAL:臨時序列化節點
         */
        zookeeperClient.create().withMode(CreateMode.PERSISTENT).forPath("/test04","123456".getBytes());

        // 釋放資源
        zookeeperClient.close();
    }

    /**
     * 使用java操縱zookeeper,修改節點
     */
    @Test
    public void updataZnode() throws Exception {
        // 創建java操作zookeeper的客戶端物件
        String connectString = "192.168.88.161:2181,192.168.88.162:2181,192.168.88.163:2181";
        ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework zookeeperClient = CuratorFrameworkFactory.newClient(connectString, retryPolicy);

        // 啟動客戶端
        zookeeperClient.start();

        // 執行相關的操作
        zookeeperClient.setData().forPath("/test03","lixufei123456".getBytes());

        // 釋放資源
        zookeeperClient.close();
    }

    /**
     * 使用java操縱zookeeper,洗掉節點
     */
    @Test
    public void deleteZnode() throws Exception {
        // 創建java操作zookeeper的客戶端物件
        String connectString = "192.168.88.161:2181,192.168.88.162:2181,192.168.88.163:2181";
        ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework zookeeperClient = CuratorFrameworkFactory.newClient(connectString, retryPolicy);
        // 啟動客戶端
        zookeeperClient.start();

        // 執行相關的操作
        zookeeperClient.delete().forPath("/test04");

        // 釋放資源
        zookeeperClient.close();
    }

    /**
     * 使用java操縱zookeeper,查詢節點
     */
    @Test
    public void selectZnode() throws Exception {
        // 創建java操作zookeeper的客戶端物件
        String connectString = "192.168.88.161:2181,192.168.88.162:2181,192.168.88.163:2181";
        ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework zookeeperClient = CuratorFrameworkFactory.newClient(connectString, retryPolicy);
        // 啟動客戶端
        zookeeperClient.start();

        // 執行相關的操作
        byte[] bytes = zookeeperClient.getData().forPath("/test03");
        System.out.println(new String(bytes));
        // 釋放資源
        zookeeperClient.close();
    }
}

8、ZooKeeper選舉機制

zookeeper默認的演算法是FastLeaderElection,采用投票數大于半數則勝出的邏輯,

1. 概念

服務器ID

比如有三臺服務器,編號分別是1,2,3,

編號越大在選擇演算法中的權重越大,

選舉狀態

LOOKING,競選狀態,

FOLLOWING,隨從狀態,同步leader狀態,參與投票,

OBSERVING,觀察狀態,同步leader狀態,不參與投票,

LEADING,領導者狀態,

資料ID

服務器中存放的最新資料version,

值越大說明資料越新,在選舉演算法中資料越新權重越大,

邏輯時鐘

也叫投票的次數,同一輪投票程序中的邏輯時鐘值是相同的,每投完一次票這個資料就會增加,然后與接收到的其它服務器回傳的投票資訊中的數值相比,根據不同的值做出不同的判斷,

2. 全新集群選舉

假設目前有5臺服務器,每臺服務器均沒有資料,它們的編號分別是1,2,3,4,5,按編號依次啟動,它們的選擇舉程序如下:

服務器1啟動自己,給投票,然后發投票資訊,由于其它機器還沒有啟動所以它收不到反饋資訊,服務器1的狀態一直屬于Looking,

服務器2啟動,給自己投票,同時與之前啟動的服務器1交換結果,由于服務器2的編號大所以服務器2勝出,但此時投票數沒有大于半數,所以兩個服務器的狀態依然是LOOKING,

服務器3啟動,給自己投票,同時與之前啟動的服務器1,2交換資訊,由于服務器3的編號最大所以服務器3勝出,此時投票數正好大于半數,所以服務器3成為領導者,服務器1,2成為小弟,

服務器4啟動,給自己投票,同時與之前啟動的服務器1,2,3交換資訊,盡管服務器4的編號大,但之前服務器3已經勝出,所以服務器4只能成為小弟,

服務器5啟動,后面的邏輯同服務器4成為小弟,

3. 非全新集群選舉

對于運行正常的zookeeper集群,中途有機器down掉,需要重新選舉時,選舉程序就需要加入資料ID、服務器ID和邏輯時鐘,

資料ID:資料新的version就大,資料每次更新都會更新version,

服務器ID:就是我們配置的myid中的值,每個機器一個,

邏輯時鐘:這個值從0開始遞增,每次選舉對應一個值, 如果在同一次選舉中,這個值是一致的,

這樣選舉的標準就變成:

? 1、邏輯時鐘小的選舉結果被忽略,重新投票;

? 2、統一邏輯時鐘后,資料id大的勝出;

? 3、資料id相同的情況下,服務器id大的勝出;

根據這個規則選出leader,

9、ZAB協議

4.1 ZAB協議與資料一致性

ZAB 協議是 Zookeeper 專門設計的一種支持崩潰恢復的原子廣播協議,通過該協議,Zookeepe 基于主從模式的系統架構來保持集群中各個副本之間資料的一致性,具體如下:

Zookeeper 使用一個單一的主行程來接收并處理客戶端的所有事務請求,并采用原子廣播協議將資料狀態的變更以事務 Proposal 的形式廣播到所有的副本行程上去,如下圖:

具體流程如下:

所有的事務請求必須由唯一的 Leader 服務來處理,Leader 服務將事務請求轉換為事務 Proposal,并將該 Proposal 分發給集群中所有的 Follower 服務,如果有半數的 Follower 服務進行了正確的反饋,那么 Leader 就會再次向所有的 Follower 發出 Commit 訊息,要求將前一個 Proposal 進行提交,

4.2 ZAB協議的內容

ZAB 協議包括兩種基本的模式,分別是崩潰恢復和訊息廣播:

1. 崩潰恢復

當整個服務框架在啟動程序中,或者當 Leader 服務器出現例外時,ZAB 協議就會進入恢復模式,通過過半選舉機制產生新的 Leader,之后其他機器將從新的 Leader 上同步狀態,當有過半機器完成狀態同步后,就退出恢復模式,進入訊息廣播模式,

2. 訊息廣播

ZAB 協議的訊息廣播程序使用的是原子廣播協議,在整個訊息的廣播程序中,Leader 服務器會每個事物請求生成對應的 Proposal,并為其分配一個全域唯一的遞增的事務 ID(ZXID),之后再對其進行廣播,具體程序如下:

Leader 服務會為每一個 Follower 服務器分配一個單獨的佇列,然后將事務 Proposal 依次放入佇列中,并根據 FIFO(先進先出) 的策略進行訊息發送,Follower 服務在接收到 Proposal 后,會將其以事務日志的形式寫入本地磁盤中,并在寫入成功后反饋給 Leader 一個 Ack 回應,當 Leader 接收到超過半數 Follower 的 Ack 回應后,就會廣播一個 Commit 訊息給所有的 Follower 以通知其進行事務提交,之后 Leader 自身也會完成對事務的提交,而每一個 Follower 則在接收到 Commit 訊息后,完成事務的提交,

10、Zookeeper的典型應用場景

5.1資料的發布/訂閱

資料的發布/訂閱系統,通常也用作配置中心,在分布式系統中,你可能有成千上萬個服務節點,如果想要對所有服務的某項配置進行更改,由于資料節點過多,你不可逐臺進行修改,而應該在設計時采用統一的配置中心,之后發布者只需要將新的配置發送到配置中心,所有服務節點即可自動下載并進行更新,從而實作配置的集中管理和動態更新,

Zookeeper 通過 Watcher 機制可以實作資料的發布和訂閱,分布式系統的所有的服務節點可以對某個 ZNode 注冊監聽,之后只需要將新的配置寫入該 ZNode,所有服務節點都會收到該事件,

5.2 命名服務

在分布式系統中,通常需要一個全域唯一的名字,如生成全域唯一的訂單號等,Zookeeper 可以通過順序節點的特性來生成全域唯一 ID,從而可以對分布式系統提供命名服務,

5.3 Master選舉

分布式系統一個重要的模式就是主從模式 (Master/Salves),Zookeeper 可以用于該模式下的 Matser 選舉,可以讓所有服務節點去競爭性地創建同一個 ZNode,由于 Zookeeper 不能有路徑相同的 ZNode,必然只有一個服務節點能夠創建成功,這樣該服務節點就可以成為 Master 節點,

5.4 分布式鎖

可以通過 Zookeeper 的臨時節點和 Watcher 機制來實作分布式鎖,這里以排它鎖為例進行說明:

分布式系統的所有服務節點可以競爭性地去創建同一個臨時 ZNode,由于 Zookeeper 不能有路徑相同的 ZNode,必然只有一個服務節點能夠創建成功,此時可以認為該節點獲得了鎖,其他沒有獲得鎖的服務節點通過在該 ZNode 上注冊監聽,從而當鎖釋放時再去競爭獲得鎖,鎖的釋放情況有以下兩種:

  • 當正常執行完業務邏輯后,客戶端主動將臨時 ZNode 洗掉,此時鎖被釋放;
  • 當獲得鎖的客戶端發生宕機時,臨時 ZNode 會被自動洗掉,此時認為鎖已經釋放,

當鎖被釋放后,其他服務節點則再次去競爭性地進行創建,但每次都只有一個服務節點能夠獲取到鎖,這就是排他鎖,

5.5 集群管理

Zookeeper 還能解決大多數分布式系統中的問題:

  • 如可以通過創建臨時節點來建立心跳檢測機制,如果分布式系統的某個服務節點宕機了,則其持有的會話會超時,此時該臨時節點會被洗掉,相應的監聽事件就會被觸發,
  • 分布式系統的每個服務節點還可以將自己的節點狀態寫入臨時節點,從而完成狀態報告或節點作業進度匯報,
  • 通過資料的訂閱和發布功能,Zookeeper 還能對分布式系統進行模塊的解耦和任務的調度,
  • 通過監聽機制,還能對分布式系統的服務節點進行動態上下線,從而實作服務的動態擴容,

11:Zookeeper ACL

1:前言:

為了避免存盤在 Zookeeper 上的資料被其他程式或者人為誤修改,Zookeeper 提供了 ACL(Access Control Lists) 進行權限控制,只有擁有對應權限的用戶才可以對節點進行增刪改查等操作,下文分別介紹使用原生的 Shell 命令和 Apache Curator 客戶端進行權限設定,

二、使用Shell進行權限管理

2.1 設定與查看權限

想要給某個節點設定權限 (ACL),有以下兩個可選的命令:

 # 1.給已有節點賦予權限
 setAcl path acl
 
 # 2.在創建節點時候指定權限
 create [-s] [-e] path data acl

查看指定節點的權限命令如下:

getAcl path

2.2 權限組成

Zookeeper 的權限由[scheme : id :permissions]三部分組成,其中 Schemes 和 Permissions 內置的可選項分別如下:

Permissions 可選項

  • CREATE:允許創建子節點;
  • READ:允許從節點獲取資料并列出其子節點;
  • WRITE:允許為節點設定資料;
  • DELETE:允許洗掉子節點;
  • ADMIN:允許為節點設定權限,

Schemes 可選項

  • world:默認模式,所有客戶端都擁有指定的權限,world 下只有一個 id 選項,就是 anyone,通常組合寫法為 world:anyone:[permissons]
  • auth:只有經過認證的用戶才擁有指定的權限,通常組合寫法為 auth:user:password:[permissons],使用這種模式時,你需要先進行登錄,之后采用 auth 模式設定權限時,userpassword 都將使用登錄的用戶名和密碼;
  • digest:只有經過認證的用戶才擁有指定的權限,通常組合寫法為 auth:user:BASE64(SHA1(password)):[permissons],這種形式下的密碼必須通過 SHA1 和 BASE64 進行雙重加密;
  • ip:限制只有特定 IP 的客戶端才擁有指定的權限,通常組成寫法為 ip:182.168.0.168:[permissions]
  • super:代表超級管理員,擁有所有的權限,需要修改 Zookeeper 啟動腳本進行配置,

2.3 添加認證資訊

可以使用如下所示的命令為當前 Session 添加用戶認證資訊,等價于登錄操作,

# 格式
addauth scheme auth 

#示例:添加用戶名為heibai,密碼為root的用戶認證資訊
addauth digest heibai:root 

2.4 權限設定示例

1. world模式

world 是一種默認的模式,即創建時如果不指定權限,則默認的權限就是 world,

[zk: localhost:2181(CONNECTED) 32] create /hadoop 123
Created /hadoop
[zk: localhost:2181(CONNECTED) 33] getAcl /hadoop
'world,'anyone    #默認的權限
: cdrwa
[zk: localhost:2181(CONNECTED) 34] setAcl /hadoop world:anyone:cwda   # 修改節點,不允許所有客戶端讀
....
[zk: localhost:2181(CONNECTED) 35] get /hadoop
Authentication is not valid : /hadoop     # 權限不足

2. auth模式
[zk: localhost:2181(CONNECTED) 36] addauth digest heibai:heibai  # 登錄
[zk: localhost:2181(CONNECTED) 37] setAcl /hadoop auth::cdrwa    # 設定權限
[zk: localhost:2181(CONNECTED) 38] getAcl /hadoop                # 獲取權限
'digest,'heibai:sCxtVJ1gPG8UW/jzFHR0A1ZKY5s=   #用戶名和密碼 (密碼經過加密處理),注意回傳的權限型別是 digest
: cdrwa

#用戶名和密碼都是使用登錄的用戶名和密碼,即使你在創建權限時候進行指定也是無效的
[zk: localhost:2181(CONNECTED) 39] setAcl /hadoop auth:root:root:cdrwa    #指定用戶名和密碼為 root
[zk: localhost:2181(CONNECTED) 40] getAcl /hadoop
'digest,'heibai:sCxtVJ1gPG8UW/jzFHR0A1ZKY5s=  #無效,使用的用戶名和密碼依然還是 heibai
: cdrwa

3. digest模式
[zk:44] create /spark "spark" digest:heibai:sCxtVJ1gPG8UW/jzFHR0A1ZKY5s=:cdrwa  #指定用戶名和加密后的密碼
[zk:45] getAcl /spark  #獲取權限
'digest,'heibai:sCxtVJ1gPG8UW/jzFHR0A1ZKY5s=   # 回傳的權限型別是 digest
: cdrwa

到這里你可以發現使用 auth 模式設定的權限和使用 digest 模式設定的權限,在最終結果上,得到的權限模式都是 digest,某種程度上,你可以把 auth 模式理解成是 digest 模式的一種簡便實作,因為在 digest 模式下,每次設定都需要書寫用戶名和加密后的密碼,這是比較繁瑣的,采用 auth 模式就可以避免這種麻煩,

4. ip模式

限定只有特定的 ip 才能訪問,

[zk: localhost:2181(CONNECTED) 46] create  /hive "hive" ip:192.168.0.108:cdrwa  
[zk: localhost:2181(CONNECTED) 47] get /hive
Authentication is not valid : /hive  # 當前主機已經不能訪問

這里可以看到當前主機已經不能訪問,想要能夠再次訪問,可以使用對應 IP 的客戶端,或使用下面介紹的 super 模式,

5. super模式

需要修改啟動腳本 zkServer.sh,并在指定位置添加超級管理員賬戶和密碼資訊:

"-Dzookeeper.DigestAuthenticationProvider.superDigest=heibai:sCxtVJ1gPG8UW/jzFHR0A1ZKY5s=" 

在這里插入圖片描述
修改完成后需要使用 zkServer.sh restart 重啟服務,此時再次訪問限制 IP 的節點:

[zk: localhost:2181(CONNECTED) 0] get /hive  #訪問受限
Authentication is not valid : /hive
[zk: localhost:2181(CONNECTED) 1] addauth digest heibai:heibai  # 登錄 (添加認證資訊)
[zk: localhost:2181(CONNECTED) 2] get /hive  #成功訪問
hive
cZxid = 0x158
ctime = Sat May 25 09:11:29 CST 2019
mZxid = 0x158
mtime = Sat May 25 09:11:29 CST 2019
pZxid = 0x158
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0

三、使用Java客戶端進行權限管理

3.1 主要依賴

這里以 Apache Curator 為例,使用前需要匯入相關依賴,完整依賴如下:

<dependencies>
    <!--Apache Curator 相關依賴-->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>4.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>4.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
        <version>3.4.13</version>
    </dependency>
    <!--單元測驗相關依賴-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

3.2 權限管理API

Apache Curator 權限設定的示例如下:

public class AclOperation {

    private CuratorFramework client = null;
    private static final String zkServerPath = "192.168.0.226:2181";
    private static final String nodePath = "/hadoop/hdfs";

    @Before
    public void prepare() {
        RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
        client = CuratorFrameworkFactory.builder()
                .authorization("digest", "heibai:123456".getBytes()) //等價于 addauth 命令
                .connectString(zkServerPath)
                .sessionTimeoutMs(10000).retryPolicy(retryPolicy)
                .namespace("workspace").build();
        client.start();
    }

    /**
     * 新建節點并賦予權限
     */
    @Test
    public void createNodesWithAcl() throws Exception {
        List<ACL> aclList = new ArrayList<>();
        // 對密碼進行加密
        String digest1 = DigestAuthenticationProvider.generateDigest("heibai:123456");
        String digest2 = DigestAuthenticationProvider.generateDigest("ying:123456");
        Id user01 = new Id("digest", digest1);
        Id user02 = new Id("digest", digest2);
        // 指定所有權限
        aclList.add(new ACL(Perms.ALL, user01));
        // 如果想要指定權限的組合,中間需要使用 | ,這里的|代表的是位運算中的 按位或
        aclList.add(new ACL(Perms.DELETE | Perms.CREATE, user02));

        // 創建節點
        byte[] data = "abc".getBytes();
        client.create().creatingParentsIfNeeded()
                .withMode(CreateMode.PERSISTENT)
                .withACL(aclList, true)
                .forPath(nodePath, data);
    }


    /**
     * 給已有節點設定權限,注意這會洗掉所有原來節點上已有的權限設定
     */
    @Test
    public void SetAcl() throws Exception {
        String digest = DigestAuthenticationProvider.generateDigest("admin:admin");
        Id user = new Id("digest", digest);
        client.setACL()
                .withACL(Collections.singletonList(new ACL(Perms.READ | Perms.DELETE, user)))
                .forPath(nodePath);
    }

    /**
     * 獲取權限
     */
    @Test
    public void getAcl() throws Exception {
        List<ACL> aclList = client.getACL().forPath(nodePath);
        ACL acl = aclList.get(0);
        System.out.println(acl.getId().getId() 
                           + "是否有刪讀權限:" + (acl.getPerms() == (Perms.READ | Perms.DELETE)));
    }

    @After
    public void destroy() {
        if (client != null) {
            client.close();
        }
    }
}

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

標籤:其他

上一篇:jdk1.8安裝教程,跟著步驟來 安裝失敗你來打我

下一篇:Kimball維度建模

標籤雲
其他(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