dubbo如何設(shè)置連接zookeeper權(quán)限
前言
最近自己的技術(shù)棧項(xiàng)目,再升級(jí)dubbo為2.7.5,zookeeper為3.5.6,curator-recipes升級(jí)為4.2.0的時(shí)候一直出現(xiàn)zookeeper not connected和Connection lost for ***的錯(cuò)誤。
之前未升級(jí)前還是好的...隨手查看報(bào)錯(cuò)源碼信息并百度,終于再stackflow上面找到原因。
設(shè)置環(huán)境參數(shù)ZKClientConfig.ENABLE_CLIENT_SASL_KEY=false,默認(rèn)未true
System.setProperty(ZKClientConfig.ENABLE_CLIENT_SASL_KEY,Constant.IS_FALSE.toString());
大概意思是zookeeper作為外部應(yīng)用需要向系統(tǒng)申請(qǐng)資源,申請(qǐng)資源的時(shí)候需要通過(guò)認(rèn)證,而sasl是一種認(rèn)證方式,添加以上那一句來(lái)繞過(guò)sasl認(rèn)證。避免等待,來(lái)提高效率。
隨后繼續(xù)深進(jìn),了解到zookeeper的sasl認(rèn)證相關(guān)(試了下,效果不大好,可能我姿勢(shì)不大對(duì)? 這里就不介紹zk的sasl介紹和相關(guān)配置了,有興趣的可以自行百度),并附加的深入學(xué)習(xí)了zk的ACL 權(quán)限,以及dubbo以zk未注冊(cè)中心的,權(quán)限認(rèn)證!下面開始相關(guān)介紹。
zookeeper設(shè)置ACL權(quán)限
查閱dubbo的官方文檔dubbo-registry發(fā)現(xiàn)連接注冊(cè)中心的時(shí)候是可以選擇是否需要用戶名密碼,接下來(lái)就是要如何設(shè)置zookeeper的用戶名跟密碼

