Dubbo快速入门

一、初识Dubbo

1、Dubbo是什么

  • 轻量级,高性能的RPC框架
  • 并不是要成为一个微服务的全面解决方案
  • 以Java语言而出名

2、Dubbo现状

  • 全称是Apache Dubbo
  • 微店,网易云音乐,考拉,滴滴,中国电信,人寿

3、Dubbo的故事:主要历程

  • 09年开始做,做的第1个版本
  • 10年初的时候,架构升级,Dubbo 2.0
  • 开源
  • one company战略
  • 合到HSF去
  • 第3节点,捐给Apache

二、RPC介绍

  • RPC———远程过程调用
  • 早期单机时代:IPC
  • 网络时代:把IPC扩展到网络上,这就是RPC
  • 实现RPC很头疼,于是就有了RPC框架
  • 调用其他机器上的程序和调用本地的程序一样方便

常见的RPC框架

  • 阿里的Dubbo
  • 新浪的Montan
  • Facebook的Thrift
  • 各个框架都有各自的优缺点

HTTP和RPC对比

  • 传输效率
  • 性能消耗,主要在于序列化和反序列化的耗时
  • 负载均衡

三、Dubbo工作原理

在这里插入图片描述
在这里插入图片描述

1、服务容器负责启动,加载,运行服务提供者
2、服务提供者在启动时,向注册中心注册自己提供的服务
3、服务消费者在启动时,向注册中心订阅自己所需的服务
4、注册中心返回服务提供者地址列表给消费者
5、从提供者地址列表中,选一台提供者进行调用
6、定期发送一次统计数据到监控中心

四、案例实操:项目编写

以实现课程查询的接口,来实操整合Dubbo和Zookeeper,并实现服务间的调用。

1、项目创建

项目创建IDEA创建Maven项目,删除原src,创建子模块,项目结构如下:
在这里插入图片描述
父模块依赖添加pom.xml:

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

<properties>
    <java.version>1.8</java.version>
    <spring-boot.version>2.1.12.RELEASE</spring-boot.version>
    <dubbo.version>2.7.4.1</dubbo.version>
</properties>

