原创

Dubbo 创建 提供者 消费者


一、说明

Dubbo官方建议将服务接口、服务模型、服务异常等均放在 API 包中,因为服务模型和异常也是 API 的一部分,这样做也符合分包原则:重用发布等价原则(REP),共同重用原则(CRP)。 我们的演示项目分为3个:

  • gmall-common : 放置共用的服务接口、实体对象、工具类等等。
  • gmall-user-provider : 服务提供者(提供获取用户地址的服务)
  • gmall-order-consumer : 服务消费者

二、创建公共依赖项目 (gmall-common)

我们把 服务消费者 和 服务消费者 都需要的服务的接口层放入这个项目中。

1. 创建maven项目 gmall-common

2. UserAddress 实体类

package com.gf.entity;


import java.io.Serializable;

public class UserAddress implements Serializable{

    private static final long serialVersionUID = -1220870792073689661L;

    private Integer id;
    private String userAddress;
    private String userId;
    private String consignee;
    private String isDefault;

    public UserAddress(Integer id, String userAddress, String userId, String consignee, String isDefault) {
        this.id = id;
        this.userAddress = userAddress;
        this.userId = userId;
        this.consignee = consignee;
        this.isDefault = isDefault;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserAddress() {
        return userAddress;
    }

    public void setUserAddress(String userAddress) {
        this.userAddress = userAddress;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getConsignee() {
        return consignee;
    }

    public void setConsignee(String consignee) {
        this.consignee = consignee;
    }

    public String getIsDefault() {
        return isDefault;
    }

    public void setIsDefault(String isDefault) {
        this.isDefault = isDefault;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder( "{\"UserAddress\":{" );
        sb.append( "\"id\":" )
                .append( id );
        sb.append( ",\"userAddress\":\"" )
                .append( userAddress ).append( '\"' );
        sb.append( ",\"userId\":\"" )
                .append( userId ).append( '\"' );
        sb.append( ",\"consignee\":\"" )
                .append( consignee ).append( '\"' );
        sb.append( ",\"isDefault\":\"" )
                .append( isDefault ).append( '\"' );
        sb.append( "}}" );
        return sb.toString();
    }

}

3. UserService 接口

package com.gf.service;


import com.gf.entity.UserAddress;

import java.util.List;

public interface UserService {

    List<UserAddress> getUserAddressList(String userId);

}

三、创建服务提供者 (gmall-user-provider)

1. pom.xml

目前,dubbo-spring-boot-starter 发布,将为Spring Boot 2.x和1.x分离两个版本:

  • 0.2.x 是Spring Boot 2.x的主流发行版

  • 0.1.x 是用于维护Spring Boot 1.x的旧版本

因为我们是整合SpringBoot2.X,所以我们引入0.2.0 的 dubbo-spring-boot-starter

<?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.gf</groupId>
    <artifactId>gmall-user-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>gmall-user-provider</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 引入dubbo依赖 -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>
		 <!-- 公共类依赖 -->
        <dependency>
            <groupId>com.gf</groupId>
            <artifactId>gmall-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

2. application.properties

#就是服务名,不能跟别的dubbo提供端重复
dubbo.application.name=gmall-user-provider

#是指定注册中心协议
dubbo.registry.protocol=zookeeper

#注册中心的地址加端口号
dubbo.registry.address=127.0.0.1:2181

#注解方式要扫描的包

dubbo.scan.base-package=com.gf

#是分布式固定是dubbo,不要改
dubbo.protocol.name=dubbo

#服务暴露端口
dubbo.protocol.port=20880

#表示从注册中心发现监控中心地址
dubbo.monitor.protocol=registry

3. UserServiceImpl

Dubbo 的 @Service 注解用于暴露服务, 因为与spring 的@Service 重名,为了区别,我们使用@Component 把这个类交给spring管理

package com.gf.service.impl;


import com.alibaba.dubbo.config.annotation.Service;
import com.gf.entity.UserAddress;
import com.gf.service.UserService;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Service // com.alibaba.dubbo.config.annotation.Service
@Component
public class UserServiceImpl implements UserService{


    @Override
    public List<UserAddress> getUserAddressList(String userId) {

        List<UserAddress> list = new ArrayList<>();
        UserAddress address1 = new UserAddress(1 , "上海市杨浦区xxx路xxx号" , "1" , "王某某","0");
        UserAddress address2 = new UserAddress(2 , "上海市徐汇区xxx路xxx号" , "1" , "张某某","1");

        list.add( address1 );
        list.add( address2 );

        return list;
    }
}

4. 主启动类 UserServiceProviderApplication

我们使用**@EnableDubbo** 开启基于注解的dubbo功能

package com.gf;

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

//开启基于注解的dubbo功能
@EnableDubbo
@SpringBootApplication
public class UserServiceProviderApplication {

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

四、创建服务消费者 (gmall-order-consumer)

1. 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.gf</groupId>
	<artifactId>gmall-order-consumer</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>gmall-order-consumer</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.0.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<!-- 引入springboot的web依赖 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- 引入dubbo的依赖 -->
		<dependency>
			<groupId>com.alibaba.boot</groupId>
			<artifactId>dubbo-spring-boot-starter</artifactId>
			<version>0.2.0</version>
		</dependency>
		<!-- 公共类依赖 -->
		<dependency>
			<groupId>com.gf</groupId>
			<artifactId>gmall-common</artifactId>
			<version>1.0-SNAPSHOT</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

2. application.properties

#项目运行端口
server.port=8761

#就是服务名,不能跟别的dubbo提供端重复
dubbo.application.name=gmall-order-consumer

#是指定注册中心协议、地址和端口
dubbo.registry.address=zookeeper://127.0.0.1:2181

#表示从注册中心发现监控中心地址
dubbo.monitor.protocol=registry

3. OrderService

package com.gf.service;


import com.gf.entity.UserAddress;

import java.util.List;

public interface OrderService {

    List<UserAddress> initOrder(String userId);

}

4. OrderServiceImpl

Dubbo 提供了 @Reference 注解 用来引用远程服务接口

package com.gf.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.gf.entity.UserAddress;
import com.gf.service.OrderService;
import com.gf.service.UserService;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {

    @Reference
    UserService userService;


    @Override
    public List<UserAddress> initOrder(String userId) {
        System.out.println( "用户id : " + userId );
        //查询用户地址
        List<UserAddress> addressList = userService.getUserAddressList( userId );
        return addressList;
    }
}


5. OrderController

package com.gf.controller;

import com.gf.entity.UserAddress;
import com.gf.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class OrderController {

    @Autowired
    OrderService orderService;

    @RequestMapping("/initOrder")
    public List<UserAddress> initOrder(@RequestParam("userId") String userId) {
        return orderService.initOrder( userId );
    }


}

五、安装监控中心 dubbo-monitor-simple

Dubbo为我们提供了一个简单的监控中心,dubbo-monitor-simple,上一章我们下载的运维相关的项目 incubator-dubbo-ops-master 中有个 dubbo-monitor-simple,我们通过 mvn clean package 来构建项目。
构建完成后 我们可以看到有个 dubbo-monitor-simple-2.0.0-assembly.tar.gz 我们解压后,进入它的目录 conf 下有个 dubbo.properties

dubbo.container=log4j,spring,registry,jetty-monitor
dubbo.application.name=simple-monitor
dubbo.application.owner=dubbo
#dubbo.registry.address=multicast://224.5.6.7:1234
#默认指定了使用zookeeper注册中心,端口也和我们使用的一样,所以不需要修改了
dubbo.registry.address=zookeeper://127.0.0.1:2181
#dubbo.registry.address=redis://127.0.0.1:6379
#dubbo.registry.address=dubbo://127.0.0.1:9090
#服务暴露端口
dubbo.protocol.port=7070
#服务运行端口
dubbo.jetty.port=8080
dubbo.jetty.directory=${user.home}/monitor
dubbo.charts.directory=${user.home}/monitor/charts
dubbo.statistics.directory=${user.home}/monitor/statistics
dubbo.log4j.file=logs/dubbo-monitor-simple.log
dubbo.log4j.level=WARN

我们进入assembly.bin 目录下执行启动命令:

./start.sh

我们访问:http://127.0.0.1:8080/services.html

因为我没并没有启动 服务提供者 和 服务消费者,所以这里监控到的服务只有 监控中心自己。

六、项目测试

我们分别启动服务提供者和服务消费者,然后我们打开我们上一章节搭建的 Dubbo控制台

我们可以看出到,我们的服务都注册成功了,然后我们访问,http://127.0.0.1:8761/initOrder?userId=1 ,我们获取到了数据。

我们这时查看监控中心,我们可以看到检测到了我们的应用。

我们还可以看服务调用的一些统计 信息 和 图表

源码下载:https://github.com/gf-huanchupk/DubboLearning

dubbo
  • 作者:程序员果果
  • 发表时间:2018-11-19 15:48
  • 版权声明:自由转载-非商用-非衍生-保持署名 (创意共享4.0许可证)
  • 公众号转载:请在文末添加作者公众号二维码
  • 评论

      微信扫一扫,关注公众号 『 程序员果果 』