zoukankan      html  css  js  c++  java
  • Dubbo学习笔记3:Dubbo服务提供端与消费端应用的搭建

    Demo结构介绍

    Demo使用Maven聚合功能,里面有三个模块,目录如下:

    • 其中Consumer模块为服务消费者,里面TestConsumer和consumer.xml组成了基于Spring配置方式的服务调用,TestConsumerApi是基于Dubbo API方式的服务调用,TestConsumerApiGeneric是泛化方式的服务调用,TestConsumerAsync是异步调用的方式。
    • 其中Provider模块为服务提供者,里面TestProvider和provider.xml组成了基于Spring配置方式的服务提供,TestProviderApi是基于Dubbo API的服务提供,UserServiceImpl为服务实现类。
    • 其中SDK模块是一个二方包,用来存放服务提供者所有的接口,是为了代码复用使用,在服务提供者和消费者的模块里面都需要引入这个二方包。

    其中SDK里面的接口定义源码如下:

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

    在SDK模块执行 mvn clean install 命令会安装该模块的jar到本地仓库,要想在其他模块引入该jar,必须要先执行这个安装步骤。

    基于Spring配置的服务提供方与消费方搭建

    Provider模块为服务提供者,作用是提供的服务到Zookeeper,并使用Netty服务监听服务消费端的链接。里面TestProvider和provider.xml组成了基于XML方式的服务提供,UserServiceImpl为服务实现类。

    首先需要在Provider模块里面引入SDK模块,因为Provider模块需要用到UserServiceBo接口(需要在SDK模块执行 mvn clean install 命令,会安装该模块的jar到本地仓库)。

    然后实现UserServiceBo接口为UserServiceImpl,代码如下:

    复制代码
    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内容如下:

    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文件和日志文件与服务提供者类似,不再赘述。

  • 相关阅读:
    跳出iframe
    leetcode 225. Implement Stack using Queues
    leetcode 206. Reverse Linked List
    leetcode 205. Isomorphic Strings
    leetcode 203. Remove Linked List Elements
    leetcode 198. House Robber
    leetcode 190. Reverse Bits
    leetcode leetcode 783. Minimum Distance Between BST Nodes
    leetcode 202. Happy Number
    leetcode 389. Find the Difference
  • 原文地址:https://www.cnblogs.com/cnndevelop/p/12186915.html
Copyright © 2011-2022 走看看