<dependencyManagement>
    <dependencies>
        <!-- Spring Boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <!-- Apache Dubbo  -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-bom</artifactId>
            <version>${dubbo.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
            <version>${dubbo.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</dependencyManagement>

2、服务提供者(producer)的开发

producer模块引入依赖pom.xml:

<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 Spring Boot Starter -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.4.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
    </dependency>
    <!-- Zookeeper dependencies -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-dependencies-zookeeper</artifactId>
        <version>${dubbo.version}</version>
        <type>pom</type>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- Web 功能 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- MySQL connector, 需要与 MySQL 版本对应 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- MyBatis依赖-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.1</version>
    </dependency>
</dependencies>

entity包下的实体类Course.java(生成get和set方法):

public class Course implements Serializable {
	Integer id;
	Integer courseId;
	String name;
	//1上架,0下架
	Integer valid;
}

mapper包下的CourseMapper.java:

@Mapper
@Repository
public interface CourseMapper {

	@Select("SELECT * FROM course WHERE valid = 1")
	List<Course> findValidCourses();
}

service包下的CourseListService.java:

public interface CourseListService {

	List<Course> getCourseList();
}

impl包下的CourseListServiceImpl.java(需要注意的是@Service的包将不在是我们平时的http,而是换成了dubbo):

import com.ygayddcxy.producer.entity.Course;
import com.ygayddcxy.producer.mapper.CourseMapper;
import com.ygayddcxy.producer.service.CourseListService;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;

@Service(version = "${demo.service.version}")
public class CourseListServiceImpl implements CourseListService {

	@Autowired
	private CourseMapper courseMapper;

	@Override
	public List<Course> getCourseList() {
		return courseMapper.findValidCourses();
	}
}

application.properties配置:

demo.service.version=1.0.0

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/course_prepare?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.username=root
spring.datasource.password=1214

logging.pattern.console=%clr(%d{${LOG_DATEFORMAT_PATTERN:HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}

spring.application.name=course-list

#dubbo协议
dubbo.protocol.name=dubbo
#-1随机找一个端口号
dubbo.protocol.port=-1  
#dubbo注册
dubbo.registry.address=zookeeper://192.168.17.132:2181
# 配置中心连接时间改为20秒
dubbo.config-center.timeout=20000
dubbo.registry.file=${user.home}/dubbo-cache/${spring.application.name}/dubbo.cache

mybatis.configuration.map-underscore-to-camel-case=true

dubbo.scan.base-packages=com.ygayddcxy.producer.service.impl

服务提供者的启动类DubboProducerApplication.java:

@EnableAutoConfiguration
public class DubboProducerApplication {

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

3、服务消费方(consumer)的开发

先引入依赖pom.xml:

<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 Spring Boot Starter -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.4.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo</artifactId>
    </dependency>
    <!-- Zookeeper dependencies -->
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-dependencies-zookeeper</artifactId>
        <version>${dubbo.version}</version>
        <type>pom</type>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- Web 功能 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- MySQL connector, 需要与 MySQL 版本对应 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- MyBatis依赖-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.1</version>
    </dependency>
    <dependency>
        <groupId>com.ygayddcxy</groupId>
        <artifactId>producer</artifactId>
        <version>1.0-SNAPSHOT</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

添加application.properties配置:

demo.service.version=1.0.0
server.port=8084
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/course_prepare?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.username=root
spring.datasource.password=1214

logging.pattern.console=%clr(%d{${LOG_DATEFORMAT_PATTERN:HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}

spring.application.name=course-price

#dubbo协议
dubbo.protocol.name=dubbo
#-1随机找一个端口号
dubbo.protocol.port=-1  
#dubbo注册
dubbo.registry.address=zookeeper://192.168.17.132:2181
# 配置中心连接时间改为20秒
dubbo.config-center.timeout=20000
dubbo.registry.file=${user.home}/dubbo-cache/${spring.application.name}/dubbo.cache

在entity包下添加实体类:
添加实体类CoursePrice.java(自行补充get和set):

public class CoursePrice implements Serializable {
	Integer id;
	Integer courseId;
	Integer price;
}

添加实体类CourseAndPrice.java(自行补充get和set):

public class CourseAndPrice implements Serializable {
	Integer id;
	Integer courseId;
	String name;
	Integer price;
}

在dao包下:
添加CoursePriceMapper.java:

@Mapper
@Repository
public interface CoursePriceMapper {

	@Select("SELECT * FROM course_price WHERE course_id = #{courseId}")
	CoursePrice findCoursePrices(Integer courseId);
}

在service包下添加CoursePriceService.java:

// 课程价格服务
public interface CoursePriceService {

	CoursePrice getCoursePrice(Integer courseId);

	List<CourseAndPrice> getCoursesAndPrice();
}

在impl包下添加CoursePriceServiceImpl.java:

// 课程价格服务
@Service
public class CoursePriceServiceImpl implements CoursePriceService {

	@Autowired
	CoursePriceMapper coursePriceMapper;

	@Reference(version = "${demo.service.version}")
	CourseListService courseListService;

	@Override
	public CoursePrice getCoursePrice(Integer courseId) {
		return coursePriceMapper.findCoursePrices(courseId);
	}

	@Override
	public List<CourseAndPrice> getCoursesAndPrice() {
		List<CourseAndPrice> courseAndPriceList = new ArrayList<>();
		List<Course> courseList = courseListService.getCourseList();
		for (int i = 0; i < courseList.size(); i++) {
			Course course = courseList.get(i);
			if (course != null) {
				CoursePrice price = getCoursePrice(course.getCourseId());
				if (price != null && price.getPrice() > 0) {
					CourseAndPrice courseAndPrice = new CourseAndPrice();
					courseAndPrice.setId(course.getId());
					courseAndPrice.setCourseId(course.getCourseId());
					courseAndPrice.setName(course.getName());
					courseAndPrice.setPrice(price.getPrice());
					courseAndPriceList.add(courseAndPrice);
				}
			}
		}
		return courseAndPriceList;
	}
}

在controller包下添加CoursePriceController.java:

@RestController
public class CoursePriceController {

	@Autowired
	CoursePriceService coursePriceService;

	@GetMapping({"/price"})
	public Integer getCoursePrice(Integer courseId) {
		CoursePrice coursePrice = coursePriceService.getCoursePrice(courseId);
		if (coursePrice != null) {
			return coursePrice.getPrice();
		} else {
			return -1;
		}
	}

	@GetMapping({"/coursesAndPrice"})
	public List<CourseAndPrice> getCoursesAndPrice() {
		return coursePriceService.getCoursesAndPrice();
	}
}

添加服务消费方的启动类DubboConsumerApplication.java:

@SpringBootApplication
public class DubboConsumerApplication {

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

至此项目的代码实现便写到这里,接下来便是测试项目,首先需要启动Zookeeper,然后在启动服务提供者,最后在启动服务消费方。
服务提供者:
在这里插入图片描述
服务消费方:
在这里插入图片描述
项目启动完成后,浏览器访问:http://127.0.0.1:8084/coursesAndPrice
在这里插入图片描述

案例实操

  • 自动检查zk和依赖的服务
  • dubbo.scan.base-packages配置
  • 实现服务间调用

最后在附上用到的数据库表结构命令:

资料:数据库结构与数据

/*
 Navicat Premium Data Transfer

 Source Server         : MySQL
 Source Server Type    : MySQL
 Source Server Version : 80022
 Source Host           : localhost:3306
 Source Schema         : course_prepare

 Target Server Type    : MySQL
 Target Server Version : 80022
 File Encoding         : 65001

 Date: 25/04/2022 00:11:20
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course`  (
  `id` int(0) NOT NULL,
  `course_id` int(0) NULL DEFAULT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `valid` int(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES (1, 1, '深入理解Java虚拟机', 1);
INSERT INTO `course` VALUES (2, 2, 'Java编程思想', 1);

-- ----------------------------
-- Table structure for course_price
-- ----------------------------
DROP TABLE IF EXISTS `course_price`;
CREATE TABLE `course_price`  (
  `id` int(0) NOT NULL,
  `course_id` int(0) NULL DEFAULT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
  `price` int(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of course_price
-- ----------------------------
INSERT INTO `course_price` VALUES (1, 1, '深入理解Java虚拟机', 399);
INSERT INTO `course_price` VALUES (2, 2, 'Java编程思想', 999);

SET FOREIGN_KEY_CHECKS = 1;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值