1
1、搭建zookpeer注冊中心
windows下載zooker
需要修改下zoo_sample .cfg為zoo.cnf
然后需要zoo.cnf中數據文件的路徑
第五步:把zoo_sample.cfg改名為zoo.cfg
[root@localhost conf]# mv zoo_sample.cfg zoo.cfg
第六步:修改data屬性:dataDir=/root/zookeeper-3.4.6/data
第七步:啟動zookeeper
2、搭建dubbo的管理控制台
這里我們使用的是dubbo的2.6版本的管理控制台,視頻上對於的就是2.6版本,現在官網上GitHub上對應的是2.7,方式不一樣
這里一定要注意jar包里面的application.properties的zookeer.properties一定要配置准確
接下來就可以使用java -jar dubbo-admin-2.6-SNAPSHOT.jar 啟動dubbo admin了,對於的端口是7001,賬戶和密碼都是root
在啟動dubbo admin之前一定保證zookper已經啟動成功了
3.搭建dubbo的服務提供者和服務消費者
我們在代碼中新建立三個工程
dubbo中對於的服務提供者和消費者所需的Javabean對象和接口都存儲在inferce這個模塊中,啟動provider是服務的提供者,consumer是服務的消費者
UserAddress.java
package com.cib.bean;
import java.io.Serializable;
public class UserAddress implements Serializable{
private Integer userId;
private String name;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
private String address;
private String phone;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "UserAddress [userId=" + userId + ", name=" + name + ", address=" + address + ", phone=" + phone + "]";
}
}
OrderService.java
package com.cib.service; import com.cib.bean.UserAddress; public interface OrderService { UserAddress createOrder(Integer userId); }
UserService.java
package com.cib.service; import com.cib.bean.UserAddress; public interface UserService { UserAddress getUserAddressByUseID(Integer userId); }
對於dubbo-common-inferce的pom.xml不需要做其他的依賴
<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.cin</groupId> <artifactId>dubbo-common-inferce</artifactId> <version>0.0.1-SNAPSHOT</version> </project>
接下來,我們重點分析下服務提供者的代碼
dubbo-user-provider
服務提供者模塊的依賴
1、第一需要依賴接口模塊
dubbo-common-inferce
2、第二需要引入dubbo模塊,這里使用的是2.6.2版本
<artifactId>dubbo</artifactId> <version>2.6.2</version>
3、需要注冊到注冊中心,需要引入注冊中心的客戶端
curator-framework
對於dubbo2.6以上的版本,對於的zk注冊中心的客戶端是curator,2.6以下版本dubbo對應的客戶端是zkclient
<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.cib</groupId> <artifactId>dubbo-user-provider</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>com.cin</groupId> <artifactId>dubbo-common-inferce</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> </dependencies> </project>
接下來我們來看
package com.cib.service.impl; import com.cib.bean.UserAddress; import com.cib.service.UserService; public class UserServiceImpl implements UserService{ public UserAddress getUserAddressByUseID(Integer userId) { // TODO Auto-generated method stub System.out.println("服務端被調用"); UserAddress userAddress = new UserAddress(); userAddress.setAddress("北京市東城區89號"); userAddress.setName("科比"); userAddress.setPhone("187777737737"); return userAddress; } }
這里服務提供者提供了UserServiceImpl這個類,這個類提供了一個getUserAddressByUseID方法,可以讓消費者遠程訪問
接下來我們要提供配置文件,在配置文件中配置dubbo對於的參數,我們在resource文件夾下面新建立一個provider.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:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 使用dubbo發布服務 --> <!-- 提供方應用信息,用於計算依賴關系 --> <dubbo:application name="user-service-provider" /> <dubbo:registry protocol="zookeeper" address="localhost:2181" /> <!-- 用dubbo協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 聲明需要暴露的服務接口 --> <dubbo:service interface="com.cib.service.UserService" ref="userService" /> <!--具體實現該接口的 bean--> <bean id="userService" class="com.cib.service.impl.UserServiceImpl"/>
我們重點對每個參數進行校驗
1、dubbo服務的名稱
2、注冊中心的地址配置
3、服務端和消費者通信的協議和端口
4、暴露服務的接口<dubbo:service interface
<dubbo:application name="user-service-provider" />是提供的dubbo應用的名稱
<dubbo:registry protocol="zookeeper" address="localhost:2181" />provide需要向zk注冊中心進行注冊
<dubbo:protocol name="dubbo" port="20880" /> 這里消費者要調用服務的提供者,需要對於的端口和協議進行通信,這里就配置對於的通信協議和端口
<!-- 聲明需要暴露的服務接口 -->
<dubbo:service interface="com.cib.service.UserService" ref="userService" />
<!--具體實現該接口的 bean-->
<bean id="userService" class="com.cib.service.impl.UserServiceImpl"/>
我們編寫一個測試代碼,讓服務消費者運行起來
import java.io.IOException; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Provider { public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("provider.xml"); context.start(); System.out.println("dubbo服務提供端已啟動...."); System.in.read(); // 按任意鍵退出 } }
我們將程序運行起來
我們進入到dubbo-admin的控制台
可以看到這里有服務數目為1,應用數1,提供者數目1
這里應用名就是<dubbo:application name="user-service-provider" />中配置的
一個應該中可以暴露多個service接口,<dubbo:service interface="com.cib.service.UserService" ref="userService" />
我們可以看到當前的應用名稱是user-service-provider,我們查看當前user-service-provider應用下的com.cib.service.UserService這個服務接口,可以對這個接口使用路由規則,訪問控制,負載均衡等操作
4、接下來我們查詢服務消費者的代碼
dubbo-order-consumer
pom.xml
1.依賴接口模塊
2.依賴dubbo版本
3.依賴注冊中心的客戶端版本
<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.cib</groupId> <artifactId>dubbo-order-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>com.cin</groupId> <artifactId>dubbo-common-inferce</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> </dependencies> </project>
接下來配置dubbo的配置文件
consumer.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="com.cib.service"></context:component-scan> <dubbo:application name="order-service-consume" /> <dubbo:registry address="zookeeper://localhost:2181"/> <!--使用 dubbo 協議調用定義好的 api.PermissionService 接口--> <dubbo:reference id="userService" interface="com.cib.service.UserService"/> </beans>
這里配置spring的包掃描主要后面OderService中使用到userService,使用到了spring中的@Service的注解
OrderServiceImpl.java
package com.cib.service.imp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.cib.bean.UserAddress; import com.cib.service.OrderService; import com.cib.service.UserService; @Service public class OrderServiceImpl implements OrderService { @Autowired UserService userService; public UserAddress createOrder(Integer userId) { // TODO Auto-generated method stub UserAddress userAddressByUseID = userService.getUserAddressByUseID(userId); return userAddressByUseID; } }
我們編寫一個測試類,來遠程調用下userService
import java.io.IOException; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.cib.bean.UserAddress; import com.cib.service.OrderService; public class Consumer { public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "consumer.xml" ); context.start(); System.out.println("dubbo服務消費端已啟動..."); OrderService demoService = (OrderService)context.getBean( OrderService.class );// 獲取遠程服務代理 UserAddress hello = demoService.createOrder(null);//執行遠程方法 System.out.println(hello);//顯示調用結果 System.in.read(); // 按任意鍵退出 } }
程序的運行結果為:
我們在dubbo的admin上面也可以看到對於的信息為:
應用數目變成了2,因為多了一個 <dubbo:application name="order-service-consume" />order-service-consume這個應用
服務還是只有也、一個,就是
上面我們安裝了dubbo-admin服務管理中心,接下來我們要安裝服務的監控中心,監控一個服務的調用情況,使用dubbo-monitro-simple這個攻擊
dubbo-monitor-simple是dubbo提供的簡單監控中心,可以用來顯示接口暴露,注冊情況,也可以看接口的調用明細,調用時間等。
Simple Monitor掛掉不會影響到Consumer和Provider之間的調用,所以用於生產環境不會有風險。
Simple Monitor采用磁盤存儲統計信息,請注意安裝機器的磁盤限制,如果要集群,建議用mount共享磁盤。
charts目錄必須放在jetty.directory下,否則頁面上訪問不了。
配置好了之后可以結合admin管理后台使用,可以清晰的看到服務的訪問記錄、成功次數、失敗次數。
monitor的安裝步驟如下
1. 下載源碼(托管在github上)
~]# wget https://github.com/alibaba/dubbo/archive/dubbo-2.6.0.zip
~]# unzip dubbo-2.6.0.zip
~]# cd dubbo-dubbo-2.6.0/
2. 安裝依賴
~]# yum -y install java-1.8.0-openjdk maven
maven: 用於編譯dubbo-simple-monitor
jdk: dubbo-simple-monitor是java語言所寫,故需要jdk
3. 編譯dubbo-simple-monitor
dubbo-dubbo-2.6.0]# cd dubbo-simple/dubbo-monitor-simple/
dubbo-monitor-simple]# mvn clean install編譯成功后的目標文件為:target/dubbo-monitor-simple-2.6.0-assembly.tar.gz
執行mvn clean pakeage 操作
編譯完成之后進入到
我們需要將dubbo-monitor-simple-2.6.0-assembly.tar.gz這個包解壓,修改里面的配置文件,之后在啟動,解壓之后修改dubbo.properties,確保里面注冊中心的配置是正確的
啟動服務進入到bin目錄下
這里為了避免端口和springboot默認的端口有沖突,我們把dubbo中dubbo.properties對於的端口修改下
接下來,我們需要將dubbo-monitor添加到服務提供方和消費方,這里才能對dubbo的服務進行監控
- 我們需要監控的服務在配置dubbo時要加入<dubbo:monitor protocol="registry"/>這項配置
我們在consumer.xml和provider.xml中添加對於的配置選項
- 這樣我們重啟服務提供者和消費者我們可以看到對於的信息
總結dubbo中應用,服務,已經方法的關系
- 1、dubbo應該就是一個maven工程
在dubbo的配置文件中<dubbo:application name="user-service-provider" />來制定dubbo應用的名稱
一個dubbo應用中可以提供多個服務,所謂的服務就是一個接口,一個接口類對於一個服務,服務的暴露通過<dubbo:service interface="com.cib.service.UserService" ref="userService" />這個來暴露
一個接口類下,可以保護多個方法,例如com.cib.service.UserService這個接口下面可以定義多個方法
3、springboot整合dubbo
新建兩個spring-boot的工程
這里要注意spring-boot版本和dubbo版本整合的版本
對於服務提供者的pom.xml如下:
<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.atguigu</groupId>
<artifactId>boot-user-service.procider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- zookeeper client依賴 -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>com.cin</groupId>
<artifactId>dubbo-common-inferce</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<!-- 添加spring-boot的maven插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
這里spring-boot的版本是2.0.3.RELEASE,那么springboot與dubbo整合的是對於的版本號是dubbo-spring-boot-starter是2.X版本,如果springboot是2.X版本,對於的與dubbo整合的版本是2.X這里要特別注意
整合之后,我們可以看到依賴包中會下載對於的dubbo
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
此外還需要引入注冊中心客戶端的依賴
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
同時還需要引入對於的common-interferce公共接口的依賴
<dependency>
<groupId>com.cin</groupId>
<artifactId>dubbo-common-inferce</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
接下來將我們重點的配置
application.properties的內容如下
#\u5F53\u524D\u670D\u52A1/\u5E94\u7528\u7684\u540D\u5B57
dubbo.application.name=user-service-provider222
#\u6CE8\u518C\u4E2D\u5FC3\u7684\u534F\u8BAE\u548C\u5730\u5740
dubbo.registry.protocol=zookeeper
dubbo.registry.address=127.0.0.1:2181
#\u901A\u4FE1\u89C4\u5219\uFF08\u901A\u4FE1\u534F\u8BAE\u548C\u63A5\u53E3\uFF09
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#\u8FDE\u63A5\u76D1\u63A7\u4E2D\u5FC3
dubbo.monitor.protocol=registry
#\u5F00\u542F\u5305\u626B\u63CF\uFF0C\u53EF\u66FF\u4EE3 @EnableDubbo \u6CE8\u89E3
##dubbo.scan.base-packages=com.zang.gmall
我們對上面的配置文件一一進行講解
dubbo.application.name=user-service-provider222對於之前的<dubbo:application name="user-service-provider" />
dubbo.registry.protocol=zookeeper
dubbo.registry.address=127.0.0.1:2181對應之前的<dubbo:registry protocol="zookeeper" address="localhost:2181" />
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880對應之前的<dubbo:protocol name="dubbo" port="20880" />
dubbo.monitor.protocol=registry對於之前的 <dubbo:monitor protocol="registry"/>
關鍵點:在之前的配置文件中使用下面的服務提供者獎服務暴露出去,在springboot和dubbo整合之后,只需要一個dubbo提供的@Service就可以獎服務暴露出去,這里和Spring提供的@Service一定要區別開來
<dubbo:service interface="com.cib.service.UserService" ref="userService" /
<bean id="userService" class="com.cib.service.impl.UserServiceImpl"/>
我們來看下面的UserServiceImpl的代碼,使用dubbo提供過的@Service將服務暴露出去
package com.cib.service.impl; import org.springframework.stereotype.Component; import com.alibaba.dubbo.config.annotation.Service; import com.cib.bean.UserAddress; import com.cib.service.UserService; //注意這里@Service是dubbo框架提供的注解,springboot與dubbo整合的時候,暴露服務 //com.alibaba.dubbo.config.annotation.Service //@Component讓UserServiceImpl被spring容器管理 @Service @Component public class UserServiceImpl implements UserService{ public UserAddress getUserAddressByUseID(Integer userId) { // TODO Auto-generated method stub System.out.println("服務端被調用"); UserAddress userAddress = new UserAddress(); userAddress.setAddress("北京市東城區89號"); userAddress.setName("科比"); userAddress.setPhone("187777737737"); return userAddress; } }
//注意這里@Service是dubbo框架提供的注解,springboot與dubbo整合的時候,暴露服務 //com.alibaba.dubbo.config.annotation.Service //@Component讓UserServiceImpl被spring容器管理
接下來我們來看啟動類BootUserServiceProviderAplication
package com.cib; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; @EnableDubbo @SpringBootApplication public class BootUserServiceProviderAplication { public static void main(String[] args) { SpringApplication.run(BootUserServiceProviderAplication.class,args); } }
強調在啟動類的時候一定要加上:@EnableDubbo這個注解
這樣我們的服務提供方就已經成功了,我們啟動應用之前要保證zookeeper已經啟動
我們接下來啟動應用,在dubbo-admin上就可以看到對於的注冊信息
5、接下來我們進行消費者端的配置
對於的pom文件和消費者一樣
<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.atguigu</groupId> <artifactId>boot-user-service-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <!-- zookeeper client依賴 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> <dependency> <groupId>com.cin</groupId> <artifactId>dubbo-common-inferce</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> </dependency> </dependencies> <!-- 添加spring-boot的maven插件 --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
接下來我們來看對於的dubbo的配置文件application.properties