進(jìn)入zookeeper的bin文件夾運(yùn)行客戶端
./zkCli.sh
help 查看指令
[zk: localhost:2181(CONNECTED) 0] help
ZooKeeper -server host:port cmd args
stat path [watch]
set path data [version]
ls path [watch]
delquota [-n|-b] path
ls2 path [watch]
setAcl path acl
setquota -n|-b val path
history
redo cmdno
printwatches on|off
delete path [version]
sync path
listquota path
rmr path
get path [watch]
create [-s] [-e] path data acl
addauth scheme auth
quit
getAcl path
close
connect host:port如果在dubbo中沒有指定分組的話,dubbo會(huì)默認(rèn)生成一個(gè)分組dubbo,也就是在zookeeper下面會(huì)有個(gè)子節(jié)點(diǎn)dubbo
也可以自己手動(dòng)創(chuàng)建
create /dubbo
Zookeeper的ACL通過(guò)scheme:username:password:permissions來(lái)構(gòu)成權(quán)限
scheme這邊主要用到2種方式,另外還有設(shè)置ip和host,這幾個(gè)沒用到的這邊就先不細(xì)說(shuō)
1.auth方式(密碼明文)
添加用戶名和密碼
addauth digest admin:13871500871
授予/dubbo auth權(quán)限
setAcl /dubbo auth:admin:13871500871:rwadc
配置dubbo連接zookeeper配置文件
<dubbo:registry protocol ="zookeeper" address="127.0.0.1:2181" username="admin" password="13871500871" client="curator" />
2.digest授權(quán)方式(方式跟auth差不多)
授予/dubbo digest權(quán)限
addauth digest admin:jI+oJfxCaWyh/3Zw/r+fwhbZVRY=
setAcl /dubbo digest:admin:jI+oJfxCaWyh/3Zw/r+fwhbZVRY=:cdrwa
配置zookeeper配置文件
<dubbo:registry protocol ="zookeeper" address="127.0.0.1:2181" username="admin" password="13871500871" client="curator" />
digest 密碼生成方式:把密碼進(jìn)行sha1編碼然后對(duì)結(jié)果進(jìn)行base64編碼
BASE64(SHA1(password))
查看zookeeper源碼發(fā)現(xiàn),其實(shí)包里面已經(jīng)有現(xiàn)成的方法,直接調(diào)用這個(gè)類生成就行,
idPassword字符串格式:username:password
org.apache.zookeeper.server.auth.DigestAuthenticationProvider
static public String generateDigest(String idPassword) throws NoSuchAlgorithmException {
String parts[] = idPassword.split(":", 2);
byte digest[] = MessageDigest.getInstance("SHA1").digest(
idPassword.getBytes());
return parts[0] + ":" + base64Encode(digest);
}還有一個(gè)點(diǎn)就是要設(shè)置client="curator"
通過(guò)ZookeeperRegistry發(fā)現(xiàn)zookeeper的連接是通過(guò)zookeeperTransporter進(jìn)行創(chuàng)建,
zookeeperTransporter接口分別由CuratorZookeeperTransporterZkclientZookeeperTransporter實(shí)現(xiàn),這2個(gè)分別創(chuàng)建
CuratorZookeeperClient和ZkclientZookeeperClient
public class ZkclientZookeeperTransporter implements ZookeeperTransporter {
public ZookeeperClient connect(URL url) {
return new ZkclientZookeeperClient(url);
}
}public class CuratorZookeeperTransporter implements ZookeeperTransporter {
public ZookeeperClient connect(URL url) {
return new CuratorZookeeperClient(url);
}
}查看源碼發(fā)現(xiàn)ZkclientZookeeperClient是沒有進(jìn)行設(shè)置zookeeper的auth的賬號(hào)和密碼,
CuratorZookeeperClient有去獲取配置的相關(guān)用戶信息。
public ZkclientZookeeperClient(URL url) {
super(url);
client = new ZkClient(url.getBackupAddress());
client.subscribeStateChanges(new IZkStateListener() {
public void handleStateChanged(KeeperState state) throws Exception {
ZkclientZookeeperClient.this.state = state;
if (state == KeeperState.Disconnected) {
stateChanged(StateListener.DISCONNECTED);
} else if (state == KeeperState.SyncConnected) {
stateChanged(StateListener.CONNECTED);
}
}
public void handleNewSession() throws Exception {
stateChanged(StateListener.RECONNECTED);
}
});
} public CuratorZookeeperClient(URL url) {
super(url);
try {
Builder builder = CuratorFrameworkFactory.builder()
.connectString(url.getBackupAddress())
.retryPolicy(new RetryNTimes(Integer.MAX_VALUE, 1000))
.connectionTimeoutMs(5000);
String authority = url.getAuthority();
if (authority != null && authority.length() > 0) {
builder = builder.authorization("digest", authority.getBytes());
}
client = builder.build();
client.getConnectionStateListenable().addListener(new ConnectionStateListener() {
public void stateChanged(CuratorFramework client, ConnectionState state) {
if (state == ConnectionState.LOST) {
CuratorZookeeperClient.this.stateChanged(StateListener.DISCONNECTED);
} else if (state == ConnectionState.CONNECTED) {
CuratorZookeeperClient.this.stateChanged(StateListener.CONNECTED);
} else if (state == ConnectionState.RECONNECTED) {
CuratorZookeeperClient.this.stateChanged(StateListener.RECONNECTED);
}
}
});
client.start();
} catch (IOException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}cdrwa表示zookeeper的五種權(quán)限
CREATE: 創(chuàng)建子節(jié)點(diǎn)READ: 獲取節(jié)點(diǎn)數(shù)據(jù)或者當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)列表WRITE: 節(jié)點(diǎn)設(shè)置數(shù)據(jù)DELETE: 刪除子節(jié)點(diǎn)ADMIN: 節(jié)點(diǎn)設(shè)置權(quán)限
如果用戶名密碼錯(cuò)誤,或者沒設(shè)置,會(huì)報(bào)KeeperErrorCode = NoAuth錯(cuò)誤
注:停止zookeeper,清除zookeeper文件夾下面的logs,或者用delete 刪除節(jié)點(diǎn) 就可以清除權(quán)限
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java使用java -jar啟動(dòng)并按日分包日志的最佳實(shí)踐
在生產(chǎn)環(huán)境中,Java應(yīng)用程序通常以java -jar方式運(yùn)行,而日志管理是運(yùn)維的重要部分,如果日志文件過(guò)大,不僅影響性能,還會(huì)增加排查問(wèn)題的難度,因此,按日分包日志成為常見的需求,本文將介紹4種實(shí)現(xiàn)方式,并提供詳細(xì)配置和代碼示例,需要的朋友可以參考下2025-07-07
spring配置文件解析失敗報(bào)”cvc-elt.1: 找不到元素 ''''beans'''' 的聲明”異常解決
這篇文章主要給大家介紹了關(guān)于spring配置文件解析失敗報(bào)”cvc-elt.1: 找不到元素 'beans' 的聲明”異常的解決方法,需要的朋友可以參考下2020-08-08
Java實(shí)現(xiàn)滑動(dòng)驗(yàn)證碼(前端部分)
這篇文章主要為大家介紹了如何用Java語(yǔ)言實(shí)現(xiàn)滑動(dòng)驗(yàn)證碼的生成(前端部分),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下2022-10-10
SpringBoot多環(huán)境開發(fā)該如何配置
這篇文章主要介紹了 SpringBoot多環(huán)境的開發(fā)配置詳情,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09
Java Socket實(shí)現(xiàn)傳輸壓縮對(duì)象的方法示例
這篇文章主要介紹了Java Socket實(shí)現(xiàn)傳輸壓縮對(duì)象的方法,結(jié)合具體實(shí)例形式分析了java socket針對(duì)數(shù)據(jù)的壓縮、傳輸、接收、解壓縮等操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-06-06
java基于servlet實(shí)現(xiàn)文件上傳功能
Java concurrency之AtomicLongFieldUpdater原子類_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
Java實(shí)現(xiàn)的簡(jiǎn)單音樂播放器功能示例

