⾛进Dubbo——编写⼆⽅包、服务提供者和消费者
前⾔
从这⼀章开始搭建Dubbo环境,也就是使⽤者最期待的⼲货——如何编写⼀个Dubbo版的HelloWorld程序?
为了演⽰⽅便,更重要的是为了⽅便Bean的管理等资源,特地引⼊Springboot帮我们搭建Web环境。
本⽂分为⼆⽅包的编写、Springboot环境搭建、服务提供⽅编写、服务消费者编写四个部分。
⾸先说明,⼆⽅包、服务提供者、服务消费者都需要单独打包,也就是位于三个不同的项⽬中。
demo源码已经,
⼆⽅包的编写
我们从最简单的过程开始。⼆⽅包的编写很简单,新建⼀个maven项⽬,创建⼀个名为edu.hsftest.api的包,然后包下创建⼀个接⼝
package;
public interface IHelloWorld {
String say(String name);
}
不需要引⼊额外的依赖,然后我们在idea的terminal(或者进⼊项⽬根⽬录下,打开终端/cmd)输⼊构建指令(哦,还得保证你配置过maven,没配置过请百度⼀下吧)
mvn package
然后去项⽬的target⽂件夹下到api-1.0-SNAPSHOT.jar⽂件,以备后续使⽤。
也可以参考后⾯关于,将⼆⽅包安装在本地仓库下,执⾏
mvn install
这样后续就可以按正常⽅式引⼊依赖
Springboot环境搭建
最简单的⽅式是通过SpringInitializr创建,可以参见,不再赘述。
我⾃⼰是通过⼿动配置pom来做的,因为想体验⼀下配置过程:)
简⽽⾔之,parent标签配置spring-boot-starter-parent,dependencies配置spring-boot-starter-web就⼤功告成了。⼀开始没有配置parent,导致很多springboot的功能都⽆法使⽤。
配置完依赖之后,需要编写main+controller,最终搭建⼀个最基础版本的⽹页,代码就不附了,给⼀个
这就是最简单的⽹页,实在懒得复读过程了,⼤家可以参考给出的链接。然后我们开始做⼀些和dubbo有关的事情,go~
Dubbo消费者编写
之所以不先说⽣产者,是因为消费者的代码更复杂些,还需要包含Controller等代码。
依赖添加
这⾥我们根据来,先在pom⾥添加两个依赖(注意,是添加!)。这⾥我们采⽤的是2.7.12版本的dubbo。别忘了还有个⼆⽅包需要加⼊进来,是通过系统绝对路径的⽅式引⼊。这会在打包的时候造成⼀些问题,但是我们先忽略它,因为这样是可以运⾏的。如果之前将⼆⽅包安装在本地仓库了,那也可以和其它包⼀样正常引⼊。
<properties>
<dubbo.version>2.7.12</dubbo.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
springboot结构</dependency>
<dependency>
<groupId>edu.dubbotest</groupId>
<artifactId>api</artifactId>
<version>1.0-SNAPSHOT</version>
<systemPath>{这⾥请填写⼆⽅包jar包绝对路径}</systemPath>
<scope>system</scope>
</dependency>
</dependencies>
编写SpringBoot的启动类
然后因为我们采⽤了Springboot,所以也要使⽤Springboot喜欢的注解⽅式来进⾏配置。
package;
import SpringApplication;
import SpringBootApplication;
/**
* Main类,最好配置⼀下包扫描,提⽰SpringBoot在这个包⽬录下还有⼀些配置或者组件。
* 这⾥我们明⽰了两个包,分别是dubbo的包和controller的包
* @author chenly
*/
@SpringBootApplication(scanBasePackages ={"edu.dubbotest.dubbo","ller"})
public class Application {
public static void main(String[] args){
// SpringBoot就是这么启动的,第⼀个参数表⽰它的根配置类是哪个,SpringBoot可以根据这个配置类上的注解读取配置 SpringApplication.run(Application.class, args);
}
}
编写Dubbo的配置类
还需要编写⼀个Dubbo的配置类
package;
import EnableDubbo;
import Configuration;
/**
* 单纯地配置了启⽤dubbo,并且设定dubbo的扫描路径,其实现在不需要扫描任何包
* @author chenly
*/
@Configuration
@EnableDubbo(scanBasePackages ={"edu.k"})
public class DubboConfiguration {
}
插⼊⼀段说明
到这⾥⼀般的博⽂不会停,⽽是直接⼀串下来把代码贴完。但是我不是为了秀代码⽽来,毕竟demo都已经给出,所以应该把demo⾥的细节都讲清楚。
相信各位同学见过不少这样的SpringBoot代码,⼀个启动类配置了包扫描,此外还有⼀堆配置类。配置类有时候只有⼀些注解,内部是空的,第⼀眼看上去还是挺懵逼的,有时候依葫芦画瓢却不知道为什么。
我尽量不去触及SpringBoot的太晦涩的知识,我只解释⼀下注解和这⾥⽤到的注解参数
注解:⽤法很简单,就是@XXXX。同学们可以认为注解就是给类加了个标识,通过这些标识,我们能写⼊/获得⼀些额外信息。⽐如我们⽤到的下⾯的注解
@SpringBootApplication:表明以SpringBoot⽅式启动。SpringBoot集成了很多东西,简单的开发⼀个Web项⽬⾮常快,能做后台处理业务逻辑,也能做web服务器把前端页⾯返回给浏览器。
@Configuration:表明这是⼀个配置类,含有⼀些应⽤配置
@EnableDubbo:表明启⽤Dubbo功能,Dubbo⽤起来很简单,这是因为Dubbo框架在幕后为我们做了很多⼯作。这些⼯作的启动也是⽐较费时的,所以需要显式启⽤Dubbo
注解参数:写在注解括号⾥的就是注解的参数,可以认为是注解包含的可供⽤户⼿动配置的配置项。这⾥⽤到的唯⼀⼀个注解参数是scanBasePackages,表明在这个⼦包下还有⼀些配置和组件需要处理,希望框架扫描这个包下的所有类,处理这些类的配置信息(实际上⼤部分都是注解信息)
我们的项⽬结构是这样的
- dubbo
- mock
- *IHelloWorldMock.java*
- *DubboConfiguration.java*
- controller
- *TestController.java*
- *Application.java*
因此最终的注解配置含义⼤致如下
我们在main函数内启动SpringBoot时,指定了⼀个根配置类,是Application.class
Application类上的注解表明我们是⼀个SpringBoot应⽤,⽽且需要额外扫描"edu.dubbotest.dubbo",
"ller"两个包。这两个包⾥分别存储着我们的dubbo配置和web响应api
"edu.dubbotest.dubbo"包下,到了DubboConfiguration配置类,⽽且拥有⼀个Spring的注解@Configuration,Spring会⾃动将其加载,以供dubbo框架进⾏⾃定义的处理
Dubbo框架的对所有Spring加载的实例进⾏筛查,到具有dubbo相关注解的类,⽐如DubboConfiguration类,启⽤了Dubbo,并且设定了dubbo相关类的包扫描路径。于是它接着扫描"edu.k"包下的类
最终,框架(包括Spring和Dubbo)除了启⽤了相关的功能之外,还发现了我们编写的TestController类和IHelloWorldMock类。
不过,到这⾥还不够。
在TestController类中(下⾯⼀段会讲到),Spring发现了⼀个@Controller接⼝,明⽩这是⼀个Web请求处理类,并且其index()⽅法上拥有⼀个@GetMapping("/")注解,表明访问主页的(GET)请求都要交给这个函数处理。因此Spring将其缓存并注册到url映射组件中
在IHelloWorldMock类中,Dubbo发现了⼀个@DubboService注解,于是明⽩这是⼀个服务提供者的实现,所以将它实例化、缓存起来,并将其接⼝名等注册到服务发现组件上
到这⾥解释完了吗?还差⼀点点。我们缓存了这些类,什么时候⽤呢?
在服务提供者被远端调⽤时(此时,服务提供者是本地,消费者是远端了),Dubbo会根据请求的接⼝类型,从缓存中取出合适的服务实现者,将⽹络传来的参数分离出来交给本地函数处理
在浏览器访问后端api接⼝的根⽬录时(或者理解为后端的“主页”),Spring会⾃动根据url路径到合适的处理类,调⽤合适的处理函数,并将返回值通过http协议传回浏览器
到这⾥,我们就把框架做了什么说得⽐较清楚了(细节不够严谨,还望见谅)。我们需要显式地(通过注解等配置⽅式)告诉框架,希望它让我们完成什么⼯作,框架会根据注解⾥标明的参数进⾏处理。
编写controller
编写完controller后,就可以通过⽹页展⽰效果了。
package;
import IHelloWorld;
import DubboReference;
import Logger;
import LoggerFactory;
import GetMapping;
import RestController;
/**
* 单纯地打印⼀句话
* @author chenly
*/
@RestController
public class TestController {
Logger logger = Logger(TestController.class);
/
/ 使⽤起来⾮常简单,⼀个注解就ok
@DubboReference
IHelloWorld helloWorldConsumer;
// 将主页的Get请求映射到这个函数进⾏处理
@GetMapping("/")
String index(){
logger.info("we are dubbo!");
// 调⽤代码就和普通的类没什么两样
return helloWorldConsumer.say("xiaoming");
}
}
最后的最后,还需要⼀个配置⽂件,来说明dubbo的应⽤名、注册中⼼地址等信息,配置⽂件的配置⽅式可以参考这个,同时对照着来看。dubbo的⽂档真的好少,百度⼀下的必不可少。
dubbo:
application:
name: dubbo-test-consumer # 这⾥写明了应⽤名
qosEnable:false# 这⾥的qos是⼀个dubbo的管理平台,为了避免额外的报错,我们先给他关了
registry:
address: zookeeper://127.0.0.1:2181# 这⾥写明了注册中⼼的地址,zookeeper的东西过⼀会⼉再解释
provider:
protocal: dubbo # 通信协议选择dubbo私有协议
port:-1# -1表⽰不使⽤特定的端⼝,⽅便我们调试,也可以证明服务⾃动发现功能是多么的必要
Dubbo⽣产者的编写
⽣产者除了配置⽂件⾥要改⼀下名字之外,基本相同。哦,还需要编写接⼝的实现类
package;
import IHelloWorld;
import DubboService;
import Logger;
import LoggerFactory;
import Random;
/**
* dubbo⽣产者
* @author chenly
*/
@DubboService
public class HelloWorldImpl implements IHelloWorld {
Logger logger = Logger(HelloWorldImpl.class);
// 这⾥的id⽤于标识⽣产者,这样可以区分不同的⽣产者
static int id;
static{
id =new Random().nextInt();
}
@Override
public String say(String name){
logger.info("正常dubbo测试");
return"hello, "+ name +" from "+ id;
}
}
到这⾥为⽌,所有代码的讲解都已经完成了,相信⼤家对于代码也会有更深的理解。
运⾏
既然是demo,肯定得展⽰⼀下——不过在这之前,请先运⾏zookeeper。zookeeper是dubbo⽤于注册发现⽽使⽤的第三⽅依赖,关于zookeeper不做过多解释,使⽤也不复杂,可以百度⼀下怎么下载运⾏,也可以根据后⾯的docker教程,使⽤docker运⾏
然后在idea中分别启动服务提供者和服务消费者,打开浏览器,输⼊127.0.0.1:8080(如果实际端⼝没有修改的话),应该可以看到hello, xiaoming from -1494505934
最后⼀串数字是随机⽣成的,所以你可能会看到别的数字
如果出现了⼀些错误没法运⾏(⽐如⽆法连接Zookeeper),或者懒得配Zookeeper想跳过这⼀步,那可以接着往下看,因为我的⽬标是docker部署,因此在之前都不太好完全跑起来看效果
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论