前言
分布式应用
在分布式系统中,国内常用 Zookeeper + Dubbo 组合,而 SpringBoot 推荐使用 Spring 提供的分布式一站式解决方案 Spring + SpringBoot + SpringCloud。
图 1:分布式架构图
Zookeeper和Dubbo
- Zookeeper 是一个分布式的,开放源码的分布式应用程序协调服务。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名维护、分布式同步、组服务等。
- Dubbo 是 Alibaba 开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo 采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。
图 2:Dubbo 架构图
整合Dubbo
安装Zookeeper
参考【Docker 中安装 Zookeeper】。
Provider工程
1、新建 Provider 工程,引入 Web 场景启动器和 Dubbo 及 Zookeeper 相关依赖:
<?xml version="1.0" encoding="UTF-8"?> <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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.20.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>zze.springboot.dubbo</groupId> <artifactId>provider-ticket</artifactId> <version>0.0.1-SNAPSHOT</version> <name>provider-ticket</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <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> <scope>test</scope> </dependency> <!--引入 Dubbo 整合 SpringBoot 的场景启动器--> <dependency> <groupId>com.alibaba.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>0.1.0</version> </dependency> <!--引入 Zookeeper 客户端工具依赖--> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
pom.xml
2、配置 Provider 工程注册到 Zookeeper:
dubbo: application: name: provider-ticket # 指定服务应用名称 registry: address: zookeeper://192.168.202.136:2181 # Zookeeper 服务地址 scan: base-packages: zze.springboot.dubbo.ticket.service # 扫描指定包下服务注册到 Zookeeper
application.yml
3、编写要注册的服务接口及其实现类:
package zze.springboot.dubbo.ticket.service; public interface TicketService { public String getTicket(); }
zze.springboot.dubbo.ticket.service.TicketService
package zze.springboot.dubbo.ticket.service.impl; import com.alibaba.dubbo.config.annotation.Service; import org.springframework.stereotype.Component; import zze.springboot.dubbo.ticket.service.TicketService; @Component // 注册到 IoC 容器 @Service // 使用 Dubbo 的 @Service 注解标注这是一个要发布的服务 public class TicketServiceImpl implements TicketService { @Override public String getTicket() { return "《大话西游》"; } }
zze.springboot.dubbo.ticket.service.impl.TicketServiceImpl
4、启动工程,看到 Dubbo 服务注册信息如下:
Consumer工程
1、新建 Consumer 工程,引入 Web 场景启动器和 Dubbo 及 Zookeeper 相关依赖:
<?xml version="1.0" encoding="UTF-8"?> <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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.20.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>zze.springboot.dubbo</groupId> <artifactId>consumer-user</artifactId> <version>0.0.1-SNAPSHOT</version> <name>consumer-user</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <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> <scope>test</scope> </dependency> <!--引入 Dubbo 整合 SpringBoot 的场景启动器--> <dependency> <groupId>com.alibaba.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>0.1.0</version> </dependency> <!--引入 Zookeeper 客户端工具依赖--> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
pom.xml
2、配置 Zookeeper 地址:
dubbo: application: name: consumer-user # 配置消费者服务应用名称 registry: address: zookeeper://192.168.202.136:2181 # Zookeeper 服务地址
application.yml
3、拷贝 Provider 工程中服务接口到 Consumer 工程:
package zze.springboot.dubbo.ticket.service; public interface TicketService { public String getTicket(); }
zze.springboot.dubbo.ticket.service.TicketService
4、编写 Service 类,远程引用 Provider 提供的 Service 实现:
package zze.springboot.dubbo.user.service; import com.alibaba.dubbo.config.annotation.Reference; import org.springframework.stereotype.Service; import zze.springboot.dubbo.ticket.service.TicketService; @Service public class UserService { @Reference // 远程引用 Provider 提供的实现 private TicketService ticketService; public String buyTicket(){ return ticketService.getTicket(); } }
zze.springboot.dubbo.user.service.UserService
5、测试:
package zze.springboot.dubbo.user; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import zze.springboot.dubbo.user.service.UserService; @RunWith(SpringRunner.class) @SpringBootTest public class ConsumerUserApplicationTests { @Autowired private UserService userService; @Test public void contextLoads() { String s = userService.buyTicket(); System.out.println(s); /* 《大话西游》 */ } }
test