Dubbo學習筆記2:Dubbo服務提供端與消費端應用的搭建

Demo結構介紹git

Demo使用Maven聚合功能,裏面有三個模塊,目錄以下:web

 

  • 其中Consumer模塊爲服務消費者,裏面TestConsumer和consumer.xml組成了基於Spring配置方式的服務調用,TestConsumerApi是基於Dubbo API方式的服務調用,TestConsumerApiGeneric是泛化方式的服務調用,TestConsumerAsync是異步調用的方式。
  • 其中Provider模塊爲服務提供者,裏面TestProvider和provider.xml組成了基於Spring配置方式的服務提供,TestProviderApi是基於Dubbo API的服務提供,UserServiceImpl爲服務實現類。
  • 其中SDK模塊是一個二方包,用來存放服務提供者全部的接口,是爲了代碼複用使用,在服務提供者和消費者的模塊裏面都須要引入這個二方包。

其中SDK裏面的接口定義源碼以下:spring

public interface UserServiceBo {
    String sayHello(String name);  
    String testPojo(Person person);
}
public interface Person {
}

在SDK模塊執行 mvn clean install 命令會安裝該模塊的jar到本地倉庫,要想在其餘模塊引入該jar,必需要先執行這個安裝步驟。apache

基於Spring配置的服務提供方與消費方搭建緩存

Provider模塊爲服務提供者,做用是提供的服務到Zookeeper,並使用Netty服務監聽服務消費端的連接。裏面TestProvider和provider.xml組成了基於XML方式的服務提供,UserServiceImpl爲服務實現類。app

首先須要在Provider模塊裏面引入SDK模塊,由於Provider模塊須要用到UserServiceBo接口(須要在SDK模塊執行 mvn clean install 命令,會安裝該模塊的jar到本地倉庫)。異步

而後實現UserServiceBo接口爲UserServiceImpl,代碼以下:maven

public class UserServiceImpl implements UserServiceBo{

    @Override
    public String sayHello(String name) {
        //讓當前當前線程休眠2s
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return name; 
    }

    @Override
    public String sayHello2(String name) {
        //讓當前當前線程休眠2s
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return name;
    }
        @Override
    public String testPojo(Person person) {
        return JSON.toJSONString(person);
    }  
}

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: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.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd 
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方應用信息,用於計算依賴關係 -->
    <dubbo:application name="dubboProvider" />

    <!-- 使用zookeeper註冊中心暴露服務地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

    <!-- 用dubbo協議在20880端口暴露服務 -->
    <dubbo:protocol name="dubbo" port="20880" />
    <!-- 啓用monitor模塊 -->
    <dubbo:monitor protocol="registry" />

    <bean id="userService" class="com.test.UserServiceImpl" />

    <!-- 聲明須要暴露的服務接口 -->
    <dubbo:service interface="com.test.UserServiceBo" ref="userService"
        group="dubbo"  version="1.0.0" timeout="3000"/>

</beans>

日誌文件log4j.properties內容以下:ide

log4j.rootLogger=INFO,A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout

而後,編寫服務發佈測試類TestProvider,代碼以下:

public class TestProvider {   

    public static void main(String[] arg) throws InterruptedException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:provider.xml");

        //掛起當前線程,若是沒有改行代碼,服務提供者進程會消亡,服務消費者就發現不了提供者了
        Thread.currentThread().join();
    }
}

最後,運行TestProvider類,輸出以下:

說明當前服務已經註冊了Zookeeper。

基於Spring配置的服務消費方搭建

Consumer模塊爲服務消費方,服務消費端主要是從Zookeeper獲取本身須要的服務提供者的ip列表,而後根據路由規則選擇一個ip進行遠程調用。裏面TestConsumer和consumer.xml組成了基於xml方式的服務調用。

首先須要在Consumer模塊中引入SDK模塊,由於Consumer模塊須要用到UserServiceBo接口(泛化調用時候不須要這個步驟)。

consumer.xml內容以下:

<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.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd 
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

  <!-- 消費方應用名,用於計算依賴關係,不是匹配條件,不要與提供方同樣 -->    
    <dubbo:application name="dubboConsumer" />  

      <!-- 使用multicast廣播註冊中心暴露發現服務地址 -->    
    <dubbo:registry  protocol="zookeeper" address="zookeeper://127.0.0.1:2181" />  
       <!-- 啓動monitor-->
    <dubbo:monitor protocol="registry" />        
      <!-- 生成遠程服務代理,能夠和本地bean同樣使用demoService -->    
    <dubbo:reference id="userService" interface="com.test.UserServiceBo" group="dubbo" version="1.0.0" timeout="3000"/>    

</beans>

測試服務消費類TestConsumer代碼以下:

public class TestConsumer {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] { "classpath:consumer.xml" });

        final UserServiceBo demoService = (UserServiceBo) context.getBean("userService");

        System.out.println(demoService.sayHello("哈哈哈"));
    }
}

最後運行TestConsumer,會輸出:

說明服務消費端已經正常調用了服務提供方的服務了。

注:至此一個經典的含有服務提供者/服務消費者/服務註冊中心的簡單分佈式系統搭建完畢了。

基於Dubbo API方式的服務提供方與消費方搭建

基於Dubbo API方式的服務提供方搭建

其中Provider模塊爲服務提供者,裏面TestProviderApi是基於Dubbo Api的服務提供,UserServiceImpl爲服務實現類。

首先須要在Provider模塊裏面引入SDK模塊,這個不變。

而後實現UserServiceBo接口爲UserServiceImpl,這個也不變。

再接着編寫Dubbo Api服務提供測試代碼TestProviderApi,代碼以下:

public class TestProviderApi {

    public static void main(String[] arg) throws InterruptedException {

        //(4.3.1-1)等價於  <bean id="userService" class="com.test.UserServiceImpl" />
        UserServiceBo userService = new UserServiceImpl();
        //(4.3.1-2)等價於  <dubbo:application name="dubboProvider" />
        ApplicationConfig application = new ApplicationConfig();
        application.setName("dubboProvider");

        //(4.3.1-3)等價於  <dubbo:registry address="zookeeper://127.0.0.1:2181" />
        RegistryConfig registry = new RegistryConfig();
        registry.setAddress("127.0.0.1:2181");
        registry.setProtocol("zookeeper");

        // (4.3.1-4)等價於 <dubbo:protocol name="dubbo" port="20880" />
        ProtocolConfig protocol = new ProtocolConfig();
        protocol.setName("dubbo");
        protocol.setPort(20880);

        //4.3.1-5)等價於     <dubbo:monitor protocol="registry" />
        MonitorConfig monitorConfig = new MonitorConfig();
        monitorConfig.setProtocol("registry");

        //4.3.1-6)等價於 <dubbo:service interface="com.test.UserServiceBo" ref="userService"
        //group="dubbo"  version="1.0.0" timeout="3000"/>
        ServiceConfig<UserServiceBo> service = new ServiceConfig<UserServiceBo>(); // 此實例很重,封裝了與註冊中心的鏈接,請自行緩存,不然可能形成內存和鏈接泄漏
        service.setApplication(application);
        service.setMonitor(monitorConfig);
        service.setRegistry(registry); // 多個註冊中心能夠用setRegistries()
        service.setProtocol(protocol); // 多個協議能夠用setProtocols()
        service.setInterface(UserServiceBo.class);
        service.setRef(userService);
        service.setVersion("1.0.0");
        service.setGroup("dubbo");
        service.setTimeout(3000);
        service.export();

       //4.3.1-8) 掛起當前線程
        Thread.currentThread().join();
    }
}

基於dubbo-spring-boot-starter使用SpringBoot搭建一個簡單的服務提供者服務應用,這裏從新打包一個SDK,內容以下:

服務提供方搭建

服務提供方應用結構以下:

 

其中ProviderApp爲SpringBoot的啓動類,代碼以下:

@SpringBootApplication
@EnableDubboConfiguration
@RestController 
@ComponentScan(basePackages = { "com.gitchat.demo.provider.service" })  
public class ProviderApp {


    @RequestMapping("/")
    String home() {
        return "Hello Demo!";
    }
    public static void main(String[] args) {   
        SpringApplication.run(ProviderApp.class, args);
    }
}

@ComponentScan(basePackages={"com.gitchat.demo.provider.service"})說明掃描com.gitchat.demo.provider.service包下的@Component註解的類到Spring容器。

UserServiceImpl爲服務實現類,代碼以下:

@Service(interfaceClass = UserServiceBo.class,group="dubbo",version="1.0.0")
@Component
public class UserServiceBoImpl implements UserServiceBo{

    @Override
    public String sayHello(String name) {
        return "hello:" + name;
    }

    @Override
    public String testPojo(Person person) {
        return person.toString();
    }

}

@Service(interfaceClass=UserServiceBo.class,group="dubbo",version="1.0.0")標示UserServiceBoImpl會做爲服務提供出去,dubbo-start會掃描到這個註解,並建立一個ServiceConfig對象,而後調用ServiceConfig的export方法發佈服務到Zookeeper。使用dubbo-starter後,你只須要在須要發佈的服務的實現類上添加@Service註解就能夠了,無須在顯示建立ServiceConfig對象。

配置文件application.properties內容以下:

server.port=7003
management.port=7004
spring.application.name=demo-provider

spring.dubbo.server=true
spring.dubbo.registry=zookeeper://127.0.0.1:2181

其中server.port爲內嵌Tomcat容器監聽端口,management.port爲健康檢查端口,spring.application.name爲應用的名稱,spring.dubbo.server=true說明開啓Dubbo服務,spring.dubbo.registry爲服務註冊中心地址。

日誌配置文件log4j.properties內容以下:

log4j.rootLogger=INFO,A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout

pom.xml裏面須要配置內容以下,首先因爲是SpringBoot應用因此須要以下引入:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
</parent>
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
</dependency>

還須要引入dubbo-spring-boot-starter,這個starter裏面包含了Dubbo須要的東西:

    <dependency>
            <groupId>com.alibaba.spring.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.0.0</version>
    </dependency>

而後引入Zookeeper包,和依賴的SDK:

        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.10</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

最後須要引入spring-boot-maven插件,以便打包爲可執行的jar文件:

<build>
        <finalName>demo-provider</finalName>

        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <executable>false</executable>
                    <excludeDevtools>true</excludeDevtools>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            </plugins>
    </build>

上面配置完畢後,執行ProviderApp的main函數輸出以下,可知服務註冊到Zookeeper了:

服務消費方搭建

服務消費方應用結構以下:

 

其中ConsumerApp爲SpringBoot啓動的入口,代碼以下:

@SpringBootApplication
@EnableDubboConfiguration 
@RestController
@ComponentScan(basePackages = { "com.gitchat.demo.consumer.service" })
public class ConsumerApp {

    @Autowired 
    private ConsumerService  consumerService; 

    @RequestMapping(value = "/testSayHello", method = RequestMethod.GET)
    String testSayHello(@RequestParam(value = "name", required = true) String name) {
        return  consumerService.sayHello(name);
    }

    @RequestMapping("/")
    String home() {
        return "Hello Demo!";
    }

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApp.class, args);

    }
}

可知注入了ConsumerService的一個實例到Spring容器,而後testSayHello方法內部調用了ConsumerService實例的sayHello方法,這個controller是爲了測試服務消費的,下面咱們看看ConsumerService的實現:

@Component
public class ConsumerService {

    @Reference(group="dubbo",interfaceClass=UserServiceBo.class,version="1.0.0")
    private UserServiceBo userServiceBo;

    public String sayHello(String name){
        return userServiceBo.sayHello(name);
    }
}

註解@Reference標示當前要消費UserServiceBo接口的服務,並經過註解說明要消費服務的接口,版本和分組信息,dubbo-starter會自動掃描這個註解而後生成一個ReferenceConfig對象,而後調用ReferenceConfig的get()方法獲取遠程調用實例的代理類,並設置到userServiceBo變量。ConsumerService的sayHello方法則是調用遠程服務userServiceBo的sayHello方法。

配置文件application.properties內容以下:

server.port=7001
management.port=7002
spring.application.name=demo-consumer

spring.dubbo.server=true
spring.dubbo.registry=zookeeper://127.0.0.1:2181

pom文件和日誌文件與服務提供者相似,再也不贅述。

相關文章
相關標籤/搜索