不同服务之间或者多服务之间调用接口的场景实际中会经常遇到,目前市面上解决该问题比较流行的两大框架为dubbo和springcloud。

        今天简单的建一个dubbo入门的案例,分为两个小案例一个和spring和结合案例,另一个是和springboot结合的案例,这里需要知道一点,dubbo是依赖spring环境的,不可以单独使用。搭建dubbo案例,需要安装zookeeper,可以从网上下载一个,解压后运行zkServer.cmd即可,zookeeper默认端口2181

1、dubbo+spring 的方式搭建

 1) 首先如果一个服务对其他服务公开接口,那么我们需要将这些对外的公共接口单独拿出来。第一步就是新建一个单独的公共接口模块

     

springboot启动如何dubbo源码 springboot搭建dubbo_案例

     这里为了简单,只有一个用户接口

public interface UserService {

    /**
     * 获取用户名称
     */
    String  userName();


    /**
     * 获取用户ID
     */
    String  userId();
}

 2)、新建一个dubbo集成spring的服务模块


springboot启动如何dubbo源码 springboot搭建dubbo_springboot_02

      dubbo的服务模块,这里以最简易的方式搭建,一个公共接口实现类,一个服务启动类,一个dubbo配置文件。

      我们先看看pom需要引入的依赖,这里是父pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zl.dubbo</groupId>
    <artifactId>dubbo_demo</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>api</module>
        <module>client</module>
        <module>service</module>
        <module>bootServer</module>
        <module>bootClient</module>
    </modules>



    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
        <springframework.version>4.0.2.RELEASE</springframework.version>
        <dubbo.version>2.5.7</dubbo.version>
    </properties>


    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>${dubbo.version}</version>
            <scope>compile</scope>
            <exclusions>
                <exclusion>
                    <artifactId>spring</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>

    当前服务模块的pom.xml:只需要引下父模块即可

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo_demo</artifactId>
        <groupId>com.zl.dubbo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service</artifactId>
    <dependencies>
        <dependency>
            <groupId>com.zl.dubbo</groupId>
            <artifactId>api</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

     UserService公共接口实现类:    注意:这里的@Service注解时dubbo提供的注解,不是spring的注解!

@Service
public class UserServiceImpl implements UserService {

    @Override
    public String userName() {
        return "张三";
    }

    @Override
    public String userId() {
        return "10001";
    }
}

     dubbo集成spring配置文件:  这里的dubbo我们使用注解的方式  dubbo-annotation.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:context="http://www.springframework.org/schema/context"
       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://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd
	 http://code.alibabatech.com/schema/dubbo
	 http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!--<context:component-scan base-package="com.zl"/>-->

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="storeServer_annotation"/>

    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://192.168.0.101:2181"/>

    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="rmi" port="20880"/>

    <dubbo:annotation package="com.zl.service" />

</beans>

      以及最后一个启动类: Application.class

public class Application {

    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("classpath:dubbo-annotation.xml");
        //开启
        context.start();
        System.out.println("启动成功……");
        System.in.read();   //避免程序结束,这里需要阻塞
    }
}

  到此位置 ,dubbo服务端编写完毕

 3)、编写客户端模块

springboot启动如何dubbo源码 springboot搭建dubbo_java_03

   客户端模块,这里主要作用是调用服务端接口,返回接口测试。为了简单java代码只有一个controller

    这里是使用spring,所以我们为了测试需要集成tomcat,使用web.xml进行启动客户端服务进行测试。

    首先需要新建客户端controller  , @Reference是Dubbo提供的注解。这里的UserService是Dubbo通过zookeeper反射生成的一个代理对象,具体原理后面自行百度。

@Controller
public class UserController {

    @Reference
    private UserService userService;

    @GetMapping("/index")
    public String user(HttpServletRequest request){
        String userId = userService.userId();
        String userName = userService.userName();
        request.setAttribute("userId",userId);
        request.setAttribute("userName",userName);
        return "index";
    }
}

   新建dubbo配置文件以及springMvc配置文件。 dubbo-annotation.xml   ;   spring-mvc.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:context="http://www.springframework.org/schema/context"
       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://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd
	 http://code.alibabatech.com/schema/dubbo
	 http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="enjoyStore_annotation"/>

    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://192.168.0.101:2181" check="false"/>

    <dubbo:annotation package="com.zl.client.controller" />

