Dubbo-高性能RPC通信框架

架构

Dubbo 架构

  • Registry:注册中心,协调 Consumer 与 Provider 之间的地址注册与发现。
  • Provider:服务提供者,暴露服务的服务提供方。
  • Container:服务运行容器。服务容器负责启动,加载,运行服务提供者。
  • Consumer:服务消费者,调用远程服务的服务消费方。
  • Monitor:统计服务的调用次数和调用时间的监控中心。

调用关系说明

步骤描述
1服务容器负责启动,加载,运行服务提供者。服务提供者在启动时,向注册中心注册自己提供的服务
2服务消费者在启动时,向注册中心订阅自己所需的服务
3注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
4

服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

5

服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

快速入门

XML配置

定义服务接口

public interface EchoService {
    String echo(String message);
}

在服务提供方实现接口

public class EchoServiceImpl implements EchoService {
    @Override
    public String echo(String message) {
        String now = new SimpleDateFormat("HH:mm:ss").format(new Date());

        String result = "[" + now + "] Hello " + message + ", request from consumer:"
                + RpcContext.getContext().getRemoteAddress();

        return result;
    }
}

用 Spring 配置声明暴露服务

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.xsd
     http://code.alibabatech.com/schema/dubbo
	 http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

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

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

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

    <!-- 和本地bean一样实现服务 -->
    <bean id="echoService" class="com.jd.dubbo.EchoServiceImpl"/>

    <!--声明需要暴露的服务接口-->
   <dubbo:service interface="com.jd.dubbo.EchoService" ref="echoService" timeout="1000"/>
</beans>

服务方加载 Spring 配置

Provider.java
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Provider {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring/dubbo-provider.xml");
        context.start();

        // 按任意键退出
        System.in.read();
    }
}

服务消费者XML 配置

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: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">

    <!--消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样-->
    <dubbo:application name="echo-consumer"/>

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

    <!-- 生成远程服务代理,可以和本地bean一样使用demoService  -->
    <dubbo:reference id="echoService" check="false" interface="com.jd.dubbo.EchoService"/>
</beans>

服务消费者加载Spring配置,并调用远程服务

Consumer.java

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Consumer {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring/dubbo-consumer.xml");
        context.start();

        EchoService echoService = context.getBean("echoService", EchoService.class);
        String msg = echoService.echo("yangyanping");

        System.out.println("echo result:" + msg);
    }
}

启动服务和消费,运行结果:

echo result:[09:52:55] Hello yangyanping, request from consumer:/10.0.72.111:64312

基于注解实现

以注解配置的方式来配置你的 Dubbo 应用

pom文件

<?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">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dobbo-study</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

EchoServiceImpl.java 实现类 

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.rpc.RpcContext;

import java.text.SimpleDateFormat;
import java.util.Date;

@Service
public class EchoServiceImpl implements EchoService {
    @Override
    public String echo(String message) {
        String now = new SimpleDateFormat("HH:mm:ss").format(new Date());

        String result = "[" + now + "] Hello " + message + ", request from consumer:"
                + RpcContext.getContext().getRemoteAddress();

        return result;
    }
}

Provider.java 启动类 

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.ProviderConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

public class Provider {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class);
        context.start();

        // 按任意键退出
        System.in.read();
    }

    @Configuration
    @ComponentScan(value = {"com.jd.dubbo.annonation.service"})
    @EnableDubbo(scanBasePackages = "com.jd.dubbo.annonation.service")
    static class ProviderConfiguration {
        @Bean
        public ProviderConfig providerConfig() {
            return new ProviderConfig();
        }

        @Bean
        public ApplicationConfig applicationConfig() {
            ApplicationConfig applicationConfig = new ApplicationConfig();
            applicationConfig.setName("echo-annotation-provider");

            return applicationConfig;
        }

        @Bean
        public RegistryConfig registryConfig() {
            RegistryConfig registryConfig = new RegistryConfig();
            registryConfig.setProtocol("zookeeper");
            registryConfig.setAddress("localhost");
            registryConfig.setPort(2181);

            return registryConfig;
        }

        @Bean
        public ProtocolConfig protocolConfig() {
            ProtocolConfig protocolConfig = new ProtocolConfig();
            protocolConfig.setName("dubbo");
            protocolConfig.setPort(20880);

            return protocolConfig;
        }
    }
}

Consumer.java

import com.alibaba.dubbo.config.annotation.Reference;
import com.jd.dubbo.annonation.service.EchoService;
import org.springframework.stereotype.Component;

@Component
public class EchoConsumer {
    @Reference
    private EchoService echoService;

    public String echo(String name){
        return echoService.echo(name);
    }
}

Consumer.java 消费者启动类 

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

public class Consumer {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class);
        context.start();

        EchoConsumer echoConsumer = context.getBean("echoConsumer", EchoConsumer.class);
        String msg = echoConsumer.echo("yangyanping");

        System.out.println("echo result:" + msg);
    }

    @Configuration
    @ComponentScan(value = {"com.jd.dubbo.annonation.client"})
    @EnableDubbo(scanBasePackages = "com.jd.dubbo.annonation.client")
    static class ConsumerConfiguration {

        @Bean
        public ApplicationConfig applicationConfig() {
            ApplicationConfig applicationConfig = new ApplicationConfig();
            applicationConfig.setName("echo-annotation-consumer");

            return applicationConfig;
        }

        @Bean
        public RegistryConfig registryConfig() {
            RegistryConfig registryConfig = new RegistryConfig();
            registryConfig.setProtocol("zookeeper");
            registryConfig.setAddress("localhost");
            registryConfig.setPort(2181);

            return registryConfig;
        }

        @Bean
        public ConsumerConfig consumerConfig() {
            ConsumerConfig consumerConfig = new ConsumerConfig();

            return consumerConfig;
        }
    }
}

基于API实现

EchoProvider.java 类定义

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;
import com.jd.dubbo.annonation.service.EchoService;
import com.jd.dubbo.annonation.service.EchoServiceImpl;

public class EchoProvider {
    public static void main(String[] args) throws Exception {
        ServiceConfig<EchoService> service = new ServiceConfig<>();
        service.setApplication(new ApplicationConfig("java-echo-provider"));
        service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
        service.setInterface(EchoService.class);
        service.setRef(new EchoServiceImpl());
        service.export();

        System.out.println("java-echo-provider  is running");
        System.in.read();
    }
}

EchoConsumer.java 类定义 

public class EchoConsumer {
    public static void main(String[] args) {
        ReferenceConfig<EchoService> reference = new ReferenceConfig<>();
        reference.setApplication(new ApplicationConfig("java-echo-consumer"));
        reference.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
        reference.setInterface(EchoService.class);

        EchoService echoService = reference.get();
        String message = echoService.echo("Hello World !");

        System.out.println(message);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值