dubbo是一個分佈式服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。簡單的說,dubbo就是個服務框架,若是沒有分佈式的需求,實際上是不須要用的,只有在分佈式的時候,纔有dubbo這樣的分佈式服務框架的需求。java
下面將介紹如何搭建一個簡單的示例程序(用maven構建)。git
衆所周知,RPC調用涉及到消費者、提供者和接口,因此須要在maven工程warehouse-component-parent裏面新建3個模塊,分別是warehouse-component-dubbo-facade(接口)、warehouse-component-dubbo-provider(提供者)和warehouse-component-dubbo-consumer(消費者)。對應的pom文件以下。github
warehouse-component-parent:spring
<?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> <groupId>org.wu</groupId> <artifactId>warehouse-component-parent</artifactId> <version>0.0.1</version> <packaging>pom</packaging> <name>component warehouse parent</name> <modules> <module>warehouse-component-dubbo-facade</module> <module>warehouse-component-dubbo-provider</module> <module>warehouse-component-dubbo-consumer</module> </modules> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <junit.version>4.12</junit.version> <spring.version>4.3.8.RELEASE</spring.version> <log4j.over.slf4j.version>1.7.25</log4j.over.slf4j.version> <jcl.over.slf4j.version>1.7.25</jcl.over.slf4j.version> <logback.version>1.2.3</logback.version> <dubbo.version>2.5.3</dubbo.version> <zkclient.version>0.1</zkclient.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!-- logback --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${jcl.over.slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>${log4j.over.slf4j.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency> <!-- dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>${dubbo.version}</version> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <!-- zkclient --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>${zkclient.version}</version> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.wu</groupId> <artifactId>warehouse-component-dubbo-facade</artifactId> <version>${project.version}</version> </dependency> </dependencies> </dependencyManagement> </project>
warehouse-component-dubbo-provider:apache
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.wu</groupId> <artifactId>warehouse-component-parent</artifactId> <version>0.0.1</version> </parent> <artifactId>warehouse-component-dubbo-provider</artifactId> <name>warehouse-component-dubbo-provider</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <!-- dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> </dependency> <!-- zkclient --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> </dependency> <!-- logback --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> <dependency> <groupId>org.wu</groupId> <artifactId>warehouse-component-dubbo-facade</artifactId> </dependency> </dependencies> </project>
warehouse-component-dubbo-consumer:windows
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.wu</groupId> <artifactId>warehouse-component-parent</artifactId> <version>0.0.1</version> </parent> <artifactId>warehouse-component-dubbo-consumer</artifactId> <name>warehouse-component-dubbo-consumer</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> </dependency> <!-- dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> </dependency> <!-- zkclient --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> </dependency> <!-- logback --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> <dependency> <groupId>org.wu</groupId> <artifactId>warehouse-component-dubbo-facade</artifactId> </dependency> </dependencies> </project>
工程使用的日誌框架爲logback,配置文件以下:app
<?xml version="1.0" encoding="UTF-8" ?> <configuration scan="true" scanPeriod="3 seconds"> <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度%msg:日誌消息,%n是換行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] [%logger:%L] %msg%n</pattern> </layout> </appender> <appender name="ALL_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>warehouse_component.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern> warehouse_component.%d{yyyy-MM-dd}.log </FileNamePattern> </rollingPolicy> <layout class="ch.qos.logback.classic.PatternLayout"> <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度%msg:日誌消息,%n是換行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] [%logger:%L] %msg%n</pattern> </layout> </appender> <appender name="ERROR_LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>warehouse_component_error.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern> warehouse_component_error.%d{yyyy-MM-dd}.log </FileNamePattern> </rollingPolicy> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <layout class="ch.qos.logback.classic.PatternLayout"> <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度%msg:日誌消息,%n是換行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] [%logger:%L] %msg%n</pattern> </layout> </appender> <root> <level value="INFO" /> <appender-ref ref="STDOUT" /> <appender-ref ref="ALL_LOG_FILE" /> <appender-ref ref="ERROR_LOG_FILE" /> </root> </configuration>
上述配置信息都設置好後,就能夠進行dubbo程序的開發了。首先,定義dubbo接口,在warehouse-component-dubbo-facade模塊中定義一個接口:框架
package org.warehouse.component.dubbo.facade; public interface DemoFacade { /** * dubbo接口 */ String sayHello(String name); }
接口定義好後,dubbo服務提供者warehouse-component-dubbo-provider須要實現該接口,進行相關的業務邏輯處理。eclipse
package org.warehouse.component.dubbo.provider; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.stereotype.Service; import org.warehouse.component.dubbo.facade.DemoFacade; import com.alibaba.dubbo.rpc.RpcContext; @Service("demoFacadeImpl") public class DemoFacadeImpl implements DemoFacade { @Override public String sayHello(String name) { System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress()); return "Hello " + name + ", response form provider: " + RpcContext.getContext().getLocalAddress(); } }
並經過spring配置文件(dubbo-provider.xml)暴露該服務:maven
<?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:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 自動檢測並裝配bean --> <context:component-scan base-package="org.warehouse.component.dubbo.provider" /> <!-- 提供方應用信息,用於計算依賴關係 --> <dubbo:application name="provider-of-hello-world-app" /> <!-- 使用zookeeper註冊中心暴露服務地址 --> <dubbo:registry protocol="zookeeper" address="192.168.1.103:2181" /> <!-- 用dubbo協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 聲明須要暴露的服務接口 --> <dubbo:service interface="org.warehouse.component.dubbo.facade.DemoFacade" ref="demoFacadeImpl" /> </beans>
如今能夠經過加載spring配置啓動服務提供者了(運行如下代碼):
package org.warehouse.component.dubbo.provider; import java.io.IOException; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Provider { public static void main(String[] args) throws IOException { @SuppressWarnings("resource") ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("dubbo-provider.xml"); context.start(); System.in.read(); } }
服務提供者啓動以後,服務消費者經過spring配置(dubbo-consumer.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:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 自動檢測並裝配bean --> <context:component-scan base-package="org.warehouse.component.dubbo.consumer" /> <!-- 提供方應用信息,用於計算依賴關係 --> <dubbo:application name="consumer-of-hello-world-app" /> <!-- 使用zookeeper註冊中心暴露服務地址 --> <dubbo:registry protocol="zookeeper" address="192.168.1.103:2181" /> <dubbo:reference id="demoFacade" interface="org.warehouse.component.dubbo.facade.DemoFacade" /> </beans>
加載Spring配置,並調用遠程服務(這裏是經過spring unit test的方式):
package org.warehouse.component.dubbo.consumer; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.warehouse.component.dubbo.facade.DemoFacade; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:dubbo-consumer.xml"}) public class ConsumerTest { @Autowired ApplicationContext context; @Test public void testDemoFacade() { DemoFacade facade = (DemoFacade) context.getBean("demoFacade"); String hello = facade.sayHello("world"); System.out.println(hello); } }
服務的調用就像是方法本地調用同樣簡單,這實際上是dubbo將底層通訊封裝好了,咱們只須要關注業務邏輯實現。
在spring文件中配置dubbo服務時,eclipse會出現沒法找到dubbo.xsd文件的問題。在本工程的解決辦法是將dubbo-2.5.3.jar包中的dubbo.xsd文件(META-INF文件夾中)複製到文件系統中,而後
windows -> Preferrences -> XML -> XML Catalog
Add -> Catalog Entry -> File System 選擇剛剛下載的文件路徑
修改key值和配置文件的http://code.alibabatech.com/schema/dubbo/dubbo.xsd 相同
保存。。在xml文件右鍵validate ok解決了。
最後還有一點須要說明:dubbo和zkclient須要排除對log4j的依賴後才能夠使用logback來記錄詳細日誌,具體排除方式已經在warehouse-component-parent的pom文件中展現。