Dubbo

Dubbo is a distributed, high performance RPC framework which empowers applications with service import/export capabilities.

It contains three key parts, which include:

  • Remoting: a network communication framework providing sync-over-async and request-response messaging.

  • Clustering: a remote procedure call abstraction with load-balancing/failover/clustering capabilities.

  • Registration: a service directory framework for service registration and service event publish/subscription

中文文档

Dubbo admin

You can download the code from https://github.com/alibaba/dubbo, and package the dubbo-admin

houbinbindeMacBook-Pro:dubbo-admin houbinbin$ pwd
/Users/houbinbin/it/code/dubbo/dubbo-admin
houbinbindeMacBook-Pro:dubbo-admin houbinbin$ mvn package -Dmaven.skip.test=true

Download dubbo-admin-2.5.4-SNAPSHOT.war into tomcat/webapps, and rename to ROOT.war

dubbo 2.5.4 在JDK8下启动错误

  • config tomcat

edit the tomcat port(default is 8080) after these:

<!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->

change the content to:

<Connector port="8888" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8"/>
  • start tomcat
houbinbindeMacBook-Pro:bin houbinbin$ pwd
/Users/houbinbin/it/tools/tomcat/tomcat8/bin

houbinbindeMacBook-Pro:bin houbinbin$ sh startup.sh
Using CATALINA_BASE:   /Users/houbinbin/it/tools/tomcat/tomcat8
Using CATALINA_HOME:   /Users/houbinbin/it/tools/tomcat/tomcat8
Using CATALINA_TMPDIR: /Users/houbinbin/it/tools/tomcat/tomcat8/temp
Using JRE_HOME:        /Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home
Using CLASSPATH:       /Users/houbinbin/it/tools/tomcat/tomcat8/bin/bootstrap.jar:/Users/houbinbin/it/tools/tomcat/tomcat8/bin/tomcat-juli.jar
Tomcat started.
  • visit dobbo admin in browser
URL:    localhost:8888

root/root

dubbo-admin

Hello World

zookeeper

First of all, you need start your zookeeper.

houbinbindeMacBook-Pro:bin houbinbin$ ./zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /Users/houbinbin/it/tools/zookeeper/server1/zookeeper-3.4.9/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
houbinbindeMacBook-Pro:bin houbinbin$ pwd
/Users/houbinbin/it/tools/zookeeper/server1/zookeeper-3.4.9/bin
houbinbindeMacBook-Pro:bin houbinbin$ jps
32082
34610 QuorumPeerMain
34613 Jps
30221 Bootstrap

provider

customer

provider

File tree

|____main
| |____java
| | |____com
| | | |____ryo
| | | | |____model
| | | | | |____User.java
| | | | |____Provider.java
| | | | |____service
| | | | | |____impl
| | | | | | |____UserServiceImpl.java
| | | | | |____UserService.java
| |____resources
| | |____app-core.xml
| | |____applicationContext-beans.xml
| | |____applicationContext-dubbo-provider.xml
| | |____log4j2.xml
|____test
---- pom.xml
  • User.java
@Data
public class User implements Serializable {

  private Long id;

  private String username;
}
  • UserService.java
public interface UserService {
  User getUser(Long id);
}
  • UserServiceImpl.java
@Service("userService")
public class UserServiceImpl implements UserService {

  public User getUser(Long id) {
    User user = new User();
    user.setId(id);
    user.setUsername("name"+id);
    return user;
  }

}
  • 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ryo</groupId>
    <artifactId>dubbo-provider</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <plugin.tomcat.version>2.2</plugin.tomcat.version>
        <maven-surefire-plugin.version>2.18.1</maven-surefire-plugin.version>

        <!--spring-->
        <spring.version>4.2.6.RELEASE</spring.version>
        <!--log4j-->
        <log4j.version>2.6</log4j.version>
    </properties>

    <dependencies>
        <!--spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.5.3</version>
        </dependency>

        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.4</version>
        </dependency>

        <!--log4j-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-web</artifactId>
            <version>${log4j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>${plugin.tomcat.version}</version>
                <configuration>
                    <port>8081</port>
                    <path>/</path>
                    <uriEncoding>${project.build.sourceEncoding}</uriEncoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven-surefire-plugin.version}</version>
                <configuration>
                    <skipTests>true</skipTests>
                    <testFailureIgnore>true</testFailureIgnore>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
  • app-core.xml
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="applicationContext-dubbo-customer.xml"/>
    <import resource="applicationContext-beans.xml"/>

</beans>
  • applicationContext-beans.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--自动扫描 no need to include the <context:annotation-config>-->
    <context:component-scan base-package="com.ryo"/>
