【Dubbo】Zookeeper+Dubbo项目demo搭建
一、Dubbo的注解配置
在Dubbo 2.6.3及以上版本提供支持。
1、@Service(全路径@org.apache.dubbo.config.annotation.Service)
配置服务提供方用以暴露服务,添加于api接口的实现类上,并可通过注解提供的属性进一步定制化服务。
其中比较重要的属性有:
- @Service只能定义在一个类上,用以提供一个服务的具体实现
- interfaceClass:指定服务提供方实现的interface的类
- interfaceName:指定服务提供方实现的interface的类名
- version
- group:指定服务分组
- export:是否暴露服务
- register:是否向注册中心注册服务
- application:应用配置
- module:模块配置
- provider:服务提供方配置
- protocol:传输层协议配置
- monitor:监控中心配置
- registry:注册中心配置
注意,8-13需要提供对应的spring bean的名字,bean的组装可以通过传统的XML配置方式完成,或者Java Config的方式配置(推荐使用)。
2、@Reference(全路径@org.apache.dubbo,config.annotation.Reference)
服务消费方用以引用服务,通过动态代理来实现接口的引用,同样可通过注解提供的属性进一步定制化服务。
其中比较重要的属性有:
- @Reference通常定义在一个字段上,表示一个服务的引用
- interfaceClass:指定服务的interface的类
- interfaceName:指定服务的interface的类名
- version
- group
- url:指定服务提供方的URL地址,绕过注册中心直接发起调用
- application:应用配置
- module:模块配置
- consumer:服务消费方配置
- protocol:协议配置
- monitor:监控中心配置
- registry:注册中心配置
同上,7-12需要提供对应的spring bean的名字,推荐使用Java Config的方式进行组装Bean。
3、@EnableDubbo(全路径org.apache.dubbo.config.spring.context.annotation.EnableDubbo)
@EnableDubbo注解是@EnableDubboConfig和@DubboComponentScan两者组合的便捷表达。
@EnableDubbo提供scanBasePackages和scanBasePackageClasses属性,可以在指定的包名或者类中扫描Dubbo的服务提供者(@Service标注)和服务消费者(@Reference标注),扫描到服务的提供者或消费者后,对其进行相应的组装并初始化, 最终完成服务的暴露或引用。
扫描提供者和消费者的功能@DubboComponnetScan也可以实现,@EnableDubboConfig提供外部化配置的支持。
二、Dubbo的API属性配置
目前,通过@Service、@Reference、@EnableDubbo注解,实现了服务的暴露和发现引用,除此之外,还需要一些其他的属性配置,诸如应用名、注册中心、协议信息等。
1、Dubbo中配置类结构
2、注入这些配置属性,有两种方式,分别是采用配置文件和Java Config硬编码的形式。
2.1、配置文件方式
在resources下创建xxx.properties文件,在其中添加各项属性配置,形式如下:
dubbo.application.name=provider
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
然后通过@PropertySource("classpath:/xxx.properties")注解导入配置;
导入属性在启动时,会被自动组装成相应的配置类。
2.2、Java Config硬编码方式
创建providerConfiguration类,标注@Configuration注解;
在该类中,通过@Beab的形式分别配置需要的配置类,如下:
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("provider");
return applicationConfig;
} @Bean
public ProtocolConfig protocolConfig() {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setName("dubbo");
protocolConfig.setPort("20880");
return protocolConfig;
} @Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setProtocol("zookeeper");
registryConfig.setAddress("localhost");
registryConfig.setPort(2181);
return registryConfig;
}
在具体实现中,创建Config类,通过Java Config技术(@Configuration)和annotation扫描(@EnableDubbo)来发现、组装服务提供者和消费者。
三、其他相关Spring注解
1、@Configuration(全路径org.springframework.context.annotation.Configuration)
@Configuration注解用来定义配置类,可替换XML配置文件,被注解类内有多个@Bean标注方法,这些方法会被AnnotationConfigApplicationContext或者AnnotationConfigWebApplicationContext类进行扫描,用于构建bean并初始化spring容器。
@Configuration注解的配置类有以下要求:
- @Configuration注解的配置类不可以是final类型。
- 内部嵌套的内部Configuration类必须是静态类。
1.1、@Configuration配置spring并启动spring容器
起到为spring容器配置应用上下文的作用:
ApplicationContext context = new AnnotationConfigApplicationContext(TestConfiguration.class);
效果等价于用XML文件配置:
ApplicationContext context = new ClassPathXmlApplicationContext("test-spring-context.xml");
1.2、@Configuration启动容器+@Bean注册bean,@Bean下管理bean的生命周期
@Bean标注在方法上,作用相当于注册Bean,注意:
- @Bean标注在返回实例的方法上,如果未通过@Bean指定bean的名称,默认与标注方法名同名。
- @Bean标注默认bean作用域为单例singleton,可通过@Scope()设置。
- @Bean的作用是注册bean,因此也可以用@Component、@Controller、@Service、@Repository等进行注册,不过需要配置@ComponentScan注解进行自动扫描。
- 可以通过@Bean管理bean的生命周期。
1.3、组合多个配置来源
通过@ImportSource("classpath:/xxx.xml")导入XML配置文件;
通过@Import(TestConfiguration.class)导入其他配置类;
通过@Configuration嵌套(嵌套额Configuration类必须为静态类)。
2、@Component、@Service、@Controller、@Repository、@RestController、@Bean
修饰的类均会被扫描到并注入到spring的bean容器中。
2.1、@Component
通用注解,可以被注入到spring容器进行管理。
2.2、@Service、@Controller、@Repository是针对不同使用场景采用的特定功能化的注解组件。
- @Service:作用于业务逻辑层
- @Controller:作用于表现层(springMVC注解),注解的bean会被spring-mvc框架使用,进行前端请求的处理、转发、重定向,包括调用service层的方法
- @Repository:作用于持久层,表明该类是用来执行与数据库相关的操作,并支持自动处理数据库操作产生的异常
2.3、@Controller和@RestController
首先两者都是表明该类可以接受HTTP请求,@RestController相当于@Controller+@ResponseBody的作用。
在@RestController中,返回的应该是一个对象,即使没有前端界面的渲染,也可以看到返回的是该对象对应的json字符串,而前端的作用就是利用返回的json进行解析并渲染界面。
在@Controller中,返回的是一个字符串,或者代表与字符串匹配的模板名称,与HTML页面配合使用。
- 如果只是用@RestController注解,则Controller方法中无法返回jsp页面,配置的视图解析器InternalResourceViewResolver不起作用,返回的内容就是方法中return的值。
- 如需要指定返回某个页面,则需要用@Controller配合视图解析器InternalResourceViewResolver使用。
- 如果需要返回Json、XML或自定义的mediaType内容到页面,@RestController直接就能做到,但在@Controller中需要在相应方法上加上@ResponseBody注解。
2.4、@Bean和@Component(@Service、@Controller、@Repository)的区别
- @Component注解表明一个类作为组件类,并告知spring为该类创建bean。
- @Bean注解告诉spring这个方法将返回一个对象,该对象要注册为spring应用上下文中的bean。
两者目的都是注册bean到Spring容器中。
- @Component通常是通过类路径扫描来自动侦测并自动装配到spring容器中。作用于类。
- @Bean注解通常是我们在标有该注解的方法中自定义产生这个bean的逻辑。作用于方法。
3、@Autowired、@Resource
@Autowired默认按照类型装配。
默认要求依赖的对象必须存在,若允许为NULL,可以设置required属性为false。
@Resouce默认按照名称装配。
可以通过name属性指定,指定了name属性,就只能按照名称装配。
有两个重要的属性,name和人type,将name属性解析为bean的名字,type解析为bean的类型。
使用了name属性,则使用byName的自动注入策略;而使用type属性,则使用byType的自动注入策略。
@Resouce的装配顺序:
- 同时指定了name和type属性,从spring上下文找到唯一匹配的bean进行装配,找不到则抛出异常。
- 指定了name属性,从上下文查找名称匹配的bean进行装配,找不到则抛出异常。
- 指定了type属性,从上下文查找类型匹配的唯一bean进行装配,找不到或者找到多个则抛出异常。
- 属性均未指定,则默认按照byName的方式进行查找装配。
4、@PropertySource、@ImportResource
@ImportResource:导入spring的配置文件,如xxx.XML。
@PropertySource
@ConfigurationProperties是默认从全局配置文件中获取指定的值,例如@ConfigurationProperties(prefix=“person”)是从application.yml(properties)中加载person的属性并映射到对应类的属性。
如果配置在xxx.properties中(非全局配置文件),就需要用@PropertySource(value={"classpath:/xxx.properties"})导入指定配置文件。
四、项目搭建流程
1、注册中心Zookeeper搭建
Zookeeper的安装不在此介绍,可参考:Zookeeper单点与集群安装
2、项目框架搭建
创建maven项目hello_dubbo,删掉其中的src文件夹,并添加对spring-boot的依赖,作为整个项目运行环境。
新建new module,依次为api(服务接口公共包)、provider(服务提供者模块)、consumer(服务消费者模块),。
此时项目结构如图:
pom文件关键信息为:
<groupId>com.li</groupId>
<artifactId>hello_dubbo</artifactId>
<version>1.0-SNAPSHOT</version> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/>
</parent> <modules>
<module>api</module>
<module>provider</module>
<module>consumer</module>
</modules>
hello_dubbo_pom.xml
3、api包
在pom文件中配置依赖关系:
<parent>
<groupId>com.li</groupId>
<artifactId>hello_dubbo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent> <artifactId>api</artifactId>
api_pom.xml
在api包中创建要对外提供服务的接口类HelloAPI.java:
package com.li.api; public interface HelloApi { public String sayHello(String name);
}
HelloApi
此时的api模块结构:
4、provider项目
1、修改pom文件,添加相关依赖:
<parent>
<groupId>com.li</groupId>
<artifactId>hello_dubbo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent> <artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>provider</name> <dependencies>
<!--web支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--添加Zookeeper依赖-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.5</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加Dubbo依赖,已并入apache-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.3</version>
</dependency>
<!--添加zookeeper客户端框架Curator-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--添加对API模块的依赖-->
<dependency>
<groupId>com.li</groupId>
<artifactId>api</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
provider_pom.xml
2、添加service包,在其中创建api接口的实现类,提供服务的具体实现,并用@Service暴露服务:
package com.li.provider.service; import com.li.api.HelloApi;
import org.apache.dubbo.config.annotation.Service; @Service
public class HelloService implements HelloApi { @Override
public String sayHello(String name) {
return "hello " + name;
}
}
HelloService
3、provider的配置注入方式选择采用properties文件的形式。
在resources下添加provider.properties配置文件:
dubbo.application.name=helloP
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
server.port=8001
provider.properties
在主目录下创建Configuration类,作为配置类:
package com.li.provider; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource; @Configuration
@EnableDubbo(scanBasePackages = "com.li.provider.service")
@PropertySource("classpath:/provider.properties")
public class ProviderConfiguration {
}
ProviderConfiguration
4、启动类选择springBoot启动:
package com.li.provider; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class ProviderApplication { public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
} }
ProviderApplication
5、至此,Provider模块完成,项目结构如下:
5、consumer项目
1、修改pom文件,添加相关依赖:
<parent>
<groupId>com.li</groupId>
<artifactId>hello_dubbo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent> <artifactId>consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>consumer</name> <dependencies>
<!--web支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--添加Zookeeper依赖-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.5</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加Dubbo依赖,已并入apache-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>2.7.3</version>
</dependency>
<!--添加zookeeper客户端框架Curator-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--添加对API模块的依赖-->
<dependency>
<groupId>com.li</groupId>
<artifactId>api</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
consumer_pom.xml
2、创建action包,新增HelloAction类,作为MVC框架的service层,提供业务逻辑处理并利用@Reference提供对远程服务的引用:
package com.li.consumer.action; import com.li.api.HelloApi;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service; @Service //注意为spring的@Service注解,将其作为bean管理
public class HelloAction { @Reference(check = false)
private HelloApi helloApi; public String doHello(String name) {
return helloApi.sayHello(name);
}
}
HelloAction
3、创建controller包,新增HelloController类,作为MVC框架的controller层,提供前端请求的转发,以及业务逻辑的调用:
package com.li.consumer.controller; import com.li.consumer.action.HelloAction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; @RestController
public class HelloController { @Autowired
private HelloAction action; @GetMapping("/hello")
public String hello(@RequestParam("name")String name) {
return action.doHello(name);
}
}
HelloController
4、consumer的配置注入方式选择采用Java Config硬编码的形式。
在resources下添加consumer.properties配置文件:
server.port=8002 //注册对外提供服务的端口
consumer.properties
在主目录下创建Configuration类,作为配置类:
package com.li.consumer; import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource; @Configuration
@PropertySource("classpath:/consumer.properties")
public class ConsumerConfiguration { @Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig config = new ApplicationConfig();
config.setName("helloC");
return config;
} @Bean
public RegistryConfig registryConfig() {
RegistryConfig config = new RegistryConfig();
config.setAddress("zookeeper://127.0.0.1:2181");
return config;
}
}
ConsumerConfiguration
5、启动类选择springBoot启动:
package com.li.consumer; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class ConsumerApplication { public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
} }
ConsumerApplication
6、至此,Consumer模块完成,项目结构如下:
6、项目启动
项目启动时,首先启动Zookeeper,命令行执行zkServer.cmd。
正常启动顺序应该先启动提供者,然后启动消费者,因为@Reference注解在启动时默认会去注册中心检查所引用服务状态是否正常提供服务,若想先启动消费者,可选择关闭检查功能,@Reference(check=false)。
全部启动后,可打开zk客户端查看已注册服务情况。
最后打开浏览器,访问localhost:8002/hello?name=world发现正常引用服务。
【Dubbo】Zookeeper+Dubbo项目demo搭建的更多相关文章
- Dubbo项目demo搭建
项目参考: http://dubbo.io/User+Guide-zh.htm https://my.oschina.net/superman158/blog/466637 项目使用 maven+id ...
- ZooKeeper+Dubbo+SpringBoot 微服务Demo搭建
1. 首先创建springBoot项目,springBoot是一堆组件的集合,在pom文件中对需要的组件进行配置.生成如下目录结构 创建test项目,同步在test创建dubbo-api,dubbo- ...
- Java学习之Dubbo+ZooKeeper分布式服务Demo
背景:在之前的一个<Java学习之SpringBoot整合SSM Demo>分享中说到搭建ZooKeeper和Dubbo分布式框架中遇到了一些技术问题没能成功,只分享了其中的一个中间产物, ...
- [dubbo实战] dubbo+zookeeper伪集群搭建
zookeeper作为注册中心,服务器和客户端都要访问,如果有大量的并发,肯定会有等待.所以可以通过zookeeper集群解决. 一.为什么需要zookeeper呢? 大部分分布式应用需要一个主控.协 ...
- [dubbo实战] dubbo+zookeeper伪集群搭建 (转)
zookeeper作为注册中心,服务器和客户端都要访问,如果有大量的并发,肯定会有等待.所以可以通过zookeeper集群解决. 一.为什么需要zookeeper呢? 大部分分布式应用需要一 个主控. ...
- spring+hibernate项目demo搭建
之前用maven+spring+mybatis+spring mvc搭建了一个web项目,用于学习spring及相关知识,现在打算将mybatis换成hibernate,一样搭建一个框架. 其实myb ...
- SpringBoot+Dubbo+Zookeeper 实例
前言 当下Java 生态环境里面,微服务占据了非常大的份额,现在大部分新开发的 Java选型的后台程序都很奇妙的会跟微服务发生一些关系.那目前市面上主流的微服务方向主要有 Spring 家族推出的Sp ...
- 搭载Dubbo+Zookeeper踩了这么多坑,我终于决定写下这篇!
大家好,我是melo,一名大二上软件工程在读生,经历了一年的摸滚,现在已经在工作室里边准备开发后台项目啦. 这篇文章我们不谈数据结构了,来谈谈入门分布式踩过的坑.感觉到了分布式这一层,由于技术更新迭代 ...
- Dubbo + Zookeeper 简单配置
Dubbo + Zookeeper Zookeeper 下载及配置 下载到本机/usr/local目录 wget https://mirrors.tuna.tsinghua.edu.cn/apache ...
随机推荐
- 表达式树练习实践:C# 循环与循环控制
目录 表达式树练习实践:C# 循环 LabelTarget for / while 循环 无限循环 最简单的循环 多次循环 break 和 continue 一起 表达式树练习实践:C# 循环 C# ...
- Java位运算符&、|、^、>>、<<、~、>>>
如果要搞懂Java中的位运算符,首先要搞懂二进制的运算,之前一篇有介绍详细请看 二进制运算-十进制与二进制的转换 Java中的位运算符有:&(按位与).|(按位或).^(按位异或).>& ...
- Python学习-字符编码, 数据类型
本篇主要内容: 字符编码 Python中的数据类型有哪些 类型的一些常用操作及方法 一.字符编码 编码解释的大部分内容摘自廖雪峰老师教程中的讲解,点击跳转. 简单介绍: 我们知道计算机只能处理数字,如 ...
- 第六届蓝桥杯java b组第三题
第三题 三羊献瑞 观察下面的加法算式: 其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字. 请你填写“三羊献瑞”所代表的4位数字(答案唯一),不要填写任何多余内容. 答案这个题目完全可以使用暴 ...
- 暑期——第三周总结(Ubuntu系统安装eclipse问题【已解决】)
所花时间:7天 代码行:200(python)+150(java) 博客量:1篇 了解到知识点 : 一: Python: 问题 unresolved reference xrange 解决方案 pyt ...
- uni-app实现滑动切换效果
在对于uni-app框架了解之后,今天就实现一个滚动切换tab效果,这个很常见的一个效果,最后封装成一个组件,便于以后使用,写这个需要引入uni官方提供的uni.css样式,用到了写好的样式,就不需要 ...
- MySQL命令窗口出现中文乱码的解决方法
查询表语句的时候,出现了中文乱码,但是用Navicat for MySQL查看的时候却是正常的,字符集都是设置的utf-8,如下图所示: 其实上大学学习java的时候也遇到了中文乱码但是却没有 ...
- docker容器添加对外映射端口
一般在运行容器时,我们都会通过参数 -p(使用大写的-P参数则会随机选择宿主机的一个端口进行映射)来指定宿主机和容器端口的映射,例如 docker run -it -d --name [contain ...
- 玩转 SpringBoot 2 之整合 JWT 上篇
前言 该文主要带你了解什么是 JWT,以及JWT 定义和先关概念的介绍,并通过简单Demo 带你了解如何使用 SpringBoot 2 整合 JWT. 介绍前在这里我们来探讨一下如何学习一门新的技术, ...
- jobs后台任务
前台作业:占据了命令提示符,就是你当前可以操作的作业后台作业:启动之后,释放命令提示符,后续的操作在后台完成 前台——>后台 ctrl+z:把正在前台的作业送往后台,这时作业的状态是暂停. CO ...