Dubbo实践
Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成。
Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
--(摘自《百度百科》)
本演示将实现远程调用和服务自动注册以及发现。
首先,demo结构如图所示:
dubbo-api module提供接口服务。
dubbo-consumer module是消费者。
dubbo-provider module是服务提供者。
dubbo-consumer和dubbo-provider同时依赖于dubbo-appi。
解释dubbo-api module源码,它仅仅提供接口,没有其他逻辑。
dubbo-api的pom.xml
<?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 https://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>2.7.12</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.mike.study</groupId> <artifactId>dubbo-api</artifactId> <version>0.0.1</version> <name>dubbo-api</name>
<properties> <java.version>8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
接口类UserService,提供一个login的方法。
import com.mike.study.domain.UserInfo; public interface UserService { UserInfo login(UserInfo userInfo); }
同时,方便统一管理对象,创建demain.UserInfo类, 由于实体类是要在网上传输,所以它是需要继承Serializable接口,否则会报错。
import java.io.Serializable; public class UserInfo implements Serializable { private String account; private String password; public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
至此,api module已经准备完毕。接下来创建provider module,提供服务并且注册到zookeeper上。所以要事先准备好zookeeper,参考网上资料,这里不展开介绍安装教程。
dubbo-provider的pom.xml需要引入zookeeper和dubbo相关依赖。
<?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 https://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>2.7.12</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.mike.study</groupId> <artifactId>dubbo-provider</artifactId> <version>0.0.1</version> <name>dubbo-provider</name>
<properties> <java.version>8</java.version> </properties>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.mike.study</groupId> <artifactId>dubbo-api</artifactId> <version>0.0.1</version> </dependency> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.10</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
springboot自带日志框架,这里zookeeper依赖排除了自己日志框架。
配置application.yml文件,设置好zookeeper的地址,dubbo框架会把服务自动注册到zookeeper上,避免同时启动会和consumer的端口有冲突,需要设定provider的端口为8081。
1 spring: 2 dubbo: 3 application: 4 name: dubbo-provider 5 protocol: 6 name: dubbo 7 port: 20880 8 registry: 9 address: zookeeper://127.0.0.1:2181 10 server: 11 port: 8081
接下来,实现服务的逻辑,这里简单修改下user信息后直接返回出去。
1 import com.alibaba.dubbo.config.annotation.Service; 2 import com.mike.study.api.UserService; 3 import com.mike.study.domain.UserInfo; 4 import org.springframework.stereotype.Component; 5 6 @Component 7 @Service 8 public class UserServiceImpl implements UserService { 9 @Override 10 public UserInfo login(UserInfo userInfo) { 11 UserInfo reUser = new UserInfo(); 12 reUser.setAccount("账号:"+ userInfo.getAccount()); 13 reUser.setPassword("密码:"+ userInfo.getPassword()); 14 15 return reUser; 16 } 17 }
这里用到了2个注解,@Component将当前类交给springboot容器管理,@Service是dubbo的注解,将接口注册到zookeeper上供订阅者使用。
注意,上面注解外,还需要在启动类添加注解来启动dubbo自动配置。
1 import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; 2 import org.springframework.boot.SpringApplication; 3 import org.springframework.boot.autoconfigure.SpringBootApplication; 4 import org.springframework.context.ConfigurableApplicationContext; 5 6 @SpringBootApplication 7 @EnableDubboConfiguration // 启用dubbo自动配置 8 public class DubboProviderApplication { 9 10 public static void main(String[] args) { 11 ConfigurableApplicationContext 12 context = SpringApplication.run(DubboProviderApplication.class, args); 13 } 14 15 }
自此,provider也准备好,最后看consumer如何消费服务。
dubbo-consumer由于是要冲zookeeper上拿到接口,所以也要引入zookeeper等相关依赖。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 <parent> 6 <groupId>org.springframework.boot</groupId> 7 <artifactId>spring-boot-starter-parent</artifactId> 8 <version>2.7.12</version> 9 <relativePath/> <!-- lookup parent from repository --> 10 </parent> 11 <groupId>com.mike.study</groupId> 12 <artifactId>dubbo-consumer</artifactId> 13 <version>0.0.1-SNAPSHOT</version> 14 <name>dubbo-consumer</name>
16 <properties> 17 <java.version>8</java.version> 18 </properties>
19 <dependencies> 20 <dependency> 21 <groupId>org.springframework.boot</groupId> 22 <artifactId>spring-boot-starter-web</artifactId> 23 </dependency> 24 25 <dependency> 26 <groupId>com.mike.study</groupId> 27 <artifactId>dubbo-api</artifactId> 28 <version>0.0.1</version> 29 </dependency> 30 31 <dependency> 32 <groupId>com.alibaba.spring.boot</groupId> 33 <artifactId>dubbo-spring-boot-starter</artifactId> 34 <version>2.0.0</version> 35 </dependency> 36 37 <dependency> 38 <groupId>com.101tec</groupId> 39 <artifactId>zkclient</artifactId> 40 <version>0.10</version> 41 </dependency> 42 43 <dependency> 44 <groupId>org.apache.zookeeper</groupId> 45 <artifactId>zookeeper</artifactId> 46 <version>3.4.10</version> 47 <exclusions> 48 <exclusion> 49 <groupId>org.slf4j</groupId> 50 <artifactId>slf4j-log4j12</artifactId> 51 </exclusion> 52 <exclusion> 53 <groupId>log4j</groupId> 54 <artifactId>log4j</artifactId> 55 </exclusion> 56 </exclusions> 57 </dependency> 58 59 <dependency> 60 <groupId>org.springframework.boot</groupId> 61 <artifactId>spring-boot-starter-test</artifactId> 62 <scope>test</scope> 63 </dependency> 64 </dependencies> 65 66 <build> 67 <plugins> 68 <plugin> 69 <groupId>org.springframework.boot</groupId> 70 <artifactId>spring-boot-maven-plugin</artifactId> 71 </plugin> 72 </plugins> 73 </build> 74 75 </project>
同样配置application.yml,指定zookeeper和服务端口。
1 spring: 2 dubbo: 3 application: 4 name: dubbo-consumer 5 protocol: 6 name: dubbo 7 port: 20880 8 registry: 9 address: zookeeper://127.0.0.1:2181 10 server: 11 port: 8082
添加一个controller层用来调用UserService服务,添加 @Reference注解拿到provider的远程接口。
1 import com.alibaba.dubbo.config.annotation.Reference; 2 import com.mike.study.api.UserService; 3 import com.mike.study.domain.UserInfo; 4 import org.springframework.web.bind.annotation.GetMapping; 5 import org.springframework.web.bind.annotation.RestController; 6 7 8 @RestController 9 public class UserController { 10 @Reference 11 UserService userService; 12 13 @GetMapping("/login") 14 public UserInfo login(UserInfo userInfo){ 15 UserInfo result = userService.login(userInfo); 16 return result; 17 } 18 }
同样,consumer也要启动dubbo的自动配置。
1 import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration; 2 import org.springframework.boot.SpringApplication; 3 import org.springframework.boot.autoconfigure.SpringBootApplication; 4 5 @SpringBootApplication 6 @EnableDubboConfiguration 7 public class DubboConsumerApplication { 8 9 public static void main(String[] args) { 10 SpringApplication.run(DubboConsumerApplication.class, args); 11 } 12 13 }
依次跑起zookeeper,provider服务,consumer服务。查看zookeeper的节点,可以看到,consumer和provider节点。
在浏览器上访问consumer:http://localhost:8082/login?account=test&password=123,效果如下