前言

当下Java 生态环境里面,微服务占据了非常大的份额,现在大部分新开发的 Java选型的后台程序都很奇妙的会跟微服务发生一些关系。那目前市面上主流的微服务方向主要有 Spring 家族推出的Spring Boot Cloud 还有阿里巴巴推出的 Dubbo 服务。

这两种服务我都大体上的使用过,说一下我的感受。我感觉Spring Boot Cloud 周边的服务功能框架比较健全,如果希望快速的搭建起一个大型的商业类型的项目可以选择Spring Boot Cloud,毕竟人家血统纯正的 Spring Boot体系,以及最近挺火的 Spring Cloud Alibaba 感觉也挺不错的。Dubbo 服务这边大体就是使用 nacos 或者 zookeeper 作为注册中心来实现微服务,可能周边的服务框架没有 Spring BootCloud 那样健全,但是个人感觉 Dubbo 的服务调用会比 feign 和 ribbon 舒服一点。所以我就想粗略的讲一下 Dubbo 和 Zookeeper 怎么使用。

创建服务

创建一个 maven 项目,下面三个子项目,分别是 common,provider,consumer。

curator-recipes 和 curator-client 这两个服务包是因为当前 dubbo 版本和 zk 版本的兼容性问题,后续版本更新后应该就不需要开发人员引入了。

 parent 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.learn</groupId>
<artifactId>springboot-dubbo-zookeeper</artifactId>
<version>1.0.0.LEARN</version>
<packaging>pom</packaging>

<name>springboot-dubbo-nacos</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<modules>
<module>common</module>
<module>consumer</module>
<module>provider</module>
</modules>

<dependencyManagement>
<dependencies>
<!-- common -->
<dependency>
<groupId>com.learn</groupId>
<artifactId>common</artifactId>
<version>${version}</version>
</dependency>

<!-- Spring Boot -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.3.5.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.3.5.RELEASE</version>
</dependency>

<!-- Dubbo + Zookeeper -->
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-client -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

Common 模块

common 模块用作定义 provider 和 consumer 模块当中公共的类和接口,为了怎么代码的耦合度。如果不使用 common 模块,就必须在 provider 和 consumer 模块当中都定义调用接口和实体类。

 common pom.xml:

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

<modelVersion>4.0.0</modelVersion>
<artifactId>common</artifactId>
<name>common</name>
<url>http://maven.apache.org</url>
<packaging>jar</packaging>

<parent>
<groupId>com.learn</groupId>
<artifactId>springboot-dubbo-zookeeper</artifactId>
<version>1.0.0.LEARN</version>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
</dependencies>
</project>

定义服务调用接口:

package com.learn.common.handler.service;

/**
* 调用接口
* @author xiaohu
*
*/
public interface IHelloService { public String hello(); }

provider 模块

provider 作为服务的提供者,只需要实现 common 中定义的接口就行了,然后就是把服务通过 Dubbo 注册到 zookeeper 注册中心。

 provider pom.xml:

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

<modelVersion>4.0.0</modelVersion>
<artifactId>provider</artifactId>
<name>provider</name>
<url>http://maven.apache.org</url>
<packaging>jar</packaging>

<parent>
<groupId>com.learn</groupId>
<artifactId>springboot-dubbo-zookeeper</artifactId>
<version>1.0.0.LEARN</version>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<!-- common -->
<dependency>
<groupId>com.learn</groupId>
<artifactId>common</artifactId>
</dependency>

<!-- Spring Boot -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- Dubbo + Zookeeper-->
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-client -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
</dependency>
</dependencies>
</project>

启动类:

package com.learn.provider;

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

/**
* 服务提供者启动类
*
* @author xiaohu
*
*/
// 激活 Dubbo 服务
@EnableDubbo
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
System.out.println("Provider Application Starter ...");
SpringApplication.run(ProviderApplication.class, args);
System.out.println("Provider Application Starter Successful!");
}
}

application.properties:

# 启动端口
server.port=8000

# dubbo + zookeeper
dubbo.application.name=provider
dubbo.registry.address=zookeeper://127.0.0.1:2181
# -1 表示自动获取一个未被占用的端口
dubbo.protocol.port=-1
dubbo.protocol.name=dubbo

接口实现:

package com.learn.provider.handler.service;

import org.apache.dubbo.config.annotation.DubboService;

import com.learn.common.handler.service.IHelloService;

/**
* IHelloService 实现类
* @author xiaohu
*
*/
@DubboService
public class HelloService implements IHelloService {

public String hello() {
// TODO Auto-generated method stub
return "Hello World!";
} }

consumer 模块

consumer 作服务的消费者,调用服务接口。

consumer pom.xml:

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

<modelVersion>4.0.0</modelVersion>
<artifactId>consumer</artifactId>
<name>consumer</name>
<url>http://maven.apache.org</url>
<packaging>jar</packaging>

<parent>
<groupId>com.learn</groupId>
<artifactId>springboot-dubbo-zookeeper</artifactId>
<version>1.0.0.LEARN</version>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<!-- common -->
<dependency>
<groupId>com.learn</groupId>
<artifactId>common</artifactId>
</dependency>

<!-- Spring Boot -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Dubbo + Zookeeper-->
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.curator/curator-client -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
</dependency>
</dependencies>
</project>

启动类:

package com.learn.consumer;

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

/**
* 服务消费者启动类
*
* @author xiaohu
*
*/
// 激活 Dubbo
@EnableDubbo
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
System.out.println("Consumer Application Starter ...");
SpringApplication.run(ConsumerApplication.class, args);
System.out.println("Consumer Application Starter Successful!");
}
}

application.properties:

# 启动端口
server.port=8001

# dubbo + zookeeper
dubbo.application.name=consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
# -1 表示随机一个未被使用端口
dubbo.protocol.port=-1
dubbo.protocol.name=dubbo

服务调用:

package com.learn.consumer.endpoint.controller;

import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.learn.common.handler.service.IHelloService;

/**
* 服务调用
* @author xiaohu
*
*/
@RestController
public class HelloController { @DubboReference
private IHelloService helloService; @RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() {
return helloService.hello();
} }

运行测试一下:

先启动 zookeeper 服务:

再依次启动 provider 和 consumer 服务:

两个服务都已经成功的起来了。可以访问 http://localhost:8001/hello 测试一下。

成功返回了 Hello World!

总结

到此,一个简单的通过 Dubbo 完成的服务调用就写完了。这里需要说明,common 模块并不是必须的,只是个人的编码习惯,为的实体类和接口可以复用而已。如果不喜欢的可以在调用和实现模块中定义就行了,但是必须保证接口内容能对上。

服务启动顺序最好是按照,服务提供者优先启动,服务消费者后面启动的原则。

现在来说 Dubbo 经过了一段时间的断维之后,又开始维护了。我觉得这个是一件好的事情,给我们提供了更多元化的一个选择。也希望这篇文章能够帮助到大家,谢谢。

 有兴趣的话可以扫码或搜索 "边缘技术" 关注我的微信公众号,非常感谢大家。

# -1 表示自动获取一个未被占用的端口