#\u907F\u514D\u548C\u76D1\u63A7\u4E2D\u5FC3\u7AEF\u53E3\u51B2\u7A81\uFF0C\u8BBE\u4E3A8081\u7AEF\u53E3\u8BBF\u95EE
server.port=8081
dubbo.application.name=order-service-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.monitor.protocol=registry
dubbo.application.name=order-service-consumer對於之前的 <dubbo:application name="order-service-consume" />
dubbo.registry.address=zookeeper://127.0.0.1:2181對於之前的dubbo.registry.address=zookeeper://127.0.0.1:2181
在之前的配置中還存在一個
<!--使用 dubbo 協議調用定義好的 api.PermissionService 接口-->
<dubbo:reference id="userService" interface="com.cib.service.UserService"/>
消費端需要調用服務,需要使用<dubbo:reference id="userService" 引入要調用的遠程服務
這里spring boot和dubbo整合之后如何實現了,這里Spring boot給我們提供了一個@Reference的注解來幫我們實現
我們來看OrderServiceImpl.java
package com.cib.service.imp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.alibaba.dubbo.config.annotation.Reference; import com.cib.bean.UserAddress; import com.cib.service.OrderService; import com.cib.service.UserService; @Service public class OrderServiceImpl implements OrderService { @Reference UserService userService; public UserAddress createOrder(Integer userId) { // TODO Auto-generated method stub UserAddress userAddressByUseID = userService.getUserAddressByUseID(userId); return userAddressByUseID; } }
消費者中的服務要通過userService調用服務提供者的代碼,我們只需要在服務在userService上面使用@Reference注解就可以了
接下來我們編寫一個controller類
package com.cib.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.cib.bean.UserAddress; import com.cib.service.OrderService; @Controller public class OrderController { @Autowired OrderService orderService; @RequestMapping("/initOrder") @ResponseBody public String initOrder(){ UserAddress createOrder = orderService.createOrder(null); return createOrder.toString(); } }
對於的啟動類
package com.cib; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; @EnableDubbo @SpringBootApplication public class BootUserServiceProviderAplication { public static void main(String[] args) { SpringApplication.run(BootUserServiceProviderAplication.class,args); } }
啟動消費者之后,我們在頁面上輸入
就遠程訪問服務消費者提供的代碼了
7.接下來講解dubbo配置文件的優先加載順序等
JVM啟動-D參數優先,這樣可以使用戶在部署和啟動時進行參數重寫,比如在啟動時需改變協議的端口。
XML次之,如果在XML中有配置,則dubbo.properties中的相應配置項無效。
Properties最后,相當於缺省值,只有XML沒有配置時,dubbo.properties的相應配置項才會生效,通常用於共享公共配置,比如應用名。
接下來我們來測試下效果
上面的application.properties相當於上圖中的dubbo.xml文件,我們在resource目錄下新建立一個dubbo.properties 文件
dubbo.properties的內容為
dubbo.protocol.port=20885
如果虛擬機的端口配置為20883
application.properties中配置的端口為dubbo.protocol.port=20880
dubbo.properties中配置dubbo通信協議的端口為dubbo.protocol.port=20885
按照上面的優先級為:20883>20880>20885
點擊 run configure中配置虛擬機的參數
我們在dubbo-admin控制台中可以看到對應的配置信息
對於的服務端口變成了20883
8、dubbo配置服務啟動時候的檢查
如果服務消費者啟動的時候,在注冊中心中發現當前消費者需要遠程調用的服務在注冊中心中不存在,消費者啟動的時候就會報錯,我們可以修改dubbo默認的配置
當消費者啟動的時候既然遠程調用的服務不存在,也能讓消費者正常啟動,在真正遠程調用的時候才檢查遠程服務提供者是否啟動,需要修改下面的配置,默認報錯如下
Exception in thread "main" com.alibaba.dubbo.rpc.RpcException: No provider available from registry localhost:2181 for service com.cib.service.UserService on consumer 192.168.0.102 use dubbo version 2.6.2, please check status of providers(disabled, not registered or in blacklist).
at com.alibaba.dubbo.registry.integration.RegistryDirectory.doList(RegistryDirectory.java:575)
at com.alibaba.dubbo.rpc.cluster.directory.AbstractDirectory.list(AbstractDirectory.java:74)
at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.list(AbstractClusterInvoker.java:271)
at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:232)
at com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:75)
at com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:52)
at com.alibaba.dubbo.common.bytecode.proxy0.getUserAddressByUseID(proxy0.java)
at com.cib.service.imp.OrderServiceImpl.createOrder(OrderServiceImpl.java:17)
at Consumer.main(Consumer.java:14)
我們在消費端的dubbo的配置文件中consumer.xml
中進行配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="com.cib.service"></context:component-scan> <dubbo:application name="order-service-consume" /> <dubbo:registry address="zookeeper://localhost:2181"/> <!--使用 dubbo 協議調用定義好的 api.PermissionService 接口--> <dubbo:reference id="userService" interface="com.cib.service.UserService" check="false"/> <dubbo:monitor protocol="registry"/> </beans>
<dubbo:reference id="userService" interface="com.cib.service.UserService" check="false"/>中配置check=fasle,現在一個dubbo應用下可以發布多個服務,如果每個服務都這樣設置比較麻煩,dubbo給我們提供統一對服務的配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="com.cib.service"></context:component-scan> <dubbo:application name="order-service-consume" /> <dubbo:registry address="zookeeper://localhost:2181"/> <!--使用 dubbo 協議調用定義好的 api.PermissionService 接口--> <dubbo:reference id="userService" interface="com.cib.service.UserService" /> <dubbo:monitor protocol="registry"/> <dubbo:consumer check="false"/> </beans>
<dubbo:consumer check="false"/>對所有的服務都有效果
<dubbo:registy check="false"/>配置dubbo應用啟動的時候即使沒有注冊中心,啟動的時候也不會報錯
9、dubbo中的超時配置
當消費者調用提供者方法的時候,可以對調用的時候進行配置
配置的時候存在優先級關系
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="com.cib.service"></context:component-scan> <dubbo:application name="order-service-consume" /> <dubbo:registry address="zookeeper://localhost:2181"/> <!--使用 dubbo 協議調用定義好的 api.PermissionService 接口--> <dubbo:reference id="userService" interface="com.cib.service.UserService" timeout="4000" > <dubbo:method name="getUserAddressByUseID" timeout="6000"></dubbo:method> </dubbo:reference> <dubbo:monitor protocol="registry"/> <dubbo:consumer check="false" timeout="3000"/> </beans>
我們來看下時間的優先級:
優先級最高:精確到服務下面的某個方法: <dubbo:method name="getUserAddressByUseID" timeout="6000"></dubbo:method>
優先級第二:精確到應用下的某個服務,改服務下的所有方法超時時間都一樣<dubbo:reference id="userService" interface="com.cib.service.UserService" timeout="4000" >
優先級最差:讓改應用下的所有服務都是一樣的超時時間:<dubbo:consumer check="false" timeout="3000"/>
第二個優先級:如果配置一樣,消費端優先,提供者次之
在服務提供者,也可以給某個服務配置超時時間
我們在provider.xml中配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="cn.e3mall.service"></context:component-scan> <!-- 使用dubbo發布服務 --> <!-- 提供方應用信息,用於計算依賴關系 --> <dubbo:application name="user-service-provider" /> <dubbo:registry protocol="zookeeper" address="localhost:2181" /> <!-- 用dubbo協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 聲明需要暴露的服務接口 --> <dubbo:service interface="com.cib.service.UserService" ref="userService" timeout="2000" /> <!--具體實現該接口的 bean--> <bean id="userService" class="com.cib.service.impl.UserServiceImpl"/> <dubbo:monitor protocol="registry"/> </beans>
<dubbo:service interface="com.cib.service.UserService" ref="userService" timeout="2000" /> 配置超時時間為2000,表示如果服務提供者2秒內訪問改服務下的方法都還沒有訪問完成,就拋出異常
如果在消費者端進行了配置,也是在服務級別配置超時時間
<dubbo:reference id="userService" interface="com.cib.service.UserService" timeout="4000" >
二者的級別都是針對服務級別的,在級別一樣的情況下,消費者優先,消費者調用的時候只有超過4秒才拋出異常,不是提供者配置的2秒,這里要注意
對於服務 提供方我們也可以統一使用 <dubbo:provider timeout="3000"></dubbo:provider>對全部的服務配置超時時間
第三種場景:
在消費者端超市時間配置在方法級別,在服務消費者超時時間配置在服務級別,在服務調用的時候,按照消費者配置的時間有效
服務提供方:方法級別
消費方:配置到服務級別,沒有配置方法級別
所有當消費者調用getUserAddressList方法超過1秒之后,就會拋出異常
10、dubbo中的重試次數
DUBBO超時時間和重試機制,在上面配置中當dubbo遠程調用消費者異常或者失敗的時候,dubbo提供了重試機制,例如服務消費者調用服務提供者的服務超時之后,如果設置了重試機制
dubbo會進行重試操作
我們來看消費者和提供者的配置
消費者:
provider.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="cn.e3mall.service"></context:component-scan> <!-- 使用dubbo發布服務 --> <!-- 提供方應用信息,用於計算依賴關系 --> <dubbo:application name="user-service-provider" /> <dubbo:registry protocol="zookeeper" address="localhost:2181" /> <!-- 用dubbo協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 聲明需要暴露的服務接口 --> <dubbo:service interface="com.cib.service.UserService" ref="userService" timeout="2000" /> <!--具體實現該接口的 bean--> <bean id="userService" class="com.cib.service.impl.UserServiceImpl"/> <dubbo:monitor protocol="registry"/> </beans>
服務提供方:配置了該服務的超時時間是2000秒
package com.cib.service.impl; import com.cib.bean.UserAddress; import com.cib.service.UserService; public class UserServiceImpl implements UserService{ public UserAddress getUserAddressByUseID(Integer userId) { // TODO Auto-generated method stub System.out.println("服務端被調用"); try { Thread.sleep(1500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } UserAddress userAddress = new UserAddress(); userAddress.setAddress("北京市東城區89號"); userAddress.setName("科比"); userAddress.setPhone("187777737737"); return userAddress; } }
服務提供者代碼里面超時時間設置為1500毫秒
我們來看服務消費者
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="com.cib.service"></context:component-scan> <dubbo:application name="order-service-consume" /> <dubbo:registry address="zookeeper://localhost:2181"/> <!--使用 dubbo 協議調用定義好的 api.PermissionService 接口--> <dubbo:reference id="userService" interface="com.cib.service.UserService" timeout="1000" > </dubbo:reference> <dubbo:monitor protocol="registry"/> <dubbo:consumer check="false" /> </beans>
<dubbo:reference id="userService" interface="com.cib.service.UserService" timeout="1000" >
<dubbo:service interface="com.cib.service.UserService" ref="userService" timeout="2000" />
二者都是服務級別,以消費者的有效,所有當提供方調用服務端的時候如果超過1秒,就會超時,現在在提供方現場sleep了1500毫秒,調用的時候肯定會拋出異常
我們在消費者方配置如下,增加一個重試參數
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="com.cib.service"></context:component-scan> <dubbo:application name="order-service-consume" /> <dubbo:registry address="zookeeper://localhost:2181"/> <!--使用 dubbo 協議調用定義好的 api.PermissionService 接口--> <dubbo:reference id="userService" interface="com.cib.service.UserService" timeout="1000" retries="5"> </dubbo:reference> <dubbo:monitor protocol="registry"/> <dubbo:consumer check="false" /> </beans>
<dubbo:reference id="userService" interface="com.cib.service.UserService" timeout="1000" retries="5">對某個服務進行重試,當第一次調用失敗之后,在重新嘗試五次
我們來看看服務端的打印
我們可以看到服務提供方的方法被調用了6次
retries的使用了timeout一樣,也可以配置在服務提供方。也可以配置針對某個具體的方法,優先級和timeout一樣
在服務提供方配置如下:
<dubbo:service interface="com.cib.service.UserService" ref="userService" timeout="2000" retries="10" />
重點強調:重試的時候一定保證被調用方法的冪等性
重點強調2:resties只能針對服務級別,不能到服務下面的具體的方法
<dubbo:service interface="com.cib.service.UserService" ref="userService2" timeout="2000" > <dubbo:method name="getUserAddressByUseID" reties="5" /> </dubbo:service>
在啟動的時候會報錯:
Caused by: org.xml.sax.SAXParseException; lineNumber: 24; columnNumber: 60; cvc-complex-type.3.2.2: 元素 'dubbo:method' 中不允許出現屬性 'reties'
12、dubbo中對服務多版本的支持
現在消費者方提供了一個接口服務:該接口有兩個實現類,在消費者方可以通過版本號來確認調用服務提供方的那個實現類
我們來看代碼
消費方:
provider.xml的配置如下
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="cn.e3mall.service"></context:component-scan> <!-- 使用dubbo發布服務 --> <!-- 提供方應用信息,用於計算依賴關系 --> <dubbo:application name="user-service-provider" /> <dubbo:registry protocol="zookeeper" address="localhost:2181" /> <!-- 用dubbo協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 聲明需要暴露的服務接口 --> <dubbo:service interface="com.cib.service.UserService" ref="userService1" timeout="2000" version="1.0.0" /> <dubbo:service interface="com.cib.service.UserService" ref="userService2" timeout="2000" version="2.0.0" /> <!--具體實現該接口的 bean--> <bean id="userService1" class="com.cib.service.impl.UserServiceImpl"/> <bean id="userService2" class="com.cib.service.impl.UserServiceImpl2"/> <dubbo:monitor protocol="registry"/> </beans>
com.cib.service.UserService有兩個實現類,提供了兩個服務,第一份服務設置版本號為version="1.0.0",第二個服務的版本號是version="2.0.0"
package com.cib.service.impl; import com.cib.bean.UserAddress; import com.cib.service.UserService; public class UserServiceImpl implements UserService{ public UserAddress getUserAddressByUseID(Integer userId) { // TODO Auto-generated method stub System.out.println("服務端1被調用"); UserAddress userAddress = new UserAddress(); userAddress.setAddress("北京市東城區89號"); userAddress.setName("科比"); userAddress.setPhone("187777737737"); return userAddress; } }
UserServiceImpl中打印服務端1被調用,UserServiceImpl2 中打印服務端2被調用
package com.cib.service.impl; import com.cib.bean.UserAddress; import com.cib.service.UserService; public class UserServiceImpl2 implements UserService{ public UserAddress getUserAddressByUseID(Integer userId) { // TODO Auto-generated method stub System.out.println("服務端2被調用"); UserAddress userAddress = new UserAddress(); userAddress.setAddress("北京市東城區89號"); userAddress.setName("科比"); userAddress.setPhone("187777737737"); return userAddress; } }
我們來看消費端的配置consumer.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="com.cib.service"></context:component-scan> <dubbo:application name="order-service-consume" /> <dubbo:registry address="zookeeper://localhost:2181"/> <!--使用 dubbo 協議調用定義好的 api.PermissionService 接口--> <dubbo:reference id="userService" interface="com.cib.service.UserService" timeout="1000" retries="5" version="2.0.0"> </dubbo:reference> <dubbo:monitor protocol="registry"/> <dubbo:consumer check="false" /> </beans>
我們配置<dubbo:reference id="userService" interface="com.cib.service.UserService" timeout="1000" retries="5" version="2.0.0">,調用userService服務的時候是調用2.0.0這個服務
我們允許看程序的打印
同理:version也只能針對服務級別,不能配置到服務下面的具體某個方法
<dubbo:service interface="com.cib.service.UserService" ref="userService2" timeout="2000" > <dubbo:method name="getUserAddressByUseID" version="5" /> </dubbo:service>
上面這種配置在啟動的時候會報錯:錯誤信息如下所示
Caused by: org.xml.sax.SAXParseException; lineNumber: 24; columnNumber: 61; cvc-complex-type.3.2.2: 元素 'dubbo:method' 中不允許出現屬性 'version'。
16、dubbo的本地存根
dubbo的本地存根的原理是:遠程服務后,客戶端通常只剩下接口,而實現全在服務器端,但提供方有些時候想在客戶端也執行部分邏輯,那么就在服務消費者這一端提供了一個Stub類,然后當消費者調用provider方提供的dubbo服務時,客戶端生成 Proxy 實例,這個Proxy實例就是我們正常調用dubbo遠程服務要生成的代理實例,然后消費者這方會把 Proxy 通過構造函數傳給 消費者方的Stub ,然后把 Stub 暴露給用戶,Stub 可以決定要不要去調 Proxy。會通過代理類去完成這個調用,這樣在Stub類中,就可以做一些額外的事,來對服務的調用過程進行優化或者容錯的處理。附圖:
本質就是:消費者在調用遠程方法之前,先調用本地存根的方法,在本地存根的方法做做一些輸入參數的校驗或者容錯,例如輸入參數滿足條件之后,在調用遠程的服務,本地存根是針對服務級別的
我們來看消費端的代碼
我們編寫一個存根類
package com.cib.service.imp; import com.cib.bean.UserAddress; import com.cib.service.UserService; public class OtherStub implements UserService{ private UserService userService; public OtherStub(UserService userService){ this.userService = userService; } public UserAddress getUserAddressByUseID(Integer userId) { System.out.println("本地存根方法被調用"); //在調用真正的遠程方法之前,例如做參數校驗 if(userId== null){ } UserAddress userAddress = userService.getUserAddressByUseID(null); return userAddress; } }
改存根類一定要有一個帶有輸入參數是遠程服務的一個有參構造函數,dubbo在應用啟動的時候,會將遠程調用的代理類通過這個形參注入到本地存根中,然后在本地存根中使用對於的頁業務判斷,來決定是否
調用遠程的方法
我們來看dubbo的配置
provider.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="com.cib.service"></context:component-scan> <dubbo:application name="order-service-consume" /> <dubbo:registry address="zookeeper://localhost:2181"/> <!--使用 dubbo 協議調用定義好的 api.PermissionService 接口-->
<dubbo:reference id="userService" interface="com.cib.service.UserService" timeout="1000" retries="5" version="2.0.0" stub="com.cib.service.imp.OtherStub">在服務引用的時候使用stub標簽添加上本地存根的全類名
強調:本地存根也是只能針對服務級別,不能針對服務下面的具體方法
4、springboot與dubbo的整合方法
1、之前我們已經講解了dubbo與springboot的第一種整合方式,在pom.xml中引入dubbo-starter的依賴,然后在application.properties中配置對於的參數,在服務提供方使用dubbo提供的@Service來暴露服務,
在服務消費方使用@Refence來調用遠程服務,上面我們講的timeout等參數可以在@Service或者@Refence中進行配置
在服務提供方的代碼:
package com.cib.service.impl; import org.springframework.stereotype.Component; import com.alibaba.dubbo.config.annotation.Service; import com.cib.bean.UserAddress; import com.cib.service.UserService; //注意這里@Service是dubbo框架提供的注解,springboot與dubbo整合的時候,暴露服務 //com.alibaba.dubbo.config.annotation.Service //@Component讓UserServiceImpl被spring容器管理 @Service(timeout=6000) @Component public class UserServiceImpl implements UserService{ public UserAddress getUserAddressByUseID(Integer userId) { // TODO Auto-generated method stub System.out.println("服務端被調用"); UserAddress userAddress = new UserAddress(); userAddress.setAddress("北京市東城區89號"); userAddress.setName("科比"); userAddress.setPhone("187777737737"); return userAddress; } }
但是這里@Serive和@Refence中的配置只能針對服務級別,如果要配置到方法級別就會有問題,例如配置到getUserAddressByUseID這個方法的超時時間@Service就無法實現
springboot與dubbo整合的三種方式:
1、引入dubbo-starter,使用@EnableDubbo開啟dubbo,在aplication.properties中配置上面dubbo的屬性的相關文件,使用@Service暴露dubbo服務,使用@Reference引用dubbo服務
2、第二種方式,保留dubbo的配置文件,在springboot應該啟動起來的時候,到dubbo的配置文件導入帶工程中
對於服務提供者
我們編寫一個dubbo的配置文件,將第一種方式中的aplication.properties刪除掉
provider.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="cn.e3mall.service"></context:component-scan> <!-- 使用dubbo發布服務 --> <!-- 提供方應用信息,用於計算依賴關系 --> <dubbo:application name="user-service-provider" /> <dubbo:registry protocol="zookeeper" address="localhost:2181" /> <!-- 用dubbo協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 聲明需要暴露的服務接口 --> <dubbo:service interface="com.cib.service.UserService" ref="userService1" timeout="2000" /> <!--具體實現該接口的 bean--> <bean id="userService1" class="com.cib.service.impl.UserServiceImpl"/> <dubbo:monitor protocol="registry"/> </beans>
我們使用dubbo原生的配置文件,暴露服務使用了 <dubbo:service interface=,不再使用@Service注解暴露服務
package com.cib.service.impl; import org.springframework.stereotype.Component; import com.alibaba.dubbo.config.annotation.Service; import com.cib.bean.UserAddress; import com.cib.service.UserService; //注意這里@Service是dubbo框架提供的注解,springboot與dubbo整合的時候,暴露服務 //com.alibaba.dubbo.config.annotation.Service //@Component讓UserServiceImpl被spring容器管理 @Component public class UserServiceImpl implements UserService{ public UserAddress getUserAddressByUseID(Integer userId) { // TODO Auto-generated method stub System.out.println("服務端getUserAddressByUseID方法被調用in:"+System.currentTimeMillis()); UserAddress userAddress = new UserAddress(); userAddress.setAddress("北京市東城區89號"); userAddress.setName("科比"); userAddress.setPhone("187777737737"); System.out.println("服務端getUserAddressByUseID方法被調用out:"+System.currentTimeMillis()); return userAddress; } @Override public void testError() { // TODO Auto-generated method stub System.out.println("服務端testError方法被調用"); throw new RuntimeException("provider throw exception....."); } @Override public void testSleep() { // TODO Auto-generated method stub System.out.println("服務端testSleep方法被調用"); try { Thread.sleep(8000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
UserServiceImpl 不再使用@sevice暴露服務,在啟動英語中不再使用@EnableDubbo的注解,需要使用@ImportResource(locations="classpath:provider.xml")導入dubbo的配置文件
package com.cib; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ImportResource; import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; @ImportResource(locations="classpath:provider.xml") @SpringBootApplication public class BootUserServiceProviderAplication { public static void main(String[] args) { SpringApplication.run(BootUserServiceProviderAplication.class,args); } }
pom.xml文件的內容如下
<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.atguigu</groupId> <artifactId>boot-user-service.procider</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.2.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.1</version> </dependency> <!-- zookeeper client依賴 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.11</version> </dependency> <dependency> <groupId>com.cin</groupId> <artifactId>dubbo-common-inferce</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.1</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.1.0</version> </dependency> </dependencies> <!-- 添加spring-boot的maven插件 --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
第三種方式:使用注解的方式,創建一個配置文件的方式來實現。我們窗口一個dubbo的config的配置文件
千萬要注意。配置文件的位置不能喝springboot的啟動類的文件在同一個包或者子包下面,否則會存在問題
我們單獨建立一個新的包
MyDubboConfig和BootUserServiceProviderAplication不再一個包下面,這里一定要注意下
MyDubboConfig.java的內容如下
package com.cib.config; import java.util.ArrayList; import java.util.List; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.MethodConfig; import org.apache.dubbo.config.ProtocolConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.ServiceConfig; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.cib.service.UserService; @Configuration public class MyDubboConfig { //<dubbo:application name="user-service-provider" /> @Bean public ApplicationConfig applicationConfig(){ ApplicationConfig applicationConfig = new ApplicationConfig(); applicationConfig.setName("user-service-provider"); return applicationConfig; } //<dubbo:registry protocol="zookeeper" address="localhost:2181" /> @Bean public RegistryConfig registryConfig(){ RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setAddress("localhost:2181"); registryConfig.setProtocol("zookeeper"); return registryConfig; } //<dubbo:protocol name="dubbo" port="20880" /> @Bean public ProtocolConfig protocolConfig(){ ProtocolConfig protocolConfig = new ProtocolConfig(); protocolConfig.setName("dubbo"); protocolConfig.setPort(20880); return protocolConfig; } //<dubbo:service interface="com.cib.service.UserService" ref="userService1" timeout="2000" /> @Bean public ServiceConfig<UserService> serviceConfig(UserService userService){ ServiceConfig<UserService> serviceConfig = new ServiceConfig<UserService>(); serviceConfig.setInterface(UserService.class); //設置暴露的dubbo的服務,這里dubbo服務UserServiceImpl已經使用@compent放入到了spring容器中,這里 //serviceConfig方法調用的時候,會將UserServiceImpl從形參中傳遞過來 serviceConfig.setRef(userService); //設置服務的超時時間 serviceConfig.setTimeout(6000); //還可以設置服務中國的具體的方法 MethodConfig methodConfig = new MethodConfig(); //設置方法的名稱 methodConfig.setName("getUserAddressByUseID"); //設置方法的超時時間 methodConfig.setTimeout(4000); List<MethodConfig> lists = new ArrayList(); lists.add(methodConfig); //設置service中的方法 serviceConfig.setMethods(lists); return serviceConfig; } }
對於MyDubboConfig首先要使用
@Configuration注解,其次<dubbo:application name="user-service-provider" />如何在配置文件中進行配置了
<dubbo:application 對於的在配置文件中就是ApplicationConfig,要使用@Bean添加到注解中
<dubbo:registry對於的配置文件中的類就是RegistryConfig
上面的配置文件就等價於下面的
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd"> <context:component-scan base-package="cn.e3mall.service"></context:component-scan> <!-- 使用dubbo發布服務 --> <!-- 提供方應用信息,用於計算依賴關系 --> <dubbo:application name="user-service-provider" /> <dubbo:registry protocol="zookeeper" address="localhost:2181" /> <!-- 用dubbo協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 聲明需要暴露的服務接口 --> <dubbo:service interface="com.cib.service.UserService" ref="userService1" timeout="2000" /> <!--具體實現該接口的 bean--> <bean id="userService1" class="com.cib.service.impl.UserServiceImpl"/> <dubbo:monitor protocol="registry"/> </beans>
接下來,需要將服務暴露出去,需要使用到@Service注冊,整個@Service注解是dubbo的,要讓@Service被描述到需要在應用啟動類開啟 @EnableDubbo注解
package com.cib.service.impl; import org.springframework.stereotype.Component; import com.alibaba.dubbo.config.annotation.Service; import com.cib.bean.UserAddress; import com.cib.service.UserService; //注意這里@Service是dubbo框架提供的注解,springboot與dubbo整合的時候,暴露服務 //com.alibaba.dubbo.config.annotation.Service //@Component讓UserServiceImpl被spring容器管理 @Component @org.apache.dubbo.config.annotation.Service public class UserServiceImpl implements UserService{ public UserAddress getUserAddressByUseID(Integer userId) { // TODO Auto-generated method stub System.out.println("服務端getUserAddressByUseID方法被調用in:"+System.currentTimeMillis()); UserAddress userAddress = new UserAddress(); userAddress.setAddress("北京市東城區89號"); userAddress.setName("科比"); userAddress.setPhone("187777737737"); System.out.println("服務端getUserAddressByUseID方法被調用out:"+System.currentTimeMillis()); return userAddress; } @Override public void testError() { // TODO Auto-generated method stub System.out.println("服務端testError方法被調用"); throw new RuntimeException("provider throw exception....."); } @Override public void testSleep() { // TODO Auto-generated method stub System.out.println("服務端testSleep方法被調用"); try { Thread.sleep(8000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
這里注解使用的類是@org.apache.dubbo.config.annotation.Service,不要使用import com.alibaba.dubbo.config.annotation.Service,因為dubbo已經從阿里巴巴轉移給apache了,如果使用阿里巴巴提供的
dubbo @Service注解會提示改方法已經過期了
在啟動類中要配置@EnableDubbo注解
package com.cib; import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ImportResource; @EnableDubbo(scanBasePackages="com.cib") @SpringBootApplication public class BootUserServiceProviderAplication { public static void main(String[] args) { SpringApplication.run(BootUserServiceProviderAplication.class,args); } }
@EnableDubbo(scanBasePackages="com.cib")這里指定包掃描的時候,一定要能夠掃描到MyDubboConfig配置類和服務暴露的UserServiceImpl的類
接下來pom.xml中,需要因人dubbo-starter已經連接zookeeper的客戶端
<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.atguigu</groupId> <artifactId>boot-user-service.procider</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.2.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.1</version> </dependency> <!-- zookeeper client依賴 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.11</version> </dependency> <dependency> <groupId>com.cin</groupId> <artifactId>dubbo-common-inferce</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.1</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.1.0</version> </dependency> </dependencies> <!-- 添加spring-boot的maven插件 --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
20、注冊中心與dubbo直接連接
第一種高可用的情況:如果注冊中心宕機了,之前服務消費者已經訪問過了服務的提供者,注冊中心全部宕機之后,服務提供者和服務消費依然能夠通過本地緩存進行通訊
第二種情況:dubbo消費者可以不通過注冊中心訪問dubbo的消費者
在服務的消費者方直接在@Refece中直接使用服務消費者的url地址,直接調用,不通過注冊中心
21、dubbo中的負載均衡策略
那個服務器上次請求訪問的時間最少,就會調用那個最快的服務器
例如一致性hash,通過方法和參數做hash,例如參數id=1的時候只會發生到第一台集群
參數id=2訪問第二台集群,通過方法名和參數做hash得到唯一值,訪問的機器都是唯一的
1、dubbo默認的隨機負載均衡算法是隨機的
我們在服務消費端配置方法級別,配置輪詢的機制
package com.cib.service.imp; import org.apache.dubbo.config.annotation.Reference; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.cib.bean.UserAddress; import com.cib.service.OrderService; import com.cib.service.UserService; @Service public class OrderServiceImpl implements OrderService { @Reference(loadbalance="roundrobin") UserService userService; public UserAddress createOrder(Integer userId) { // TODO Auto-generated method stub UserAddress userAddressByUseID = userService.getUserAddressByUseID(userId); return userAddressByUseID; } @Override public void testError() { // TODO Auto-generated method stub userService.testError(); } @Override public void testSleep() { // TODO Auto-generated method stub userService.testSleep(); } }
@Reference(loadbalance="roundrobin")表示輪詢的機制
@Reference(loadbalance="random")表示權重的隨機,我們要調節服務的權重,可以在dubbo-admin管理控制台中的倍權和半權中進行設置,可以調整當期服務提供者的權重
23、dubbo中的服務降級
1、dubbo支持兩種方式的服務降低,第一種直接返回null,不發起遠程服務的調用,消費者對服務的調用直接返回null,消費者不進行遠程服務的調用
2、第二種方式消費者會進行遠程調用,遠程調用失敗后返回null
在dubbo的管理控制台中,對於服務消費者,有個屏蔽設置
點擊屏蔽設置之后,消費者就不會直接調用遠程服務,直接返回為null
點擊容錯之后,就是服務降級的第二種方式
24、dubbo服務容錯和hystrix
我們在服務的消費方集成hystrix,當前的springboot是2.1.2版本,那么hystic也必須是2.1.2版本
pom.xml文件文件如下
<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.atguigu</groupId> <artifactId>boot-user-service-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.2.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.1</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.1.2.RELEASE</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.1</version> </dependency> <!-- zookeeper client依賴 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.11</version> </dependency> <dependency> <groupId>com.cin</groupId> <artifactId>dubbo-common-inferce</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.1.0</version> </dependency> </dependencies> <!-- 添加spring-boot的maven插件 --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
接下來在springboot的啟動文件中添加上@EnableHysticx的注解
package com.cib;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
@EnableDubbo
@EnableHystrix
@SpringBootApplication
public class BootUserServiceProviderAplication2 {
public static void main(String[] args) {
SpringApplication.run(BootUserServiceProviderAplication2.class,args);
}
}
接下來在服務調用的遠程方法上使用@HystrixCommand(fallbackMethod="hello")注解
package com.cib.service.imp; import org.apache.dubbo.config.annotation.Reference; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.netflix.hystrix.EnableHystrix; import org.springframework.stereotype.Service; import com.cib.bean.UserAddress; import com.cib.service.OrderService; import com.cib.service.UserService; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @Service public class OrderServiceImpl implements OrderService { @Reference(loadbalance="roundrobin") UserService userService; public UserAddress createOrder(Integer userId) { // TODO Auto-generated method stub UserAddress userAddressByUseID = userService.getUserAddressByUseID(userId); return userAddressByUseID; } @Override public void testError() { // TODO Auto-generated method stub userService.testError(); } @HystrixCommand(fallbackMethod="hello") @Override public void testSleep() { // TODO Auto-generated method stub userService.testSleep(); } public void hello(){ System.out.println("hello is called"); } }
當服務消費者遠程調用testSleep方式失敗的時候,會進行進行服務降級,調用 @HystrixCommand(fallbackMethod="hello")中指定的hello方法,就是當調用testSleep方法時候之后,會調用hello方法
將值返回給客戶
我們允許來看當在瀏覽器調用http://localhost:8081/testSleep失敗之后,hello方法會被調用
25、rpc遠程調用的原理
1、dubbo的框架設計
1、dubbo啟動的原理
dubbo啟動的時候,會使用DubbBeanDefinitionParse類中的pasre方法會將dubbo配置文件中的標簽,將標簽中的內容封裝到對於的config類中
例如dubbo:monitor就封裝到MonitorConfig中,其中@Service封裝到SeriviceBean中,@Reference封裝 到ReferenceBean中
當吧配置文件封裝到對於的config中類之后,接下來需要將服務暴露出去,會調用ServiceBean中的export方法
export方法中會調用doExportUrls方法