技术文章第一时间送达!php
SpringBoot愈来愈热门以致于达到烂大街可见的程度,而Dubbo这个基于二进制的微服务框架又捐献给Apache孵化,若是不会如何使用那么是否是很很差意思呢?java
此次从公司的项目中抽一个小列子来熟悉下若是从零构建,至于深刻了解->传送门:Dubbo官方中文手册git
Springboot2.xweb
Double2.6spring
Zk3.4.14apache
JDK8api
这里就不介绍Dubbo了缓存
下载去官网查找稳定的版本进行使用:安全
http://www.apache.org/dyn/closer.cgi/zookeeper/springboot
先在服务器上安装zookeeper。
cd /usr/local/src/ #下载 sudo wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz #解压 tar -zxvf zookeeper-3.4.14.tar.gz #修改配置文件名称 mv conf/zoo_sample.cfg zoo.cfg #启动zk ./bin/zkServer.sh start #出现如下字样表明启动成功,默认端口2181 Starting zookeeper ... STARTED
父工程搭建(pom工程)
<groupId>com.simple.springboot</groupId> <artifactId>yun-double</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <name>yun-double</name> <description>double</description> <!--统一管理依赖版本--> <properties> <java.version>1.8</java.version> <double.version>2.0.0</double.version> <zkclient.version>0.10</zkclient.version> </properties> <!-- 依赖于SpringBoot --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.4.RELEASE</version> <relativePath/> </parent> <!--依赖定义--> <dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>${double.version}</version> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>${zkclient.version}</version> </dependency> </dependencies> </dependencyManagement>
建立公共接口工程common
该工程用于存储服务层接口,以减小代码的冗余。
<modelVersion>4.0.0</modelVersion> <parent> <groupId>com.simple.springboot</groupId> <artifactId>yun-double</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>com.simple.springboot</groupId> <artifactId>common</artifactId> <version>0.0.1-SNAPSHOT</version> <name>common</name> <description>公共接口</description>
建立公共接口
public interface UserService { String getUserById(int id); }
建立服务提供者(provider)
Pom文件
<modelVersion>4.0.0</modelVersion> <groupId>com.simple.springboot</groupId> <artifactId>provider</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>provider</name> <description>生产者</description> <parent> <groupId>com.simple.springboot</groupId> <artifactId>yun-double</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <!-- SpringBoot快速启动Duubbo --> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> </dependency> <!-- Zk客户端依赖 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <!-- 排除依赖里的日志 --> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <!-- 导入公共接口依赖 --> <dependency> <groupId>com.simple.springboot</groupId> <artifactId>common</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
在pom文件中咱们须要引入Dubbo,Zk客户端而且引入公共接口工程
application.properties配置文件
#dubbo.application.name 应用名称 #dubbo.registry.address 注册中心地址 #dubbo.protocol.name 协议名称 #dubbo.protocol.port 协议端口 #dubbo.scan dubbo 服务类包目录 #server.port=8080 spring.application.name=user-pro dubbo.application.name=user-provider1 dubbo.registry.address=zookeeper://192.168.197.133:2181 dubbo.protocol.name=dubbo dubbo.protocol.port=20880
在这里dubbo.application.name应用名称必定不能重复
实现UserService
@Component @Service(timeout = 10000,interfaceClass = UserService.class) public class UserServiceImpl implements UserService { @Override public String getUserById(int id) { if(id == 1) { return "SimpleWu"; }else { return "Apache Dubbo"; } } }
@Service 这个注解使用的不是Spring里面的,而是com.alibaba.dubbo.config.annotation.Service
timeout 配置超时时间
interfaceClass 接口类
version 服务版本,若是配置了服务版本在消费端引用也必须同样,具体等会说
建立启动类
在该工程中咱们不须要引入Web模块浪费端口号,只须要这样写启动类
@EnableDubbo @EnableDubboConfiguration @DubboComponentScan("com.simple.springboot.provider.common.impl") public class ProviderApplication { public static void main(String[] args) { SpringApplication app = new SpringApplication(ProviderApplication.class); app.run(args); //dubbo Main独立运行,脱离web容器 Main.main(args); } }
@EnableDubbo 启动Dubbo功能
@EnableDubboConfiguration 启动Duubbo配置
@DubboComponentScan 扫描提供者实现类
建立服务消费者(consumer)
POM文件
<modelVersion>4.0.0</modelVersion> <groupId>com.simple.springboot</groupId> <artifactId>consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <name>consumer</name> <description>消费者</description> <parent> <groupId>com.simple.springboot</groupId> <artifactId>yun-double</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <!-- SpringBoot快速启动Duubbo --> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> </dependency> <!-- Zk客户端依赖 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <!-- 排除依赖里的日志 --> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <!-- 导入公共接口依赖 --> <dependency> <groupId>com.simple.springboot</groupId> <artifactId>common</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
在这个工程中咱们是须要依赖Web的,否则咋访问呢
编写Application.properties配置文件
spring.application.name=user-con server.port=8080 dubbo.application.name=user-consumer dubbo.registry.address=zookeeper://192.168.197.133:2181 dubbo.protocol.name=dubbo dubbo.protocol.port=20880 #dubbo.scan=com.simple.springboot.provider.common.impl
在这里dubbo.application.name应用名称必定不能重复,dubbo.scan 该配置指向应该是要和服务提供方一致
编写Controller
@RestController public class UserController { //timeout 能够不指定,若是提供则有填写可是version必定要指定 否则会找不到服务 直连须要加url="dubbo://localhost:20880" @Reference private UserService userService; @GetMapping("/dubbo/user/{id}") public String getUserById(@PathVariable int id){ return userService.getUserById(id); } }
在这里是使用@Reference去发现服务而不是@Autowired去注入Bean,@Reference 里面能够配置version,timeout超时时间
若是须要Dubbo直连url="dubbo://localhost:20880"
dubbo提供了四种负载均衡策略,分别是:
一、Random LoadBalance 按权重的随机负载均衡,也是dubbo默认的负载均衡策略
二、RoundRobin LoadBalance 按权重的轮询负载均衡,即在轮询的基础上添加了权重的策略
三、LeastActive LoadBalance 最少活跃调用数,相同活跃数的随机访问,活跃数指调用先后的计数差即响应时间的长短;这种策略可使响应慢的提供者收到的请求较少,大大提供系统性能
四、ConsistentHash LoadBalance 一致性哈希;相同参数的请求老是发到同一提供者
负载均衡的配置:@Reference(loadbalance = "roundrobin"),loadbalance 的值即为四种负载均衡的名称,所有小写
在集群调用失败时,Dubbo 提供了多种容错方案,缺省为 failover 重试。下面列举dubbo支持的容错策略:
一、Failover Cluster:失败自动切换,当出现失败,重试其它服务器。一般用于读操做,但重试会带来更长延迟。可经过 retries="XXX" 来设置重试次数(不含第一次)。
二、Failfast Cluster:快速失败,只发起一次调用,失败当即报错。一般用于非幂等性的写操做,好比新增记录。
三、Failsafe Cluster:失败安全,出现异常时,直接忽略。一般用于写入审计日志等操做。
四、Failback Cluster:失败自动恢复,后台记录失败请求,定时重发。一般用于消息通知操做。
五、Forking Cluster:并行调用多个服务器,只要一个成功即返回。一般用于实时性要求较高的读操做,但须要浪费更多服务资源。可经过 forks="2" 来设置最大并行数。
六、Broadcast Cluster:广播调用全部提供者,逐个调用,任意一台报错则报错 [2]。一般用于通知全部提供者更新缓存或日志等本地资源信息。
配置以下:@Reference(cluster = "failsafe")这里表示使用失败安全的容错策略
编写启动类
/** * @author:SimpleWu * @date: 2019-05-08 */ @EnableDubbo @SpringBootApplication @EnableDubboConfiguration @DubboComponentScan("com.simple.springboot.provider.common.impl") public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class,args); } }
而后直接就能够访问成功了。
若是不想使用注解扫描可使用properties进行配置
#dubbo.scan=com.simple.springboot.provider.common.impl
https://gitlab.com/450255266/code/tree/master/SpringBoot/dubbo/yun-double
Dubbo是一个二进制的Rpc框架在传输数据过程当中,实体类必须通过序列化。
在使用poi导出功能时必定不能把response传到Service层,不然传输到Service是导出不了文件而报错,至于文件下载也同样可是相信通常都会有单独的文件服务器。
看完本文有收获?请转发分享给更多人