之前学习了Netty 的源码,想着简单研究下dubbo基于netty封装的原理,然后了解netty在整个通信过程中的作用。
1. dubbo-service 工程封装的Service 接口和VO实体类
这个工程可以理解一个封装的common 工程,用于多个服务间共享。
1. pom 文件
<?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"> <parent> <artifactId>cloud</artifactId> <groupId>cn.qz.cloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>dubbo-service</artifactId> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
2. 几个重要的接口和VO类
GroupService
package cn.qz.dubbo.service; import cn.qz.dubbo.vo.GroupVO; import java.util.List; public interface GroupService { void add(GroupVO groupVO); List<GroupVO> listAll(); }
UserService
package cn.qz.dubbo.service; import cn.qz.dubbo.vo.UserVO; import java.util.List; public interface UserService { void addUser(UserVO userVO); List<UserVO> listUser(); }
GroupVO
package cn.qz.dubbo.vo; import lombok.Data; @Data public class GroupVO { private String name; private Integer userNum; }
UserVO
package cn.qz.dubbo.vo; import lombok.Data; import java.io.Serializable; @Data public class UserVO implements Serializable { private String username; private String fullname; private Integer age; }
2. dubbo-service-impl工程
这个可以理解为服务实现工程。主要是实现上面的接口,同时将服务发布到
1. pom文件
<?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"> <parent> <artifactId>cloud</artifactId> <groupId>cn.qz.cloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>dubbo-service-impl</artifactId> <dependencies> <dependency> <groupId>cn.qz.cloud</groupId> <artifactId>dubbo-service</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <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> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.3</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.3</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.13</version> <type>pom</type> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> </dependencies> </project>
2. application.yml 配置文件
server: port: -1 spring: application: name: dubbp-service-impl dubbo: application: name: dubbp-service-impl registry: protocol: zookeeper address: zookeeper://192.168.99.100:2181 protocol: name: dubbo port: 20881 scan: base-packages: cn.qz logging: level: root: info
3. DubboImplApplication主启动类
package cn.qz.dubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DubboImplApplication { public static void main(String[] args) { SpringApplication.run(DubboImplApplication.class, args); } }
4. 相关的impl 实现类
UserServiceImpl
package cn.qz.dubbo.impl; import cn.qz.dubbo.service.UserService; import cn.qz.dubbo.vo.UserVO; import org.apache.dubbo.config.annotation.Service; import java.util.ArrayList; import java.util.List; @Service(version = "1.0.0", interfaceClass = UserService.class) public class UserServiceImpl implements UserService { @Override public void addUser(UserVO userVO) { try { Thread.sleep(5 * 10000); } catch (InterruptedException e) { } System.out.println(Thread.currentThread().getName() + " cn.qz.dubbo.impl.UserServiceImpl.addUser " + userVO); } @Override public List<UserVO> listUser() { UserVO userVO = new UserVO(); userVO.setUsername("testusername"); userVO.setFullname("testfullname"); userVO.setAge(25); List<UserVO> objects = new ArrayList<>(); objects.add(userVO); return objects; } }
GroupServiceImpl
package cn.qz.dubbo.impl; import cn.qz.dubbo.service.GroupService; import cn.qz.dubbo.vo.GroupVO; import org.apache.dubbo.config.annotation.Service; import java.util.ArrayList; import java.util.List; @Service(version = "1.0.0", interfaceClass = GroupService.class) public class GroupServiceImpl implements GroupService { @Override public void add(GroupVO groupVO) { System.out.println("cn.qz.dubbo.impl.GroupServiceImpl.add " + groupVO); } @Override public List<GroupVO> listAll() { GroupVO userVO = new GroupVO(); userVO.setName("testname"); userVO.setUserNum(290); List<GroupVO> objects = new ArrayList<>(); objects.add(userVO); return objects; } }
3. dubbo-service-consumer 服务的消费者
1. pom 配置文件
<?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"> <parent> <artifactId>cloud</artifactId> <groupId>cn.qz.cloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>dubbo-service-consumer</artifactId> <dependencies> <dependency> <groupId>cn.qz.cloud</groupId> <artifactId>dubbo-service</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <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> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.3</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.3</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.13</version> <type>pom</type> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> </dependencies> </project>
2. yml 配置文件
server: port: 9090 spring: application: name: dubbp-service-consumer dubbo: application: name: dubbp-service-consumer registry: protocol: zookeeper address: zookeeper://192.168.99.100:2181
3. 主要的类
DubboConsumerApplication主启动类
package cn.qlq.dubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DubboConsumerApplication { public static void main(String[] args) { SpringApplication.run(DubboConsumerApplication.class, args); } }
GroupController
package cn.qlq.dubbo.controller; import cn.qz.dubbo.service.GroupService; import cn.qz.dubbo.vo.GroupVO; import org.apache.dubbo.config.annotation.Reference; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class GroupController { @Reference(version = "1.0.0") private GroupService groupService; @GetMapping("/listGroup") public List<GroupVO> listGroup() { return groupService.listAll(); } @GetMapping("/addGroup") public void addUser() { GroupVO groupVO = new GroupVO(); groupVO.setName("testname"); groupVO.setUserNum(290); groupService.add(groupVO); } }
UserController
package cn.qlq.dubbo.controller; import cn.qz.dubbo.service.UserService; import cn.qz.dubbo.vo.UserVO; import org.apache.dubbo.config.annotation.Reference; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class UserController { @Reference(version = "1.0.0") private UserService userService; @GetMapping("/listUser") public List<UserVO> listUser() { return userService.listUser(); } @GetMapping("/addUser") public void addUser() { UserVO user = new UserVO(); user.setUsername("addUsername"); user.setFullname("addFullname"); user.setAge(25); userService.addUser(user); } }
4. 启动后测试
1. 启动zk
2. 启动服务实现类应用
3. 查看zk 节点上面注册的信息
可以看到节点的信息包括服务的地址,bean的名称,接口的名称,接口的方法以及其他相关的信息
4. 再次启动一个impl 实例,修改启动端口和dubbo 端口(这个端口是建立netty server 用的端口)
yml 修改dubbo 协议的端口是20880
5. 再次查看zk节点,发现provider 提供者变为两个
6. 启动消费者
7. 访问进行测试:
$ curl http://localhost:9090/listUser % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 64 0 64 0 0 842 0 --:--:-- --:--:-- --:--:-- 864[{"username":"testusername","fullname":"testfullname","age":25}]
至此简单实现了其使用。关于调用原理以及负载均衡算法等下一篇进行研究。