因为要测试Dubbo接口,所以了解下Dubbo这个服务框架,下图架构、各角色说明、及调用关系的说明摘自官网
各角色的说明:
Provider:暴露服务的服务提供商
Consume:调用远程服务的服务消费方
Registry: 服务注册与发现注册的中心
Monitor:统计调用次数和调用时间的监控中心
Container:服务运行的容器
调用关系的说明:
- 服务容器负责启动、加载、运行服务提供者
- 服务提供者在启动时,向注册中心注册资金的服务
- 消费者在启动时,向注册中心订阅服务
- 注册中心将服务者地址列表发送给消费者,如果有变更基于长连接发送变更数据给消费者
- 服务消费者,从地址列表选择调用
- 服务消费者和提供者,累计调用服务的次数和时间,定时发送给监控中心。
创建的一个简单的服务提供者和服务消费者,步骤如下:
下图是服务端的代码架构:
- 创建一个Maven工程,取名:demo-provider,pom文件如下

<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> <groupId>com.ustc.demo.provider</groupId> <artifactId>demo_dubbo_provider</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>dubbo-provider</name> <url>http://maven.apache.org</url> <properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> <!-- 文件拷贝时的编码 --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- 编译时的编码 --> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.12</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.0.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>unpack</id> <phase>package</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.1</version> <includes>META-INF/assembly/**</includes> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptor>src/main/assembly/assembly.xml</descriptor> <encoding>UTF-8</encoding> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
2. 在src/main下新建文件夹assembly,然后在assembly文件夹下新建assembly.xml文件 ,内容:

<?xml version="1.0" encoding="UTF-8"?> <assembly> <id>assembly</id> <formats> <format>tar.gz</format> </formats> <includeBaseDirectory>true</includeBaseDirectory> <fileSets> <fileSet> <directory>${project.build.directory}/dubbo/META-INF/assembly/bin</directory> <outputDirectory>bin</outputDirectory> <fileMode>0755</fileMode> </fileSet> <fileSet> <directory>src/main/assembly/conf</directory> <outputDirectory>conf</outputDirectory> <fileMode>0644</fileMode> </fileSet> </fileSets> <dependencySets> <dependencySet> <outputDirectory>lib</outputDirectory> </dependencySet> </dependencySets> </assembly>
3. 在src/main/assembly文件夹下新建conf文件夹,然后在conf文件夹下新建dubbo.properties文件。文件中zookeeper的地址根据实际进行修改。,我的zookeeper是安装在本地的:

dubbo.container=log4j,spring
dubbo.application.name=demo-dubbo-provider
dubbo.application.owner=jason
#dubbo.registry.address=multicast://127.0.0.1:1234
dubbo.registry.address=zookeeper://127.0.0.1:20181
#dubbo.registry.address=redis://127.0.0.1:6379
#dubbo.registry.address=dubbo://127.0.0.1:9090
dubbo.monitor.protocol=registry
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#dubbo.service.loadbalance=roundrobin
#dubbo.log4j.file=logs/dubbo-demo-provider.log
#dubbo.log4j.level=WARN
4. 在src/test/resources包路径下,新建dubbo.properties文件,内容和上面3的dubbo.properties文件内容相同。

dubbo.container=log4j,spring
dubbo.application.name=demo-dubbo-provider
dubbo.application.owner=jason
#dubbo.registry.address=multicast://127.0.0.1:1234
dubbo.registry.address=zookeeper://127.0.0.1:20181
#dubbo.registry.address=redis://127.0.0.1:6379
#dubbo.registry.address=dubbo://127.0.0.1:9090
dubbo.monitor.protocol=registry
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#dubbo.service.loadbalance=roundrobin
#dubbo.log4j.file=logs/dubbo-demo-provider.log
#dubbo.log4j.level=WARN
5. 在src/test/resources路径下,新建log4j.xml文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <!-- Appenders --> <appender name="console" class="org.apache.log4j.ConsoleAppender"> <param name="Target" value="System.out" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-5p: %c - %m%n" /> </layout> </appender> <appender name="myFile" class="org.apache.log4j.RollingFileAppender"> <param name="File" value="logs/output.log" /><!-- 设置日志输出文件名 --> <!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 --> <param name="Append" value="true" /> <param name="MaxBackupIndex" value="10" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%p (%c:%L)- %m%n" /> </layout> </appender> <!-- Application Loggers --> <logger name="com.ustcinfo.ishare.eip.si"> <level value="error" /> </logger> <!-- 3rdparty Loggers --> <logger name="org.springframework.core"> <level value="warn" /> </logger> <logger name="org.springframework.beans"> <level value="info" /> </logger> <logger name="org.springframework.context"> <level value="info" /> </logger> <logger name="org.springframework.web"> <level value="info" /> </logger> <logger name="org.mongodb.driver"> <level value="warn" /> </logger> <!-- Root Logger --> <root> <priority value="error" /> <appender-ref ref="console" /> </root> </log4j:configuration>
6. 在src/main/java, 编写provider的接口sayHello,新建DemoService.java类:

