前言
前几篇文章,简单地介绍了一下Docker的基本命令,几个比较基本但是也是比较重要的几个概念,还是希望大家能快速的上手Docker,然后又做了一个spring boot 2.1.8版 的hello Demo整合到Docker,我们编写了Dockerfile,通过了Dockerfile生成了Docker的镜像,然后运行成了容器
今天,我们开始正式的整合内容,首先从我们最常用的RPC Dubbo来入手,现在Dubbo已经重新焕发了青春,已经被Apache列为了顶级项目,未来又是一片光明
在如今,RPC框架盛行,spring Cloud家族对这块领域更是虎视眈眈,各大公司都有自己成熟的RPC框架,但是如果说经典,还是Dubbo,毕竟 在当年解决我们问题的还是Dubbo,,当年我们没有spring cloud 没有motan 没有sofa-RPC没有GPRC,RPCX等现在也算比较流行的框架 ,而在前几年Dubbo停止维护,它渐渐地脱离了我们的视野,后来大家技术不断进步,基础越来越扎实,随着大家对Netty Zookeeper的掌握理解,写一套能用的RPC框架也不在是高不可攀的事情。
现在Dubbo回归了,捐献给了apache,更新到了2.7,并有了一些新的变化,简单地列举一些,我们以后会一一一起学习
1.有了新的Dubbo Admin UI 新的管理控制台能力更加齐全,服务治理能力也变得更加完善
2.开始支持Netty4.x 数据传输模型做了新的支持
3.序列化方式做了多样化支持
4.注册中心支持Nacos ,Nacos新的配置中心和注册中心
5异步编程的API更加强大
6.开始无缝支持Spring4+ spring Boot
7.新的简化配置和新的简化注解配置
8.服务统计,链路追踪
上述的一些特性,我们逐一介绍,并了解其原理,在了解这些原理之后,我们也会实现一套自己的RPC框架
废话不多说多少,我们现在开始从头整起来,本小节首先先整理,Dubbo2.7和Spring boot2.1.8版本的整合,可能代码量相对前几个小节多一点,希望大家PC端查看
一.搭建基本效果
我们最后形成的基本架构图是如上图所示,这是一个景点的RPC调用方式,最后我们通过浏览器来访问,证实整个链路的连贯性和正确性
二.使用docker搭建本地单机zookeeper
大家都知道dubbo在以前是使用zookeeper做注册中心的,工欲善其事必先利其器,所以我们首先要搭建本地的zookeeper,方便我们本地的调试,使用docker搭建zk,只需要2分钟
1.1 首先查看本地已有的docker镜像,发现本地并没有zookeeper镜像
1.2 首先使用【docker pull zookeeper】命令从docker的官方仓库拉去镜像,就像maven从中心仓库拉去jar包一样简单
1.3 最后使用【docker run -d –name zookeeper -p 2181:2181 zookeeper:latest】命令来使用docker来运行本地的单机zookeeper,-d 表示后台调用,–name 来给zookeeper这个container起一个名字,-p 2181:2181 使用端口映射的方式,可以使得本机能够访问容器中的zookeeper
二.使用IDEA搭建spring boot 2.x整合Dubbo2.7的骨架
2.1 点击create New Project,选择maven点击Next
2.2 填写自定义的groupId和artifactId,点击Next,最后确认项目名,点击Next
然后确认项目存放的地址和项目的正确名称,就可以finish
2.3 创建完整个项目的结构如下,在pom.xml 增加plugins,使用jdk1.8编译整个项目,并且指定整个项目的spring-boot-parent
部分pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>4.0.0org.lyn.bazinga dubbo-spring-boot-skeleton 1.0.01.82.1.8.RELEASEorg.springframework.boot spring-boot-starter-parent ${spring-boot-version}importpomorg.apache.maven.plugins maven-compiler-plugin 3.31.81.8UTF-8
2.4 接下来我们创建服务提供者的接口层,右击dubbo-spring-boot-skeleton,选择New,然后选择Module,同创建构架工程一样,选择Maven,点击Next
与创建父工程一样,依旧选择maven,点击Next
我们先创立dubbo的服务提供者模块,模块名叫做dubbo-spring-boot-provider,因为你创建的是Module,所以你的parent和groupId是无法编辑的,你填写一个有意义的artifactId,因为我们是提供者所以命名中有”provider”,点击Next
最后确认好你的模块名,项目所在系统路径,点击Finish之后,整个项目结构变成了如下图所示
整个项目的骨架图如下图所示
同理,我们也新建好我们的dubbo消费者模块,操作方式也跟上面创建服务提供者的方式一样,建立好的模块图也就变成了这样
到此为止,我们已经搭建好了我们项目的基本骨架,现在就需要开始思考,因为dubbo是面向接口的,服务提供者提供接口的jar,然后服务的消费者只依赖该接口,但是并没有实现,就可以完整整个调用,所以我们这边应该还有一个最基础的模块API模块,我们刚才创建的provider和consumer都需要依赖这个模块,不过provider是这个api接口的具体实现,consumer只是依赖这个接口的jar包,创建这个api模块也跟上面创建provider和consumer一样,最后创建结束的效果骨架图如下所示,哈哈,目前为止还是非常简单的
我们在dubbo-spring-boot-api模块新建包然后创建一个简单的接口定义
正如我们上面所说, 因为dubbo是基于接口编程的,我们的dubbo-spring-boot-api 在真实环境下会被打成jar包上传到公司的本地私有仓库,然后服务消费者会引用该jar包,然后就可以在dubbo的支持下,实现调用远程接口就像调用本地一样的效果了,所以服务提供者模块实现HelloService接口的具体业务实现 ,接下来我们完整服务提供者端完整的代码书写
3.1 dubbo-spring-boot-provider中的pom.xml的几个关键配置
3.1.1 首先在pom.xml 增加spring boot的plugin,这样在使用java -jar的时候,能够找到spring boot的main函数
org.springframework.boot spring-boot-maven-plugin 2.1.8.RELEASEpackagerepackagetrue
3.1.2 我们引入spring-boot的基本依赖
org.springframework.boot spring-boot-starter ${spring-boot-version}org.springframework.boot spring-boot-starter-web ${spring-boot-version}org.springframework.boot spring-boot-autoconfigure ${spring-boot-version}org.springframework.boot spring-boot-starter-actuator ${spring-boot-version}
3.1.3 我们需要引入dubbo-spring-boot-api,因为现在的模块和dubbo-service-provider-api是同parent,所以可以直接引入
dubbo-spring-boot-api org.lyn.bazinga1.0.0
3.1.4 我们现在dubbo-spring-boot-provider中给出HelloService接口的最简单实现
3.1.5 最后因为我们要请我们的主角登场,那就是dubbo,因为服务提供者端和服务消费者端都需要dubbo的jar包的依赖,所以dubbo的依赖我们放在dubbo-spring-boot-skeleton父工程中,这样子工程就不需要重复导入了,所在在父工程的pom.xml中引入如下maven依赖,注意不在dependencyManagement中,而是就是根依赖中
org.apache.dubbo dubbo-spring-boot-starter 2.7.0org.apache.dubbo dubbo 2.7.0org.apache.curator curator-framework 4.0.1org.apache.curator curator-recipes 4.0.1org.apache.zookeeper zookeeper 3.4.13
3.1.6 最后就轮到经典的SpringBoot的main函数启动类的书写了
3.1.7 记住,别忘记还有我们的一些简单配置,例如我们tomcat的启动端口啊,dubbo的默认扫包路径啊,dubbo使用的协议等等,我们都需要再application.properties中配置
server.port=10086# Spring boot applicationspring.application.name=dubbo-spring-boot-provider# Base packages to scan Dubbo Component: @org.apache.dubbo.config.annotation.Servicedubbo.scan.base-packages=com.lyn.bazinga.service# Dubbo Application## The default value of dubbo.application.name is ${spring.application.name}## dubbo.application.name=${spring.application.name}# Dubbo Protocoldubbo.protocol.name=dubbodubbo.protocol.port=12345## Dubbo Registrydubbo.registry.address=zookeeper://localhost:2181
3.1.8 到此为止完整的服务提供者端就算完成了,看下基本骨架截图
3.2 启动SpringBootDubboProviderApplication的main函数发现并没有报错,并成功在10086端口监听
到此为止服务提供者端的代码就完整结束了,接下来我们只要如法炮制,完成服务消费端的代码编写就可以收工了
4.1 dubbo-spring-boot-consumer端的pom.xml与dubbo-spring-boot-provider端是一模一样的,这边只要copy一下就ok了
4.1.1 首先我们写一个简单的Service,ConsumerService和其对应的实现类,这边的@Service是spring的注解,@Reference是dubbo的注解,这边需要注意
package org.lyn.bazinga.service.impl;import org.apache.dubbo.config.annotation.Reference;import org.lyn.bazinga.service.ConsumerService;import org.lyn.bazinga.service.api.HelloService;import org.springframework.stereotype.Service;@Servicepublic class ConsumerServiceImpl implements ConsumerService { @Reference(version = "1.0.0") private HelloService helloService; @Override public String hello(String name) { return helloService.hello(name); }}
4.1.2 然后我们通过一个Controller将其暴露出去
package org.lyn.bazinga.controller;import org.lyn.bazinga.service.ConsumerService;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestControllerpublic class HelloController { @Resource private ConsumerService consumerService; @GetMapping("/hello/{name}") public String hello(@PathVariable String name){ return consumerService.hello(name); }}
4.1.3 依旧是spring boot的main函数启动类和配置文件application.properties
package org.lyn.bazinga;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class SpringBootDubboConsumerApplication { public static void main(String[] args) { SpringApplication.run(SpringBootDubboConsumerApplication.class,args); }}
application.properties
server.port=10087# Spring boot applicationspring.application.name=dubbo-spring-boot-consumerserver.servlet.context-path=/dubbo-spring-boot-consumer## Dubbo Registrydubbo.registry.address=zookeeper://localhost:2181
4.1.4 完整的dubbo-spring-boot-consumer的代码结构如下
三.测试整个链路
先启动服务提供者的main函数SpringBootDubboProviderApplication
然后再启动SpringBootDubboConsumerApplication
最后我们在浏览器中简单的访问一下URL:http://localhost:10087/dubbo-spring-boot-consumer/hello/lyncc
可以正常的返回结果:”spring boot & docker &lyncc ” 说明我们整个链路全部打通了,大功告成
四 小结
1.首先先创建服务提供者,服务提供者在java开发中需要分模块创建,因为服务提供接口需要单独打成jar包,给服务消费者引用调用
2.服务提供者将服务的信息注册到zookeeper,监听本地的tcp12345的端口,等待客户端连接
3.服务消费者,发现自己需要调用com.bazinga.service.HelloService 版本是1.0.0的服务,服务消费者dubbo-spring-boot-consumer 把这个订阅信息发送给zookeeper,zookeeper返回这个服务的地址是ip:12345的地址,然后服务消费者使用Netty发送一个tcp请求,成功建立连接之后,服务提供者把结果返回
如果您看到这里,希望您点个关注,本文依旧原创,虽然很简单,也很入门,毕竟一步一个脚印吧,本文的代码也是比较多,希望PC端查看,如果是java的新手观众,建议一起手敲一下代码,先了解一下,java高手老爷们,有哪些做的不对的可以批评指正,接下来的一篇文章,应该是本地搭建新的Dubbo Admin,我们可爱的Dubbo服务治理控制台