</beans>
  • applicationContext-dubbo-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-2.5.xsd
    http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="dubbo-provider"/>

    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>

    <!-- 监听注册 -->
    <dubbo:monitor protocol="registry"/>

    <!-- 用dubbo协议在20880端口暴露服务 -1 == 20880 -->
    <dubbo:protocol name="dubbo" port="-1" />

    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.ryo.service.UserService" ref="userService"
                   version="0.0.0" retries="0" timeout="10000"/>

</beans>
  • log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="DEBUG">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>
  • Main()
public class Provider {

  public static void main(String[] args) throws IOException {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"app-core.xml"});
    context.start();
    System.out.println("dubbo-provider start...");
    System.in.read(); // 按任意键退出
  }

}

start the main()

dubbo-provider start...
  • visit the dubbo-admin

If you see this, you are success of half…

dubbo-provider

customer

Well, customer is most the same as provider. It’s File tree:

.
|____main
| |____java
| | |____com
| | | |____ryo
| | | | |____model
| | | | | |____User.java
| | | | |____service
| | | | | |____UserService.java
| |____resources
| | |____app-core.xml
| | |____applicationContext-beans.xml
| | |____applicationContext-dubbo-customer.xml
| | |____log4j2.xml
|____test
| |____java
| | |____com
| | | |____ryo
| | | | |____service
| | | | | |____UserServiceTest.java
  • applicationContext-dubbo-customer.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="dubbo-customer"/>

    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>

    <!-- 监听注册 -->
    <dubbo:monitor protocol="registry"/>

    <!-- 用dubbo协议在20880端口暴露服务 -1 == 20880 -->
    <dubbo:protocol name="dubbo" port="-1" />

    <!-- 声明需要消费的服务接口 -->
    <dubbo:reference interface="com.ryo.service.UserService" id="userService"/>

</beans>
  • UserServiceTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/app-core.xml"})
@Log4j2
public class UserServiceTest {

  @Resource
  private UserService userService;

  @Test
  public void getUserTest() {
    User user = userService.getUser(2L);
    log.info("user info:{}", user);
  }
}

result

23:31:47.259 [main] INFO  com.ryo.service.UserServiceTest - user info:User{id=2, username='name2'}

Process finished with exit code 0

Multi-Maven & Nexus

As you can see, the User.java and UserService.java we have write it twice.

We can make it into jar, and use it.

  • Provider

maven multi-module

  • Provider interface jar
$   cd facade
$   mvn clean install

houbinbindeMacBook-Pro:target houbinbin$ pwd
/Users/houbinbin/IT/code/provider/facade/target
houbinbindeMacBook-Pro:target houbinbin$ ls
classes                 facade-1.0-SNAPSHOT.jar generated-sources       maven-archiver          maven-status

Into local

We can add the facade-1.0-SNAPSHOT.jar into maven local repository

mvn install:install-file -Dfile=${jar-path} -DgroupId=com.ryo -DartifactId=${artifactId} -Dversion=${version} -Dpackaging=jar

then

mvn install:install-file -Dfile=/Users/houbinbin/IT/code/provider/facade/target/facade-1.0-SNAPSHOT.jar -DgroupId=com.ryo -DartifactId=facade -Dversion=1.0-SNAPSHOT -Dpackaging=jar

...
[INFO] --- maven-install-plugin:2.4:install-file (default-cli) @ standalone-pom ---
[INFO] Installing /Users/houbinbin/IT/code/provider/facade/target/facade-1.0-SNAPSHOT.jar to /Users/houbinbin/.m2/repository/com/ryo/facade/1.0-SNAPSHOT/facade-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.280 s
[INFO] Finished at: 2016-09-27T23:10:42+08:00
[INFO] Final Memory: 9M/309M
[INFO] ------------------------------------------------------------------------

Use the facade-1.0-SNAPSHOT.jar in customer

  • pom.xml
<dependency>
    <groupId>com.ryo</groupId>
    <artifactId>facade</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
  • customer tree
|____main
| |____java
| |____resources
| | |____app-core.xml
| | |____applicationContext-beans.xml
| | |____applicationContext-dubbo-customer.xml
| | |____log4j2.xml
|____test
| |____java
| | |____com
| | | |____ryo
| | | | |____facade
| | | | | |____UserFacadeTest.java
  • UserFacadeTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/app-core.xml"})
@Log4j2
public class UserFacadeTest {
  @Autowired
  private UserFacade userFacade;

  @Test
  public void getUserTest() {
    UserResponse userResponse = userFacade.getUser(2L);
    log.info("userResponse:{}", userResponse);
  }
}

result:

23:21:11.040 [main] INFO  com.ryo.facade.UserFacadeTest - userResponse:UserResponse(id=2, username=name2)

Process finished with exit code 0

telnet

telnet