package com.ustc.demo.provider; public interface DemoService { public String sayHello(String name); }

package com.ustc.demo.provider; import java.text.SimpleDateFormat; import java.util.Date; public class DemoServiceImpl implements DemoService { @Override public String sayHello(String name) { // TODO Auto-generated method stub String time = new SimpleDateFormat("HH:mm:ss").format(new Date()); System.out.println("From consumer: " + name); return "The current time is:" + time+name; } }
8.编写spring的配置文件,在META-INF/spring文件夹下的demo-provider.xml:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <bean id="demoService" class="com.ustc.demo.provider.DemoServiceImpl" /> <dubbo:registry address="zookeeper://127.0.0.1:2181" /> <dubbo:protocol name="dubbo" port="20880" /> <dubbo:service interface="com.ustc.demo.provider.DemoService" ref="demoService"/> </beans>
9.在src/test/java中,写main测试方法:

package com.ustc.demo.provider; public class DemoServiceMain { public static void main(String[] args) { com.alibaba.dubbo.container.Main.main(args); } }
服务端的代码已完成,准备消费端的代码:
代码架构如下:
- 新建maven工程,工程名字为demo-dubbo-consume,pom文件如下:

<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> <groupId>com.ustc.demo.consumer</groupId> <artifactId>demo_dubbo_comsumer</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>consumer</name> <url>http://maven.apache.org</url> <properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> <!-- 文件拷贝时的编码 --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- 编译时的编码 --> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.12</version> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.0.1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.5.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>unpack</id> <phase>package</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.1</version> <includes>META-INF/assembly/**</includes> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptor>src/main/assembly/assembly.xml</descriptor> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
2. 在src/main下新建文件夹assembly,然后在assembly文件夹下新建assembly.xml文件。文件内容和Provider工程中的同名文件相同。
3. 在src/main/assembly文件夹下新建conf文件夹,然后在conf文件夹下新建dubbo.properties文件。文件内容和Provider工程中的同名文件相同。
4. 在src/test/resources包路径下,新建dubbo.properties文件,内容和上面的3中dubbo.properties文件内容相同。
5.编写消费端请求类调用sayHello方法,新建DemoAction.java类

package com.ustc.demo.consumer; import com.ustc.demo.provider.DemoService; public class DemoAction { private DemoService demoService; public void setDemoService(DemoService demoService) { this.demoService = demoService; } public void start() throws Exception { for (int i = 0; i < Integer.MAX_VALUE; i ++) { try { String hello = demoService.sayHello("Hello, how much is the current time?"); System.out.println("From provider: " + hello); } catch (Exception e) { e.printStackTrace(); } Thread.sleep(2000); } } }
6.编写spring的配置文件,在META-INF/spring文件夹下的dubbo-demo-consume.xml文件:

<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 --> <dubbo:application name="consumer-of-helloworld-app" /> <!-- 使用注册中心暴露发现服务地址 --> <dubbo:registry address="zookeeper://127.0.0.1:2181" /> <dubbo:reference id="demoService" interface="com.ustc.demo.provider.DemoService"/> </beans>
7.编写测试main方法,新建Consumer.java类:

package com.ustc.demo.consumer; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.ustc.demo.provider.DemoService; public class Consumer { public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"META-INF/spring/dubbo-demo-consumer.xml"}); context.start(); DemoService demoService = (DemoService)context.getBean("demoService"); // 获取远程服务代理 String hello = demoService.sayHello("mjj"); // 执行远程方法 System.out.println( hello ); // 显示调用结果 } }
8.编写log4j2的配置文件,在src/main/resources目录下创建log4j2.xml文件:

<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%m%n" /> </Console> </Appenders> <Loggers> <Root level="INFO"> <AppenderRef ref="Console" /> </Root> </Loggers> </Configuration>
- 消费端代码完成,准备测试:需要打开zookeeper的服务端,执行zookeeper bin目录下的zkServer.cmd,端口默认为2181
- 执行provider的main函数:
- 然后运行Consume下的main函数:
- 该dubbo接口的功能正常实现,下面用jmter模拟消费方向服务方请求,如下图
接口调用正常,如下图:
安装dubbo-admin-2.6.0工具,放在tomcat webapp目录下,执行tomcat后,浏览器输入地址查看zookeeper的运行:
jmeter调用的消费方: