Java中dubbo+zookeeper微服務(wù)架構(gòu)簡(jiǎn)介
1、Apache Dubbo概述
1.1、Dubbo簡(jiǎn)介
**Apache Dubbo **是一款高性能的 Java RPC
框架。其前身是阿里巴巴公司開(kāi)源的、輕量級(jí)的開(kāi)源 Java RPC
框架,可以和 Spring
框架無(wú)縫集成,2018年阿里巴巴把這個(gè)框架捐獻(xiàn)給了apache基金,此框架的使用比 Spring Cloud
微服務(wù)的框架使用較為簡(jiǎn)單,只需要表寫相應(yīng)的服務(wù)提供和服務(wù)消費(fèi)的代碼即可,中央服務(wù)配置可由 ZooKeeper
進(jìn)行服務(wù)的注冊(cè)管理,只需要相應(yīng)的服務(wù)進(jìn)行配置注冊(cè),服務(wù)消費(fèi)進(jìn)行接口的抓取即可完成服務(wù)的遠(yuǎn)程調(diào)用。
- 什么是RPC? RPC全稱為remote procedure call,即遠(yuǎn)程過(guò)程調(diào)用。比如兩臺(tái)服務(wù)器A和B,A服務(wù)器上部署一個(gè)應(yīng)用,B服務(wù)器上部署一個(gè)應(yīng)用,A服務(wù)器上的應(yīng)用想調(diào)用B服務(wù)器上的應(yīng)用提供的方法,由于兩個(gè)應(yīng)用不在一個(gè)內(nèi)存空間,不能直接調(diào)用,所以需要通過(guò)網(wǎng)絡(luò)來(lái)表達(dá)調(diào)用的語(yǔ)義和傳達(dá)調(diào)用的數(shù)據(jù)。 需要注意的是 RPC 并不是一個(gè)具體的技術(shù),而是指整個(gè)網(wǎng)絡(luò)遠(yuǎn)程調(diào)用過(guò)程。
- RPC是一個(gè)泛化的概念,嚴(yán)格來(lái)說(shuō)一切遠(yuǎn)程過(guò)程調(diào)用手段都屬于 RPC范 疇。各種開(kāi)發(fā)語(yǔ)言都有自己的RPC框架。Java中的RPC框架比較多,廣泛使用的有
RMI
、Hessian
、Dubbo
等。 - Dubbo官網(wǎng)地址:http://dubbo.apache.org ,詳情可進(jìn)行直接的訪問(wèn)查看信息。
- Dubbo提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯(cuò)和負(fù)載均衡,以及服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn)。
1.2、Dubbo的服務(wù)架構(gòu)
Dubbo的服務(wù)架構(gòu)圖如下所示:
各節(jié)點(diǎn)角色說(shuō)明:
節(jié)點(diǎn)名 | 功能 |
---|---|
提供者 | 暴露接口的提供方 |
容器 | 整個(gè)服務(wù)運(yùn)行時(shí)的容器 |
注冊(cè) | 服務(wù)注冊(cè)與發(fā)現(xiàn)的注冊(cè)中心 |
消費(fèi)者 | 調(diào)用遠(yuǎn)程服務(wù)的消費(fèi)方 |
監(jiān)控 | 統(tǒng)計(jì)服務(wù)調(diào)用次數(shù)調(diào)用時(shí)間的監(jiān)控中心 |
服務(wù)的執(zhí)行步驟:
- 服務(wù)容器負(fù)責(zé)啟動(dòng),加載,運(yùn)行服務(wù)的接口提供者。
- 服務(wù)提供者在啟動(dòng)時(shí),向注冊(cè)中心注冊(cè)自己提供的服務(wù),也就是注冊(cè)自己的接口地址。
- 服務(wù)消費(fèi)者在啟動(dòng)時(shí),向注冊(cè)中心訂閱自己所需的服務(wù),通過(guò)代理的方式直接定位到需要的接口實(shí)現(xiàn)對(duì)象,但是需要注意的是消費(fèi)者必須有該接口才能進(jìn)行代理。
- 注冊(cè)中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更,注冊(cè)中心將基于長(zhǎng)連接推送變更數(shù)據(jù)給消費(fèi)者。 4
- 服務(wù)消費(fèi)者,從提供者地址列表中,基于軟負(fù)載均衡算法,選一臺(tái)提供者進(jìn)行調(diào)用,如果調(diào)用失敗,再選另一臺(tái)調(diào)用。
- 服務(wù)消費(fèi)者和提供者,在內(nèi)存中累計(jì)調(diào)用次數(shù)和調(diào)用時(shí)間,定時(shí)每分鐘發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心。
2、服務(wù)注冊(cè)中心 Zookeeper
通過(guò)前面的 Dubbo架構(gòu)圖 可以看到,Registry
(服務(wù)注冊(cè)中心)在整個(gè)架構(gòu)中起著至關(guān)重要的作用。Dubbo官方推薦使用 Zookeeper 作為服務(wù)注冊(cè)中心,下面詳細(xì)講一下 Zookeeper 在服務(wù)器中的安裝以及相應(yīng)的服務(wù)注冊(cè)和拉取配置。
2.1、ZooKeeper介紹
Zookeeper 是 Apache Hadoop 的子項(xiàng)目,是一個(gè)樹(shù)型的目錄服務(wù),支持變更推送,適合作為 Dubbo 服務(wù)的注冊(cè)中心,工業(yè)強(qiáng)度較高,可用于生產(chǎn)環(huán)境,并推薦使用。
流程說(shuō)明:
- 服務(wù)提供者(Provider)啟動(dòng)時(shí): 向 /dubbo/com.test.UserServiceBo/providers 目錄下寫入自己的 URL 地址
- 服務(wù)消費(fèi)者(Consumer)啟動(dòng)時(shí): 訂閱 /dubbo/com.test.UserServiceBo/providers 目錄下的提供者 URL 地址。并向 /dubbo/com.test.UserServiceBo/consumers 目錄下寫入自己的 URL 地址
- 監(jiān)控中心(Monitor)啟動(dòng)時(shí): 訂閱 /dubbo/com.test.UserServiceBo 目錄下的所有提供者和消費(fèi)者 URL 地址
2.2、ZooKeeper安裝
下載地址:http://archive.apache.org/dist/zookeeper/ 下載完成后 zookeeper-3.4.6.tar.gz
的壓縮文 件。
安裝步驟:
- 第一步:需要有安裝 JDK 的環(huán)境。
- 第二步:把
zookeeper
的壓縮包上傳到 linux 系統(tǒng)。 - 第三步:解壓縮壓縮包 tar -zxvf zookeeper-3.4.6.tar.gz -C /usr 路徑可以隨便定義。
- 第四步:進(jìn)入
zookeeper-3.4.6
目錄,創(chuàng)建data
目錄,用于數(shù)據(jù)的存儲(chǔ)。 - 第五步:進(jìn)入
conf
目錄 ,把zoo_sample.cfg
改名為zoo.cfg
,用于配置相關(guān)的數(shù)據(jù)信息,也是啟動(dòng)的配置文件。
2.3、啟動(dòng) ZooKeeper
進(jìn)入 Zookeeper
的 bin 目錄,執(zhí)行相應(yīng)的文件即可。
- 啟動(dòng)服務(wù)命令: ./zkServer.sh start
- 停止服務(wù)命令: ./zkServer.sh stop
- 查看服務(wù)狀態(tài): ./zkServer.sh status
- 客戶端連接: ./zkCli.sh
3、ZooKeeper快速入門
Dubbo 作為一個(gè)RPC框架,其最核心的功能就是要實(shí)現(xiàn)跨網(wǎng)絡(luò)的遠(yuǎn)程調(diào)用。本小節(jié)就是要?jiǎng)?chuàng)建兩個(gè)應(yīng)用,一個(gè)作為服務(wù)的提供方,一個(gè)作為服務(wù)的消費(fèi)方。通過(guò)Dubbo來(lái)實(shí)現(xiàn)服務(wù)消費(fèi)方遠(yuǎn)程調(diào)用服務(wù)提供方的方法。
3.1、服務(wù)提供方
創(chuàng)建一個(gè)簡(jiǎn)單的 web 項(xiàng)目作為服務(wù)的提供者(由maven進(jìn)行管理)。
添加依賴:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.beordie</groupId> <artifactId>dubbo-normal</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>5.0.5.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <!-- dubbo相關(guān) --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.0</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.7</version> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.12.1.GA</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
配置 web.xml 文件
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
創(chuàng)建服務(wù)接口
package com.beordie.service; /** * @Description * @Date 2021/9/2 16:08 * @Created 30500 */ public interface ServiceTest { public String get(String name); }
創(chuàng)建服務(wù)實(shí)現(xiàn)類
package com.beordie.service.impl; import com.alibaba.dubbo.config.annotation.Service; import com.beordie.service.ServiceTest; /** * @Description * @Date 2021/9/2 16:09 * @Created 30500 */ @Service public class serviceImpl implements ServiceTest { @Override public String get(String name) { return "你好" + name; } }
注意
:服務(wù)實(shí)現(xiàn)類上使用的 Service
注解是 Dubbo 提供的,用于對(duì)外發(fā)布服務(wù) 。
創(chuàng)建web.xml 中指定的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 當(dāng)前應(yīng)用名稱,用于注冊(cè)中心計(jì)算應(yīng)用間依賴關(guān)系,注意:消費(fèi)者和提供者應(yīng)用名不要一樣 --> <dubbo:application name="provider"/> <!-- 連接服務(wù)注冊(cè)中心zookeeper ip為zookeeper所在服務(wù)器的ip地址--> <dubbo:registry address="zookeeper://192.168.55.129:2181"/> <!-- 注冊(cè) 協(xié)議和port --> <dubbo:protocol name="dubbo" port="20881"></dubbo:protocol> <!-- 掃描指定包,加入@Service注解的類會(huì)被發(fā)布為服務(wù) --> <dubbo:annotation package="com.beordie.service.impl" /> </beans>
啟動(dòng)服務(wù)并在 ZooKeeper 中進(jìn)行服務(wù)查看
啟動(dòng)完服務(wù)后通過(guò)打開(kāi)客戶端的命令打開(kāi) ZooKeeper
的客戶端,然后通過(guò)指令 ls /
可查看到當(dāng)前目錄下的文件信息,會(huì)發(fā)現(xiàn)存在一個(gè) Dubbo
的文件目錄,繼續(xù)對(duì)此目錄進(jìn)行查看即可發(fā)現(xiàn)相應(yīng)的服務(wù)注冊(cè)信息。
|
3.2、服務(wù)消費(fèi)方
同樣需要?jiǎng)?chuàng)建一個(gè)項(xiàng)目來(lái)進(jìn)行服務(wù)的拉取,引入的依賴和提供方的類似,這里就直接復(fù)制即可。
配置 web.xml 文件
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定加載的配置文件 ,通過(guò)參數(shù)contextConfigLocation加載 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-web.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
創(chuàng)建和提供方一致的服務(wù)接口
可以直接對(duì)接口進(jìn)行復(fù)制,因?yàn)橹蟮姆?wù)抓取是通過(guò)動(dòng)態(tài)代理的方式進(jìn)行對(duì)象生成的,因此需要對(duì)應(yīng)的接口對(duì)象。
編寫Controlle對(duì)外暴露訪問(wèn)接口
package com.beordie.controller; import com.alibaba.dubbo.config.annotation.Reference; import com.beordie.service.ServiceTest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * @Description * @Date 2021/9/2 17:05 * @Created 30500 */ @Controller @RequestMapping("/demo") public class TeController { // Dubbo 的遠(yuǎn)程對(duì)象注入 @Reference private ServiceTest serviceTest; @RequestMapping("/hello") @ResponseBody public String getName(String name){ //遠(yuǎn)程調(diào)用 String result = serviceTest.get(name); System.out.println(result); return result; } }
創(chuàng)建對(duì)應(yīng)的啟動(dòng)配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 當(dāng)前應(yīng)用名稱,用于注冊(cè)中心計(jì)算應(yīng)用間依賴關(guān)系,注意:消費(fèi)者和提供者應(yīng)用名不要一樣 --> <dubbo:application name="dubbo-consumer"/> <!-- 連接服務(wù)注冊(cè)中心zookeeper ip為zookeeper所在服務(wù)器的ip地址--> <dubbo:registry address="zookeeper://192.168.55.129:2181"/> <!-- 掃描的方式暴露接口 --> <dubbo:annotation package="com.beordie.controller"/> </beans>
運(yùn)行測(cè)試
設(shè)置完畢后啟動(dòng)項(xiàng)目,然后訪問(wèn)相應(yīng)地址,即可抓取到正確的服務(wù)結(jié)果。
3.3、問(wèn)題思考
- 思考一:上面的Dubbo入門案例中我們是將HelloService接口從服務(wù)提供者工程 (dubbo_provider)復(fù)制到服務(wù)消費(fèi)者工程(dubbo_consumer)中,這種做法是否合適?還有沒(méi)有更好的方式?
答
:這種做法顯然是不好的,同一個(gè)接口被復(fù)制了兩份,不利于后期維護(hù)。更好的方式是單獨(dú)創(chuàng)建一個(gè) maven工程,將此接口創(chuàng)建在這個(gè)maven工程中。需要依賴此接口的工程只需要在自己工程的 pom.xml文件中引入maven坐標(biāo)即可。- 思考二:在服務(wù)消費(fèi)者工程(dubbo_consumer)中只是引用了接口,并沒(méi)有提供實(shí)現(xiàn)類,Dubbo是如何做到遠(yuǎn)程調(diào)用的?
答
:Dubbo底層是基于代理技術(shù)為接口創(chuàng)建代理對(duì)象,遠(yuǎn)程調(diào)用是通過(guò)此代理對(duì)象完成的??梢酝ㄟ^(guò)開(kāi)發(fā)工具的debug功能查看此代理對(duì)象的內(nèi)部結(jié)構(gòu)。另外,Dubbo實(shí)現(xiàn)網(wǎng)絡(luò)傳輸?shù)讓邮腔贜etty框架完成的。- 思考三:上面的Dubbo入門案例中我們使用Zookeeper作為服務(wù)注冊(cè)中心,服務(wù)提供者需要將自己的服務(wù)信息注冊(cè)到Zookeeper,服務(wù)消費(fèi)者需要從Zookeeper訂閱自己所需要的服務(wù),此時(shí)Zookeeper服務(wù)就變得非常重要了,那如何防止Zookeeper單點(diǎn)故障呢?
答
:Zookeeper其實(shí)是支持集群模式的,可以配置Zookeeper集群來(lái)達(dá)到Zookeeper服務(wù)的高可用,防 止出現(xiàn)單點(diǎn)故障。
4、 Dubbo管理控制臺(tái)
我們?cè)陂_(kāi)發(fā)時(shí),需要知道 Zookeeper 注冊(cè)中心都注冊(cè)了哪些服務(wù),有哪些消費(fèi)者來(lái)消費(fèi)這些服務(wù)。我們可以通過(guò)部署一個(gè)管理中心來(lái)實(shí)現(xiàn)。其實(shí)管理中心就是一個(gè)web應(yīng)用,部署到tomcat即可。
4.1、安裝
只需要下載對(duì)應(yīng)的 war 到本地的tomcat,然后啟動(dòng)服務(wù)即可。
需要修改WEB-INF下的dubbo.properties文件,注意dubbo.registry.address對(duì)應(yīng)的值需要對(duì)應(yīng)當(dāng)前使用的Zookeeper的ip地址和端口號(hào) dubbo.registry.address=zookeeper://192.168.55.129:2181 4.2、使用
訪問(wèn) http://localhost:8080/dubbo-admin-2.6.0/,輸入用戶名(root)和密碼(root) 即可查看網(wǎng)站,相關(guān)的服務(wù)信息都可以在這里進(jìn)行查看。
5、 Dubbo相關(guān)配置
5.1、包掃描
<dubbo:annotation package="com.beordie.service" />
服務(wù)提供者和服務(wù)消費(fèi)者都需要配置,表示包掃描,作用是掃描指定包(包括子包)下的類,提供者掃描服務(wù)所在的包,消費(fèi)者掃描控制器所在的包。
如果不使用包掃描,也可以通過(guò)如下配置的方式來(lái)發(fā)布服務(wù):
<bean id="serviceImpl" class="com.beordie.service.impl.serviceImpl" /> <dubbo:service interface="com.beordie.service.Service" ref="serviceImpl" />
作為服務(wù)消費(fèi)者,可以通過(guò)如下配置來(lái)引用服務(wù):
<!-- 生成遠(yuǎn)程服務(wù)代理,可以和本地bean一樣使用Service --> <dubbo:reference id="serviceTest" interface="com.beordie.ServiceTest" />
上面這種方式發(fā)布和引用服務(wù),一個(gè)配置項(xiàng)(dubbo:service、dubbo:reference)只能發(fā)布或者引用一個(gè)服務(wù),如果有多個(gè)服務(wù),這種方式就比較繁瑣了。推薦使用包掃描方式。
5.2、Dubbo 協(xié)議
一般在服務(wù)提供者一方配置,可以指定使用的協(xié)議名稱和端口號(hào)。
<dubbo:protocol name="dubbo" port="20880"/>
- Dubbo支持的 協(xié)議 有:
dubbo
、rmi
、hessian
、http
、webservice
、rest
、redis
等。 - 推薦使用的是dubbo協(xié)議。 dubbo 協(xié)議采用單一長(zhǎng)連接和 NIO 異步通訊,適合于小數(shù)據(jù)量大并發(fā)的服務(wù)調(diào)用,以及服務(wù)消費(fèi)者機(jī)器數(shù)遠(yuǎn)大于服務(wù)提供者機(jī)器數(shù)的情況。不適合傳送大數(shù)據(jù)量的服務(wù),比如傳文件,傳視頻等,除非請(qǐng)求量很低。
- 也可以在同一個(gè)工程中配置多個(gè)協(xié)議,不同服務(wù)可以使用不同的協(xié)議,例如:
<!-- 多協(xié)議配置 --> <dubbo:protocol name="dubbo" port="20880" /> <dubbo:protocol name="rmi" port="1099" /> <!-- 使用dubbo協(xié)議暴露服務(wù) --> <dubbo:service interface="com.beordie.HelloService" ref="helloService" protocol="dubbo" /> <!-- 使用rmi協(xié)議暴露服務(wù) --> <dubbo:service interface="com.beordie.DemoService" ref="demoService" protocol="rmi" />
5.3、負(fù)載均衡
負(fù)載均衡(Load Balance):其實(shí)就是將請(qǐng)求分?jǐn)偟蕉鄠€(gè)操作單元上進(jìn)行執(zhí)行,從而共同完成工作任 務(wù)。
- 在集群負(fù)載均衡時(shí),Dubbo 提供了多種均衡策略(包括隨機(jī)、輪詢、最少活躍調(diào)用數(shù)、一致性 Hash),缺省為random隨機(jī)調(diào)用。
- 配置負(fù)載均衡策略,既可以在服務(wù)提供者一方配置,也可以在服務(wù)消費(fèi)者一方配置,如下:
// 調(diào)用方配置 @Reference(check = false,loadbalance = "random")
// 服務(wù)方配置 @Service(loadbalance = "random")
5.4、 Dubbo無(wú)法發(fā)布被事務(wù)代理的服務(wù)
問(wèn)題
因?yàn)樘峁┑氖欠?wù)層的接口,在涉及數(shù)據(jù)庫(kù)的ACID
時(shí)就會(huì)添加事務(wù)管理,但是這樣服務(wù)將不會(huì)在 。ZooKeeper
中進(jìn)行注冊(cè),服務(wù)的消費(fèi)端也就不會(huì)拿到對(duì)應(yīng)的代理對(duì)象,也會(huì)報(bào)沒(méi)有可用的服務(wù)提供者的錯(cuò)誤。
原因
加入事務(wù)注解后,Spring會(huì)為此類基于 JDK動(dòng)態(tài)代理技術(shù) 創(chuàng)建代理對(duì)象,創(chuàng)建的代理對(duì)象完整類名為com.sun.proxy.$Proxy35
,導(dǎo)致Dubbo在進(jìn)行包匹配時(shí)沒(méi)有成功(因?yàn)槲覀冊(cè)诎l(fā)布服務(wù)時(shí)掃描的包為com.beordie.service),所以后面真正發(fā)布服務(wù)的代碼沒(méi)有執(zhí)行。
解決
使用 cglib
代理方式為Service類創(chuàng)建代理對(duì)象,并指定發(fā)布的接口 @Service(interfaceClass = HelloService.class)
到此這篇關(guān)于Java中dubbo+zookeeper微服務(wù)架構(gòu)的文章就介紹到這了,更多相關(guān)dubbo zookeeper微服務(wù)架構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
String s = new String(''a '') 到底產(chǎn)生幾個(gè)對(duì)象
這篇文章主要介紹了String s = new String(" a ") 到底產(chǎn)生幾個(gè)對(duì)象,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05Hadoop集成Spring的使用詳細(xì)教程(快速入門大數(shù)據(jù))
這篇文章主要介紹了Hadoop集成Spring的使用詳細(xì)教程(快速入門大數(shù)據(jù)),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01java HttpClient傳輸json格式的參數(shù)實(shí)例講解
這篇文章主要介紹了java HttpClient傳輸json格式的參數(shù)實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01關(guān)于SpringBoot中的請(qǐng)求映射及使用
這篇文章主要介紹了關(guān)于SpringBoot中的請(qǐng)求映射及使用,Spring Boot 中的授權(quán)機(jī)制,包括基于角色的授權(quán)和基于資源的授權(quán),同時(shí),我們也將給出相應(yīng)的代碼示例,幫助讀者更好地理解和應(yīng)用這些授權(quán)機(jī)制,需要的朋友可以參考下2023-07-07java 抓取網(wǎng)頁(yè)內(nèi)容實(shí)現(xiàn)代碼
這篇文章主要介紹了java 抓取網(wǎng)頁(yè)內(nèi)容實(shí)現(xiàn)代碼,需要的朋友可以參考下2014-02-02SpringBoot?整合?Spring-Session?實(shí)現(xiàn)分布式會(huì)話項(xiàng)目實(shí)戰(zhàn)
本文主要介紹了SpringBoot?整合?Spring-Session?實(shí)現(xiàn)分布式會(huì)話項(xiàng)目實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07淺談Java代碼的 微信長(zhǎng)鏈轉(zhuǎn)短鏈接口使用 post 請(qǐng)求封裝Json(實(shí)例)
下面小編就為大家?guī)?lái)一篇淺談Java代碼的 微信長(zhǎng)鏈轉(zhuǎn)短鏈接口使用 post 請(qǐng)求封裝Json(實(shí)例)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07