</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <context:component-scan base-package="com.zl.client.controller"></context:component-scan>

    <mvc:annotation-driven/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"></property>
        <property name="suffix" value=".jsp"></property>

    </bean>
    <import resource="dubbo_annotation.xml"/>
</beans>

     后面是web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

    <display-name>Archetype Created Web Application</display-name>

    <!-- Spring MVC servlet -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <!-- 此处可以可以配置成*.do,对应struts的后缀习惯 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>/index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

    以及一个简单的jsp页面,显示用户名和名称

<%@ page language="java"   contentType="text/html;charset=utf-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
<h2>Hello World!666</h2>
<h2>用户ID: ${userId}</h2>
<h2>用户名: ${userName}</h2>
</body>
</html>

  到此位置,客户端服务搭建完毕。好了,我们启动开始测试吧。

   先启动服务端:即运行Application类的main方法。

    然后为客户端client添加一个tomcat容器,启动。

    访问: http://localhost:8080/index

  

springboot启动如何dubbo源码 springboot搭建dubbo_springboot_04

   发现数据获取完毕,我们在打个断点看看。

 

springboot启动如何dubbo源码 springboot搭建dubbo_springboot_05

   发现这个userService对象的确是一个代理对象。  结束!

  

2、使用dubbo+springboot搭建案例

搭建完spring的案例,springboot就更简单了。

  1)、首先一样的道理,公共接口模块已经定义好了,这里不需要定义了。我们从服务端模块开始

 

springboot启动如何dubbo源码 springboot搭建dubbo_案例_06

   application.yml配置 : 端口、dubbo.name随便设置

server:
  port: 8090

dubbo:
  name: serverBoot
  zookeeper: zookeeper://192.168.0.101:2181

   UserService实现类:  UserServiceImpl.class

@Service
public class UserServiceImpl  implements UserService{
    @Override
    public String userName() {
        return "李四";
    }

    @Override
    public String userId() {
        return "10003";
    }
}

     springboot这里就用@Bean注解来进行配置了:DubboBean.class

@Configuration
public class DubboBean {

    @Value("${dubbo.zookeeper}")
    private String zkAddr;
    @Value("${dubbo.name}")
    private String appName;

    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName(appName);
        return applicationConfig;
    }

    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress(zkAddr);
        return registryConfig;
    }

    @Bean
    public ProtocolConfig protocolConfig() {
        ProtocolConfig protocolConfig = new ProtocolConfig();
        protocolConfig.setName("dubbo");
        protocolConfig.setPort(20881);
        return protocolConfig;
    }
}

     最后一个启动类

 

@SpringBootApplication
@DubboComponentScan(basePackages = "com.zl.service")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

 

    2)、客户端 

springboot启动如何dubbo源码 springboot搭建dubbo_dubbo_07

     application.yml配置:

server:
  port: 8082

dubbo:
  name: serverBoot
  zookeeper: zookeeper://192.168.0.101:2181

     UserController.class     

@RestController
public class UserController {
    
    @Reference
    private UserService userService;

    @GetMapping("/user")
    public String user(){
        String userId = userService.userId();
        String userName = userService.userName();
        return "用户ID: "+userId+", 用户名称:"+userName;
    }
}

    DubboInit.class 配置类

@Configuration
public class DubboInit {

    @Value("${dubbo.zookeeper}")
    private String zkAddr;
    @Value("${dubbo.name}")
    private String appName;

    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName(appName);
        return applicationConfig;
    }

    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress(zkAddr);
        return registryConfig;
    }

}

   最后一个启动类:

@SpringBootApplication
@DubboComponentScan("com.zl.client")
public class Application {
    
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

   大功告成,老套路,先启动服务模块,然后启动客户端模块

   访问:http://localhost:8082/user

  

springboot启动如何dubbo源码 springboot搭建dubbo_springboot_08

    我们在打个断点卡看看:

  

springboot启动如何dubbo源码 springboot搭建dubbo_java_09

   到此位置,dubbo案例搭建+测试完毕,我们再来看看整个案例的总体模块划分

springboot启动如何dubbo源码 springboot搭建dubbo_spring_10

   以上,有帮助的点个赞啊!