尚硅谷 dubbo学习视频

 

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方法

 

 

 


posted on 2019-07-14 15:12  luzhouxiaoshuai  阅读(1588)  评论(0编辑  收藏  举报

导航