SpringBoot+Dubbo+Zookeeper 实例的更多相关文章

  1. 搭建SpringBoot+dubbo+zookeeper+maven框架(二)

    上一篇文章是关于搭建SpringBoot+dubbo+zookeeper+maven框架的,但是里面的功能还不够完善,今天就日志管理方面做一些改善. 下了demo的网友可能会发现项目在启动时会有警告: ...

  2. 搭建SpringBoot+dubbo+zookeeper+maven框架(一)

    这几天项目还没来,所以就自己试着参考网上的一些资料,搭建了一个SpringBoot+dubbo+zookeeper+maven框架,网上参考的很多资料照着他们一步一步搭建,最后很多都运行不通,很是郁闷 ...

  3. SpringBoot + Dubbo + zookeeper 搭建简单分布式服务

    SpringBoot + Dubbo + zookeeper 搭建简单分布式服务 详细操作及源码见: https://github.com/BillyYangOne/dubbo-springboot

  4. springboot+dubbo+zookeeper+mybatis

    参考地址:https://www.cnblogs.com/gaopengfirst/p/9555240.html 首先创建一个maven项目: 再在该父项目中创建3个module,分别是:provid ...

  5. 分布式应用开发 | SpringBoot+dubbo+zookeeper实现服务注册发现 | 远程服务调用

    前言 通过新建两个独立服务--提供者.消费者,模拟两个独立分布的应用,通过使用dubbo+zookeeper来实现远程服务调用. 目录 项目搭建 provider-server consumer-se ...

  6. Springboot+dubbo+zookeeper整合

    本想自己搭建一个Spring+dubbo+zookeeper整合好的框架,想寻找个最佳实现但是遇到各种各样的问题,只好自己看看dubbo starter的源码 整理如下: 通过打上断点来看配置的对不对 ...

  7. SpringBoot+Dubbo+ZooKeeper+Maven入门实践

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11798626.html 注*** 本实例为仅适合初学者,关于dubbo和springboot以 ...

  8. 带着新人学springboot的应用11(springboot+Dubbo+Zookeeper 上)

    这次说个在大型项目比较常见的东西,就是分布式,分布式到底是个什么东西呢?概念太大,不好说,就像刚学javaee的人问你,什么是web啊,什么是spring啊等等,你可能觉得,这个东西我好像知道,但是用 ...

  9. SpringBoot&Dubbo&Zookeeper远程调用项目搭建

    序言 Dubbo一款分布式服务框架,作为阿里巴巴SOA服务化治理方案的核心框架,通过高性能和透明化的RPC实现服务的远程调用,对服务的负载均衡以及项目的耦合性提供很强的解决方式;具体Dubbo的介绍和 ...

随机推荐

  1. H5 常见问题汇总及解决方案

    原文链接:http://mp.weixin.qq.com/s/JVUpsz9QHsNV0_7U-3HCMg H5 项目常见问题汇总及解决方案 -- 由钟平勇分享 转自 https://github.c ...

  2. 三种远程部署war包检测

    简介 远程部署漏洞属于服务器.中间件配置问题,攻击者可通过远程部署漏洞获取系统权限,远程部署漏洞经常出现在Tomcat.Jboss.Weblogic等web容器之上. 0x01 ### tomcat部 ...

  3. 使用python编写量子线路打印的简单项目,并使用Sphinx自动化生成API文档

    技术背景 该文章一方面从量子线路的打印着手,介绍了一个简单的python量子线路工程.同时基于这个简单的小工程,我们顺带的介绍了python的API文档自动化生成工具Sphinx的基本使用方法. 量子 ...

  4. RabbitMQ之死信队列

    1:何为死信队列 死信队列也是一个正常的队列,可以被消费. 但是,死信队列的消息来源于其他队列的转发. 2:如何触发死信队列 1:消息超时 2:队列长度达到极限 3:消息被拒绝消费,并不再重进队列,且 ...

  5. JAVA基础(二)—— 常用的类与方法

    JAVA基础(二)-- 常用的类与方法 1 Math类 abs ceil floor 绝对值 大于等于该浮点数的最小整数 小于等于该浮点数的最大整数 max min round 两参数中较大的 两参数 ...

  6. 死磕Spring之IoC篇 - Bean 的创建过程

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...

  7. keras报错:AttributeError: '_thread._local' object has no attribute 'value'

    需求是使用pyqt5中的槽函数运行keras模型训练,为了不让工具在模型训练的过程中出现假死的现象,于是把训练操作放到单独的线程中运行,于是问题来了,训练操作在主线程运行时正常,但是界面假死,假若训练 ...

  8. 微信小程序自定义头部导航栏

    <!--index.wxml--> <view> <navbar id='index_header' background='{{background}}' pageNa ...

  9. 剑指 Offer 46. 把数字翻译成字符串 + 动态规划

    剑指 Offer 46. 把数字翻译成字符串 Offer_46 题目描述 题解分析 本题的解题思路是使用动态规划,首先得出递推公式如下 dp[i] = dp[i-1]+dp[i-2](如果s[i-1] ...

  10. 剑指 Offer 33. 二叉搜索树的后序遍历序列 + 根据二叉树的后序遍历序列判断对应的二叉树是否存在

    剑指 Offer 33. 二叉搜索树的后序遍历序列 Offer_33 题目详情 题解分析 本题需要注意的是,这是基于一颗二叉排序树的题目,根据排序二叉树的定义,中序遍历序列就是数据从小到大的排序序列. ...